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

TypeScript tests appear in Test Explorer, but are not run. #33

Open
alexc155 opened this issue Apr 5, 2024 · 5 comments
Open

TypeScript tests appear in Test Explorer, but are not run. #33

alexc155 opened this issue Apr 5, 2024 · 5 comments

Comments

@alexc155
Copy link

alexc155 commented Apr 5, 2024

Using the config

"nodejs-testing.extensions": [
    {
      "extensions": ["mjs", "cjs", "js"],
      "parameters": []
    },
    {
      "extensions": ["mts", "cts", "ts"],
      "parameters": ["--import", "tsx"]
    }
  ]

I can make TypeScript tests appear in the Test Explorer 😀

However, when I run all tests the Test Results pane shows 0/0 tests passed and the Test Explorer fails to show any green or red ticks.

I wonder if this is because node is being used as the test runner and the glob for detecting tests doesn't include the .ts extension?

This is similar to running npm --test --import tsx

Changing the test runner to tsx probably wouldn't help as it uses the same glob patterns to discover tests.

I have tried adding the glob to the parameters in the config:

"nodejs-testing.extensions": [
    {
      "extensions": ["mjs", "cjs", "js"],
      "parameters": []
    },
    {
      "extensions": ["mts", "cts", "ts"],
      "parameters": ["--import", "tsx", "./test/**/*.test.ts"]
    }
  ]

but then all the tests fail with Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'foo/test/**/*.test.ts' imported from foo/

I thought perhaps the filePatterns property in settings might be used for this, but it appears to only control the discovery of tests rather than their execution.

Please could you tell me what I'm doing wrong, or provide a setting I can use to pass a glob pattern of test files to the runner?

Thanks!

@connor4312
Copy link
Owner

However, when I run all tests the Test Results pane shows 0/0 tests passed and the Test Explorer fails to show any green or red ticks.

Please enable the nodejs-testing.verbose user setting and share the output from the Test Results when you do this. Thanks!

@alexc155
Copy link
Author

alexc155 commented Apr 8, 2024

Hi,

I've discovered what's wrong: In my tests I like to include the path of the test file so that I can easily jump to it from the test output. My tests look like this:

import { describe, it } from 'node:test';
import assert from 'node:assert';

describe(`${__filename} - When doing a thing`, () => {
  it('it returns true', () => {
    // ARRANGE
    const expected: boolean = true;

    // ACT
    const actual: boolean = true;

    // ASSERT
    assert(expected === actual);
  });
});

It's the ${__filename} that's causing the problem. Without it, your extension runs the test fine. With the variable I get the following in the verbose output:

worker1> starting /my/path/test/thing.test.ts
worker1> node --import" "tsx" "--test-reporter" "file:///Users/me/.vscode/extensions/connor4312.nodejs-testing-1.5.0/out/runner-loader.js" "/my/path/test/thing.test.ts
worker1> {"type":"test:enqueue","data":{"nesting":0,"name":"/my/path/test/thing.test.ts - When doing a thing","line":2,"column":875,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:dequeue","data":{"nesting":0,"name":"/my/path/test/thing.test.ts - When doing a thing","line":2,"column":875,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:enqueue","data":{"nesting":1,"name":"it returns true","line":2,"column":941,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:dequeue","data":{"nesting":1,"name":"it returns true","line":2,"column":941,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:start","data":{"nesting":0,"name":"/my/path/test/thing.test.ts - When doing a thing","line":2,"column":875,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:start","data":{"nesting":1,"name":"it returns true","line":2,"column":941,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:pass","data":{"name":"it returns true","nesting":1,"testNumber":1,"details":{"duration_ms":0.147959},"line":2,"column":941,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:plan","data":{"nesting":1,"count":1,"line":2,"column":875,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:pass","data":{"name":"/my/path/test/thing.test.ts - When doing a thing","nesting":0,"testNumber":1,"details":{"duration_ms":0.774542,"type":"suite"},"line":2,"column":875,"file":"/my/path/test/thing.test.ts"}}
worker1> {"type":"test:plan","data":{"nesting":0,"count":1}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"tests 1"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"suites 1"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"pass 1"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"fail 0"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"cancelled 0"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"skipped 0"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"todo 0"}}
worker1> {"type":"test:diagnostic","data":{"nesting":0,"message":"duration_ms 56.545125"}}
worker1> stdout closed


0/0 tests passed

It looks like it's running the test, but not gathering the result?

@alexc155
Copy link
Author

alexc155 commented Apr 8, 2024

Once I'd got the tests working, I found a separate thing. Any code that referenced a path to a file (even using resolve from node:path) was failing because the file could not be found. This appears to be because the tests are executing from the directory they are in, rather than from the root of the project.

For example, if I have:

test/thing.test.ts =>

import { describe, it } from 'node:test';
import assert from 'node:assert';
import { existsSync } from 'node:fs';
import { resolve } from 'node:path';

describe(`When doing a thing`, () => {
  it('it returns true', () => {
    // ARRANGE
    console.log(resolve('test/thing.test.ts'));
    const expected: boolean = existsSync(resolve('test/thing.test.ts'));

    // ACT
    const actual: boolean = true;

    // ASSERT
    assert(expected === actual);
  });
});

then the test runs fine from the command line. But the test fails from your extension and shows the path as

/test/test/thing.test.ts

I have managed to fix this by using a package called app-root-path instead of resolve:

import { describe, it } from 'node:test';
import assert from 'node:assert';
import { existsSync } from 'node:fs';
import appRootPath from 'app-root-path';

describe(`When doing a thing`, () => {
  it('it returns true', () => {
    // ARRANGE
    console.log(`${appRootPath}/test/thing.test.ts`);
    const expected: boolean = existsSync(`${appRootPath}/test/thing.test.ts`);

    // ACT
    const actual: boolean = true;

    // ASSERT
    assert(expected === actual);
  });
});

I wonder whether this is because you are setting the current working directory here as the directory each test file is in?

@ssalbdivad
Copy link

Thanks for your help @alexc155!

I'd love to migrate ArkType to node's test runner but I'm still encountering lots of problems with TS discovery and imports. Will be keeping an eye on this- awesome to see the early support for test coverage metrics ❤️

@connor4312
Copy link
Owner

It's the ${__filename} that's causing the problem. Without it, your extension runs the test fine. With the variable I get the following in the verbose output:

Ah, yes. This is expected. At the moment tests are discovered purely by static code analysis, which does not make any attempt to evaluate template literals with replacements. During runs, any additional tests not found in the test tree are ignored. We could add support for that, however, such that tests emitted during runs are added to the tree if they aren't already there.

This appears to be because the tests are executing from the directory they are in, rather than from the root of the project.

This probably duplicates at. At the moment I would use ${__dirname} to ensure that the paths are absoltue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants