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

Improve selfhost testing experience #189680

Closed
connor4312 opened this issue Aug 4, 2023 · 4 comments
Closed

Improve selfhost testing experience #189680

connor4312 opened this issue Aug 4, 2023 · 4 comments
Assignees
Labels
feature-request Request for new features or functionality on-testplan
Milestone

Comments

@connor4312
Copy link
Member

  • Make it possible to run extension tests using our running
    • This probably entails making a generic VS Code extension test runner (neat!)
  • @ulugbekna is passionate about Jest!
    • We probably cannot readily copy-paste jest into core tests, but we should see if there's features we miss in Jest that we can bring over
    • Any inspiration we can take from the Jest extension to improve UX in core?
@connor4312 connor4312 added the feature-request Request for new features or functionality label Aug 4, 2023
@connor4312 connor4312 added this to the August 2023 milestone Aug 4, 2023
@connor4312 connor4312 self-assigned this Aug 4, 2023
@gjsjohnmurray
Copy link
Contributor

Personally I am hoping greater use by the team of the native testing UI will lead to the coverage API getting some attention. In particular, until its results get surfaced in the UI there's not a lot of incentive for us extension developers to invest in it. See #123713

@ulugbekna
Copy link
Contributor

I’m a big fan of snapshot testing that Jest supports and think we could benefit greatly from adopting it.

Snapshot testing

