-
Notifications
You must be signed in to change notification settings - Fork 728
docs(solid-testing-library): add solid testing library docs #1370
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
Merged
MatanBobi
merged 5 commits into
testing-library:main
from
danieljcafonso:docs(solid-testing-library)
Mar 6, 2024
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
2b4d5e6
docs(solid-testing-library): add solid testing library
danieljcafonso d19ef0d
Update docs/solid-testing-library/api.mdx
danieljcafonso 9e920ee
Update docs/solid-testing-library/api.mdx
danieljcafonso dca5421
Update docs/solid-testing-library/api.mdx
danieljcafonso 6e996e8
docs: add info to netlify.toml and address pr comments
danieljcafonso File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
--- | ||
id: api | ||
title: API | ||
sidebar_label: API | ||
--- | ||
|
||
Due to being inspired by the [preact-testing-library][preact-docs] you can check | ||
its page for more information. | ||
|
||
[preact-docs]: ../preact-testing-library/intro.mdx | ||
|
||
There are several key differences, to be aware of. | ||
|
||
- [`render`](#render) | ||
- [`renderHook`](#renderHook) | ||
- [`renderDirective`](#renderDirective) | ||
- [`Async methods`](#async-methods) | ||
- [`Know issues`](#known-issues) | ||
|
||
## `render` | ||
|
||
The `render` function takes in a function that returns a Solid Component, rather | ||
than simply the component itself. | ||
|
||
```tsx | ||
const results = render(() => <YourComponent />, options) | ||
``` | ||
|
||
Solid.js does _not_ re-render, it merely executes side effects triggered by | ||
reactive state that change the DOM, therefore there is no `rerender` method. You | ||
can use global signals to manipulate your test component in a way that causes it | ||
to update. | ||
|
||
In addition to the original API, the render function of this testing library | ||
supports a convenient `location` option that will set up an in-memory router | ||
pointing at the specified location. Since this setup is not synchronous, you | ||
need to first use asynchronous queries (`findBy`) after employing it: | ||
|
||
```tsx | ||
it('uses params', async () => { | ||
const App = () => ( | ||
<> | ||
<Route path="/ids/:id" component={() => <p>Id: {useParams()?.id}</p>} /> | ||
<Route path="/" component={() => <p>Start</p>} /> | ||
</> | ||
) | ||
const {findByText} = render(() => <App />, {location: 'ids/1234'}) | ||
expect(await findByText('Id: 1234')).not.toBeFalsy() | ||
}) | ||
``` | ||
|
||
It uses `@solidjs/router`, so if you want to use a different router, you should | ||
consider the `wrapper` option instead. If you attempt to use this without having | ||
the package installed, you will receive an error message. | ||
|
||
## `renderHook` | ||
|
||
Solid.js external reactive state does not require any DOM elements to run in, so | ||
our `renderHook` call to test hooks in the context of a component (if your hook | ||
does not require the context of a component, `createRoot` should suffice to test | ||
the reactive behavior; for convenience, we also have `createEffect`, which is | ||
danieljcafonso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
described in the [`Async methods`](#async-methods) section) has no `container`, | ||
`baseElement` or queries in its options or return value. Instead, it has an | ||
`owner` to be used with | ||
[`runWithOwner`](https://www.solidjs.com/docs/latest/api#runwithowner) if | ||
required. It also exposes a `cleanup` function, though this is already | ||
automatically called after the test is finished. | ||
|
||
```ts | ||
function renderHook<Args extends any[], Result>( | ||
hook: (...args: Args) => Result, | ||
options: { | ||
initialProps?: Args, | ||
wrapper?: Component<{ children: JSX.Element }> | ||
} | ||
) => { | ||
result: Result; | ||
owner: Owner | null; | ||
cleanup: () => void; | ||
} | ||
``` | ||
|
||
This can be used to easily test a hook / primitive: | ||
|
||
```ts | ||
const {result} = renderHook(createResult) | ||
expect(result).toBe(true) | ||
``` | ||
|
||
If you are using a `wrapper` with `renderHook`, make sure it will **always** | ||
return `props.children` - especially if you are using a context with | ||
asynchronous code together with `<Show>`, because this is required to get the | ||
value from the hook and it is only obtained synchronously once and you will | ||
otherwise only get `undefined` and wonder why this is the case. | ||
|
||
## `renderDirective` | ||
|
||
Solid.js supports | ||
[custom directives](https://www.solidjs.com/docs/latest/api#use___), which is a | ||
convenient pattern to tie custom behavior to elements, so we also have a | ||
`renderDirective` call, which augments `renderHook` to take a directive as first | ||
danieljcafonso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
argument, accept an `initialValue` for the argument and a `targetElement` | ||
(string, HTMLElement or function returning an HTMLElement) in the `options` and | ||
also returns `arg` and `setArg` to read and manipulate the argument of the | ||
directive. | ||
|
||
```ts | ||
function renderDirective< | ||
Arg extends any, | ||
Elem extends HTMLElement | ||
>( | ||
directive: (ref: Elem, arg: Accessor<Arg>) => void, | ||
options?: { | ||
...renderOptions, | ||
initialValue: Arg, | ||
targetElement: | ||
| Lowercase<Elem['nodeName']> | ||
| Elem | ||
| (() => Elem) | ||
} | ||
): Result & { arg: Accessor<Arg>, setArg: Setter<Arg> }; | ||
``` | ||
|
||
This allows for very effective and concise testing of directives: | ||
|
||
```ts | ||
const {asFragment, setArg} = renderDirective(myDirective) | ||
expect(asFragment()).toBe('<div data-directive="works"></div>') | ||
setArg('perfect') | ||
expect(asFragment()).toBe('<div data-directive="perfect"></div>') | ||
``` | ||
|
||
## Async methods | ||
|
||
Solid.js reactive changes are pretty instantaneous, so there is rarely need to | ||
use `waitFor(…)`, `await findByRole(…)` and other asynchronous queries to test | ||
the rendered result, except for transitions, suspense, resources and router | ||
navigation. | ||
|
||
Solid.js manages side effects with different variants of `createEffect`. While | ||
you can use `waitFor` to test asynchronous effects, it uses polling instead of | ||
allowing Solid's reactivity to trigger the next step. In order to simplify | ||
testing those asynchronous effects, we have a `testEffect` helper that | ||
complements the hooks for directives and hooks: | ||
|
||
```ts | ||
testEffect(fn: (done: (result: T) => void) => void, owner?: Owner): Promise<T> | ||
|
||
// use it like this: | ||
test("testEffect allows testing an effect asynchronously", () => { | ||
const [value, setValue] = createSignal(0); | ||
return testEffect(done => createEffect((run: number = 0) => { | ||
if (run === 0) { | ||
expect(value()).toBe(0); | ||
setValue(1); | ||
} else if (run === 1) { | ||
expect(value()).toBe(1); | ||
done(); | ||
} | ||
return run + 1; | ||
})); | ||
}); | ||
``` | ||
|
||
It allows running the effect inside a defined owner that is received as an | ||
optional second argument. This can be useful in combination with `renderHook`, | ||
which gives you an owner field in its result. The return value is a Promise with | ||
the value given to the `done()` callback. You can either await the result for | ||
further assertions or return it to your test runner. | ||
|
||
## Known issues | ||
|
||
If you are using [`vitest`](https://vitest.dev/), then tests might fail, because | ||
the packages `solid-js`, and `@solidjs/router` (if used) need to be loaded only | ||
once, and they could be loaded both through the internal `vite` server and | ||
through node. Typical bugs that happen because of this is that dispose is | ||
supposedly undefined, or the router could not be loaded. | ||
|
||
Since version 2.8.2, our vite plugin has gained the capability to configure | ||
everything for testing, so you should only need extra configuration for globals, | ||
coverage, etc. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
--- | ||
id: intro | ||
title: Intro | ||
sidebar_label: Introduction | ||
--- | ||
|
||
[Solid Testing Library on GitHub][gh] | ||
|
||
> Inspired completely by [preact-testing-library][preact-docs] | ||
|
||
[preact-docs]: ../preact-testing-library/intro.mdx | ||
[gh]: https://github.com/solidjs/solid-testing-library | ||
|
||
```bash npm2yarn | ||
npm install --save-dev @solidjs/testing-library | ||
``` | ||
|
||
> This library is built on top of | ||
> [`DOM Testing Library`](dom-testing-library/intro.mdx) which is where most of | ||
> the logic behind the queries is. | ||
|
||
## The Problem | ||
|
||
You want to write tests for your Solid components so that they avoid including | ||
implementation details, and are maintainable in the long run. | ||
|
||
## This Solution | ||
|
||
The Solid Testing Library is a very lightweight solution for testing Solid | ||
components. Its primary guiding principle is: | ||
|
||
> [The more your tests resemble the way your software is used, the more confidence they can give you.](https://twitter.com/kentcdodds/status/977018512689455106) | ||
|
||
See the [Dom introduction][dom-solution-explainer] and [React | ||
introduction][react-solution-explainer] for a more in-depth explanation. | ||
|
||
[dom-solution-explainer]: ../dom-testing-library/intro.mdx#this-solution | ||
[react-solution-explainer]: ../react-testing-library/intro.mdx#this-solution | ||
|
||
**What this library is not**: | ||
|
||
1. A test runner or framework. | ||
2. Specific to a testing framework. | ||
|
||
If you using Jest we recommend using | ||
[solid-jest](https://github.com/solidjs/solid-jest) to properly resolve the | ||
browser version of Solid as Jest will default to the server version when run in | ||
Node. | ||
|
||
💡 If you are using Jest or vitest, you may also be interested in installing | ||
`@testing-library/jest-dom` so you can use [the custom jest matchers][jest-dom]. | ||
|
||
[jest-dom]: ../ecosystem-jest-dom |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.