jest-community / vscode-jest

The optimal flow for Jest based testing in VS Code
MIT License
2.84k stars 294 forks source link

Running tests from whole folder does not work, wrong testPathPattern option #1079

Closed akwodkiewicz closed 1 year ago

akwodkiewicz commented 1 year ago

Environment

  1. vscode-jest version: v6.0.1
  2. node -v: v18.16.0
  3. ~npm -v~ or yarn --version: 3.4.1
  4. ~npm ls jest or npm ls react-scripts (if you haven’t ejected)~:

yarn why jest

...
└─ my-backend-project@workspace:packages/backend
   └─ jest@npm:29.1.2 [bd4e4] (via npm:29.1.2 [bd4e4])
  1. your vscode-jest settings if customized: my.code-workspace:

    ...
    "jest.autoRun": "off",
    "jest.virtualFolders": [{
      "rootPath": "packages/backend",
      "name": "Backend Unit Tests", 
    }],
    ...
  2. Operating system: macOS 14.0 (23A344) (Sonoma)

Prerequisite

Steps to Reproduce

  1. Open "Testing" tab

  2. Try to "Run Test" on a "folder" item (for the purpose of troubleshooting, I'm selecting the redis folder in my project).

Screenshot 2023-10-13 at 11 34 44

Relevant Debug Info

I'm running VSCode from a .code-workspace file, this is a monorepo, but I don't have multiple roots defined (and I don't want to have them). I'm trying this new virtualFolder setup.

~Might be unrelated to the issue, though.~ (EDIT: it probably is the issue, see the next comment)

Full path to the redis folder:

Relative path to the .code-workspace file

Expected Behavior

All tests from the selected folder are run.

Actual Behavior

No tests are found.

"Test Results" tab output (added line breaks in command for readability):

> my-backend-project@0.0.1 test
> env-cmd -f .env jest \
    --testLocationInResults \
    --json \
    --useStderr \
    --outputFile /var/folders/9v/c77m1k_90wl3225q3pl3335w0000gq/T/jest_runner_my-backend-project_unit_tests_503_2.json \
    --no-coverage \
    --reporters default \
    --reporters /Users/akwodkiewicz/.vscode/extensions/orta.vscode-jest-6.0.1/out/reporter.js \
    --colors \
    --watchAll=false \
    --testPathPattern /Users/akwodkiewicz/Private/repo-A/src/redis

No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/akwodkiewicz/Private/repo-A/packages/backend/src
  7472 files checked.
  testMatch:  - 0 matches
  testPathIgnorePatterns: /node_modules/ - 7472 matches
  testRegex: \.spec\.ts$ - 1412 matches
Pattern: /Users/akwodkiewicz/Private/repo-A/src/redis - 0 matches
npm ERR! Lifecycle script `test` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: my-backend-project@0.0.1 
npm ERR!   at location: /Users/akwodkiewicz/Private/repo-A/packages/backend 

~It looks like the --testPathPattern should be set to redis -- then searching for this path pattern would be successful In /Users/akwodkiewicz/Private/repo-A/packages/backend/src.~

~However, the script is passed a faulty concatenation of the workspace absolute path (/Users/akwodkiewicz/Private/repo-A), the outer src folder (which is visible in the "Testing tab", but I did not put it on the screenshot), and redis.~

EDIT: The --testPathPattern is wrong, but a better analysis of what happens is in the next comment

akwodkiewicz commented 1 year ago
Screenshot 2023-10-13 at 11 51 55

When I'm clicking "play" on the oauth folder (location: packages/backend/src/auth/oauth), I get the following output:

> my-backend-project@.0.1 test
> env-cmd -f .env jest \
    ... \
    --testPathPattern /Users/akwodkiewicz/Private/repo-A/src/auth/oauth

No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/akwodkiewicz/Private/repo-A/packages/backend/src
  7472 files checked.
  testMatch:  - 0 matches
  testPathIgnorePatterns: /node_modules/ - 7472 matches
  testRegex: \.spec\.ts$ - 1412 matches
Pattern: /Users/akwodkiewicz/Private/repo-A/src/auth/oauth - 0 matches
npm ERR! Lifecycle script `test` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: my-backend-project@0.0.1 
npm ERR!   at location: /Users/akwodkiewicz/Private/repo-A/packages/backend 

The pattern passed to the script is always the concatenation of:

It's missing the packages/backend part, which is the rootPath defined in the virtualFolders option!

akwodkiewicz commented 1 year ago

I believe the --testPathPattern is set here:

https://github.com/jest-community/vscode-jest/blob/10414abf47d9829d67ef8932fdd12bb472154ed9/src/JestProcessManagement/JestProcess.ts#L139-L141

And the value for testFileNamePattern might be set here:

https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/src/test-provider/test-item-data.ts#L501-L505

And uri there is crafted with this static method:

https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/src/test-provider/test-item-data.ts#L479-L483


When you look at the VirtualWorkspaceFolder you can see a effectiveUri property:

https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/src/virtual-workspace-folder.ts#L93-L117

The comment above it sounds like it's something we need. But the effectiveUri is only used to determine if something is in the virtual workspace folder, the uri property does not use this effectiveUri.

Is it possible that the fix would look like this?

   get uri(): vscode.Uri { 
     return this.effectiveUri; 
   } 
akwodkiewicz commented 1 year ago

Ok, I think it's something like this:

The URI of the virtual workspace folder is defined to be the same as the "actual workspace folder". There's even a unit test for this

https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/tests/virtual-workspace-folder.test.ts#L35-L37

So whenever we run the command for my repo-A/packages/backend virtual folder, we're going to use the repo-A URI to calculate some paths.

To establish the test path patterns, we need to craft the URIs with the help of FolderData.makeUri. It joins a folder name with the parent URI. So it explains why oauth is prefixed with auth and auth is prefixed with src -- it matches what I see in the GUI.

But, then there's a question of "what is the root parent element"? And I think the answer is in line 194:

https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/src/test-provider/test-item-data.ts#L193-L194

If there are no parents, then the root is the this, which refers to the WorkspaceRoot class.

It would then explain why

and the packages/backend is missing from the equation.

We would need to somehow add the information about the effectiveUri to the WorkspaceRoot or use VirtualWorkspaceFolder-specific methods instead of FolderData static ones to account for the rootPath of the virtual folder.

akwodkiewicz commented 1 year ago

I think the only way to make it work is for the VirtualWorkspaceFolder to return effectiveUri as the URI. This is even mentioned in the class comment https://github.com/jest-community/vscode-jest/blob/ad719cb5b9509715047f1cae8ea7204db5f8faa5/src/virtual-workspace-folder.ts#L91

This makes sense, cause the "virtualness" of the folder is transparent to the context class, so it should behave as a real folder and return its real URI.

I'll try to prepare a PR tonight

connectdotz commented 1 year ago

@akwodkiewicz, good catch and nice investigation. 👍

But let's not change the uri for the virtualWorkspaceFolder, as many vscode and other components use, and assume that attribute yields the same as the original vscode.WorkspaceFolder. I think we might be able to fix this with a much narrower change:

  1. expose effectiveUri attribute in VirtualWorkspaceFolder (readonly)
  2. change the WorkspaceRoot.createTestItem() to use the effectiveUri for virtualWorkspaceFolder: https://github.com/jest-community/vscode-jest/blob/10414abf47d9829d67ef8932fdd12bb472154ed9/src/test-provider/test-item-data.ts#L135

I hope this is enough to fix the issue and look forward to the PR!

akwodkiewicz commented 1 year ago

@connectdotz, thanks for the suggestions.

But let's not change the uri for the virtualWorkspaceFolder, as many vscode and other components use, and assume that attribute yields the same as the original vscode.WorkspaceFolder.

Do you mean the setup wizard? (maybe it's broken too 😅)

I followed your advice and prepared a PR according to your proposal: https://github.com/jest-community/vscode-jest/pull/1080

I launched the modified extension on my repo and it worked correctly!

romanlex commented 10 months ago

Sorry but it doesn't work without any virtual folders( In my case "jest.rootPath": "client/src" and when I'm try to run test on folder by interface I get command

DEFAULT_LOCALE=ru jest --testLocationInResults --json --useStderr --outputFile /tmp/jest_runner_stoege_1000_2.json --no-coverage --reporters default --reporters /home/wsl/.vscode-server/extensions/orta.vscode-jest-6.1.0/out/reporter.js --colors --watchAll=false --testPathPattern /home/wsl/Development/app/core

where testPathPattern is ignore rootPath it must be --testPathPattern /home/wsl/Development/app/${rootPath}/core