Snapshot tests (aka "expect tests) are tests that capture the string representation of a given object and compare to the expected string. The important aspect of these tests is that those snapshots

  • can be hand-written or "captured" on the first run. Note how I write toMatchInlineSnapshot() and the test runner runs the test, get the expected output and updates the test with the expected snapshot. This allows writing tests a lot faster
Screen.Recording.2023-08-10.at.11.56.36.mov
  • if the actual snapshot doesn't match the expected snapshot, one can update the latter automatically with various granularity - test, suite, file. Henning contributed a code action that allows updating a single assertion failure in our tests, but it is limited to a single assertion at a time
image

Snapshots also allow for more visual tests because one doesn't need to write those by hand:

		test('returns the positions of all functions in the source code', async () => {
			const source = outdent`
				function add(a, b) {
					return a + b;
				}

				function subtract(a, b) {
					return a - b;
				}
				`;
			expect(await jsSourceWithFunPos(source)).toMatchInlineSnapshot(`
			"<start-0>function add(a, b) {
				return a + b;
			}<end-0>

			<start-1>function subtract(a, b) {
				return a - b;
			}<end-1>"
		`);
		});

Some things that could be improved with Jest & Jest extension:

  1. Updating the snapshot requires a re-run of tests (possibly reuses the cached test runs, but still not instantaneous update as is the case with the OCaml language test runner), while we could store the expected outputs and update the file as required (this's the problem with Jest rather than the extension)
  2. It uses diagnostics to show the diff between test mismatches instead of a diff viewzone
image
  1. Each diff viewzone could have a button to accept the proposed snapshot

I like this blog post describing how snapshot tests can be nice - https://blog.janestreet.com/the-joy-of-expect-tests/

Jane Street is big on snapshot testing and have their own framework. Their way of creating snapshots is a bit different because they don't compare the snapshot against an object but they capture stdout from a test as a snapshot.


Happy to jump on a call to discuss this more and, in general, help with implementation some of the things, if time permits.

connor4312 added a commit that referenced this issue Aug 14, 2023
This adds Jest-like support for snapshot testing.
Developers can do something like:

```js
await assertSnapshot(myComplexObject)
```

The first time this is run, the snapshot expectation file is written
to a `__snapshots__` directory beside the test file. Subsequent runs
will compare the object to the snapshot, and fail if it doesn't match.

You can see an example of this in the test for snapshots themselves!

After a successful run, any unused snapshots are cleaned up. On a failed
run, a gitignored `.actual` snapshot file is created beside the
snapshot for easy processing and inspection.

Shortly I will do some integration with the selfhost test extension to
allow developers to easily update snapshots from the vscode UI.

For #189680

cc @ulugbekna @hediet
connor4312 added a commit that referenced this issue Aug 14, 2023
This adds Jest-like support for snapshot testing.
Developers can do something like:

```js
await assertSnapshot(myComplexObject)
```

The first time this is run, the snapshot expectation file is written
to a `__snapshots__` directory beside the test file. Subsequent runs
will compare the object to the snapshot, and fail if it doesn't match.

You can see an example of this in the test for snapshots themselves!

After a successful run, any unused snapshots are cleaned up. On a failed
run, a gitignored `.actual` snapshot file is created beside the
snapshot for easy processing and inspection.

Shortly I will do some integration with the selfhost test extension to
allow developers to easily update snapshots from the vscode UI.

For #189680

cc @ulugbekna @hediet
connor4312 added a commit that referenced this issue Aug 14, 2023
This adds Jest-like support for snapshot testing.
Developers can do something like:

```js
await assertSnapshot(myComplexObject)
```

The first time this is run, the snapshot expectation file is written
to a `__snapshots__` directory beside the test file. Subsequent runs
will compare the object to the snapshot, and fail if it doesn't match.

You can see an example of this in the test for snapshots themselves!

After a successful run, any unused snapshots are cleaned up. On a failed
run, a gitignored `.actual` snapshot file is created beside the
snapshot for easy processing and inspection.

Shortly I will do some integration with the selfhost test extension to
allow developers to easily update snapshots from the vscode UI.

For #189680

cc @ulugbekna @hediet
connor4312 added a commit that referenced this issue Aug 15, 2023
* eng: add support for snapshot tests

This adds Jest-like support for snapshot testing.
Developers can do something like:

```js
await assertSnapshot(myComplexObject)
```

The first time this is run, the snapshot expectation file is written
to a `__snapshots__` directory beside the test file. Subsequent runs
will compare the object to the snapshot, and fail if it doesn't match.

You can see an example of this in the test for snapshots themselves!

After a successful run, any unused snapshots are cleaned up. On a failed
run, a gitignored `.actual` snapshot file is created beside the
snapshot for easy processing and inspection.

Shortly I will do some integration with the selfhost test extension to
allow developers to easily update snapshots from the vscode UI.

For #189680

cc @ulugbekna @hediet

* fix async stacktraces getting clobbered

* random fixes

* comment out leak detector, for now

* add option to snapshot file extension
@connor4312
Copy link
Member Author

Followup items from discussion:

  • A way to view/peek the snapshot expected results
    • Syntax highlighting for peek expectations would be nice
  • Test Results should reflect retired state so we can see what snapshots have been applied
  • isPeekVisible context key does not seem to behave correctly 🤔
  • Make electron messages in the output terminal dimmed out / less prominent

@connor4312
Copy link
Member Author

connor4312 commented Oct 17, 2023

I finished the big themes I wanted to implement for this issues with the test CLI and its adoption in core. Copying the notice I sent for posterity


This week I've been working on a new way to run extension tests. It includes a configuration-driven command-line runner, as well as an extension that runs extensions tests in the VS Code UI.

👉 For people who own built-in extensions: You can now use this for built-in extensions in VS Code! To onboard your extension: (example)

  1. Add your extension to the extensions array in .vscode-test.js
  2. Update test-integration.sh and test-integration.bat to run using the runner
  3. If the tests don't run in the web, you can remove your old test .ts runner script. The runner does not yet support web tests (but it will soon) so this is still needed.
  4. You can now run your extension tests in two ways:
    a. Via yarn test-extension -l <label> on the command line. Do this to validate your config is set up correctly!
    b. With the ms-vscode.extension-test-runner extension installed, you can run and debug tests using the VS Code UI, as in the image below

👉 For people who write extensions: pretty similar to the above! You can use the above as guidelines as well as the documentation and an example.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality on-testplan
Projects
None yet
Development

No branches or pull requests

3 participants