Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using Workspace - Run in the Context of the Project #6474

Closed
4 tasks done
amitz opened this issue Sep 11, 2024 · 2 comments
Closed
4 tasks done

When using Workspace - Run in the Context of the Project #6474

amitz opened this issue Sep 11, 2024 · 2 comments

Comments

@amitz
Copy link

amitz commented Sep 11, 2024

Clear and concise description of the problem

Hello everyone! I want to start by saying Vitest is amazing, and I really appreciate everyone's time working on that!

I'm using the Workspace feature - and it feels a little bit clunky. Specifically, when using an internal vitest configuration file. For example, consider the following structure:

/
├── apps
│       ├── app1
│       │   ├── test
│       │   │   ├── unit
│       │   │   │   └── example.test.ts
│       │   │   └── integrations
│       │   │       └── example.test.ts
│       │   ├── vitest.unit.config.ts
│       │   └── vitest.integration.config.ts
│       └── app2
│           ├── test
│           │   ├── unit
│           │   │   └── example.test.ts
│           │   └── integrations
│           │       └── example.test.ts
│           ├── vitest.unit.config.ts
│           └── vitest.integration.config.ts
├── vitest.workspace.ts
├── vitest.shared.unit.ts
├── vitest.shared.integration.ts
└── vitest.config.ts

From this point forward I will refer to app1 and app2 as projects inside the workspace (that's how the official documentation refers them if I understand correctly).

Our unit-tests share some kind of default configuration (for example, we want all our Unit-Tests to have restoreMock: true). The default configuration is defined inside vitest.shared.unit file at the root:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    restoreMock: true,
  }
})

It is being consumed by the internal vitest.config.unit.ts file using defineProject:

import { defineProject, mergeConfig } from 'vitest/config';
import configShared from '../../vitest.shared.unit.ts';

export default mergeConfig(
    configShared,
    defineProject({
        test: {
            name: 'app1-unit`,
            dir: 'test/unit',
        },
    }),
);

This works perfectly when running from within the project itself, but not if you try to run all your workspace unit-tests from the workspace root directory (using vitest --projects='*-unit'). The reason for that, is when running from within the workspace context, the context is the ROOT DIRECTORY of the repository. Vitest will attempt to find test files inside test/unit and not apps/app1/test/unit. That's because while apps/app1 is defined as a project in vitest.workspace.ts, the context of the run is not from the actual project directory.

This can be fixed by multiple of hacks we are tried to use (passing dir externally from the config file, using: dir: '${__dirname}/test/unit' or just having some if/else inside the config file - but all of those feels pretty hacky).

Another example is code-coverage. Code coverage can't be defined on the internal vitest.config file when using workspaces, only at the root vitest.config.ts file. Here's an example:

import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    coverage: {
      provider: "v8",
      include: ["apps/*/src/**"],

This is a bit awkward, because instead of just stating I want to include src, which exists in every project I defined as part of my workspace, I need to specifically and very manually define the structure of my Workspace using wildcards and directories (even though I already defined it in vitest.workspace.ts). What I expect to work is just include: ["src"]. That will verify coverage within the src directory inside each of the projects.

Suggested solution

I think that perhaps it's worth considering perhaps running tests from within the project context (or directory to be precise) when using Workspace. This is somehow what tools like nx or lerna do.

Alternative

No response

Additional context

No response

Validations

@AriPerkkio
Copy link
Member

The reason for that, is when running from within the workspace context, the context is the ROOT DIRECTORY of the repository. Vitest will attempt to find test files inside test/unit and not apps/app1/test/unit. That's because while apps/app1 is defined as a project in vitest.workspace.ts, the context of the run is not from the actual project directory.

Is this duplicate of #5277? We cannot do process.chdir there as node:worker_threads do not support that.

I usually just use absolute paths there with fileURLToPath(new URL('<file>', import.meta.url)). Here's one example: https://stackblitz.com/~/edit/vitest-sonar-reporter-workspaces?file=packages/server/vitest.config.ts:L8-L10&file=packages/client/vitest.config.ts:L7-L11&view=editor

Another example is code-coverage. Code coverage can't be defined on the internal vitest.config file when using workspaces, only at the root vitest.config.ts file.

Yep, that's intentional and documented at https://vitest.dev/guide/workspace.html. You should use defineProject instead of defineConfig in workspace projects. Coverage is configured for the main thread, which runs all your projects. You cannot assign multiple configurations there.

@amitz
Copy link
Author

amitz commented Sep 29, 2024

Is this duplicate of #5277? We cannot do process.chdir there as node:worker_threads do not support that.

Ha, yes! Thank you for referencing it. I agree with what mentioned in there - this indeed leaves Vitest in an odd place compared to other mono-repo executors that support workspaces. Using absolute path is a neat trick, thanks for sharing it!

Yep, that's intentional and documented at https://vitest.dev/guide/workspace.html.

I mean scope-wise. Assuming I want to only scan the src directory in each project (while code-coveraging) - this won't work:

include: ["src/**"],

Instead - I have to adjust it to be something like:

include: ["apps/*/src/**"],

This is getting complex if your Mono-Repo has a complicated structure. What makes sense to me, is to have the ability to select directories I want to scan based on the root of the project, not the Workspace. But this is exactly like the bug you mentioned above.

I'm closing this one, and will keep tracking the main issue. Thanks for the help @AriPerkkio !

@amitz amitz closed this as completed Sep 29, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Oct 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants