Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 44 additions & 34 deletions docs/en/testing/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

Dojo provides a robust testing framework using `@dojo/cli-test-intern`. It allows you to efficiently test the output of your widgets and validate your expectations.

| Feature | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Minimal API** | Simple API for testing and asserting Dojo widget's expected virtual DOM and behavior. |
| **Unit tests** | Unit tests are tests run via node and browser to test isolated blocks of code. |
| **Functional tests** | Functional tests are run using Selenium in the browser and test the overall functionality of the software as a user would interact with it. |
| **Assertion templates** | Assertion Templates allow you to build expected render functions to validate the output of your widgets. |
| Feature | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Minimal API** | Simple API for testing and asserting Dojo widget's expected virtual DOM and behavior. |
| **Unit tests** | Unit tests are tests run via node and browser to test isolated blocks of code. |
| **Functional tests** | Functional tests are run using Selenium in the browser and test the overall functionality of the software as a user would interact with it. |
| **Assertions** | Assertions allow you to build expected render functions to validate the output of your widgets. |

# Basic usage

Expand Down Expand Up @@ -41,7 +41,7 @@ dojo test --functional --config local

## Writing unit tests

- Using Dojo's [`harness` API](/learn/testing/dojo-test-harness#harness-api) for unit testing widgets.
- Using Dojo's [test `renderer` API](/learn/testing/test-renderer) for unit testing widgets.

> src/widgets/Home.tsx

Expand All @@ -63,23 +63,22 @@ export default Home;
```ts
const { describe, it } = intern.getInterface('bdd');
import { tsx } from '@dojo/framework/core/vdom';
import harness from '@dojo/framework/testing/harness';
import assertionTemplate from '@dojo/framework/testing/assertionTemplate';
import renderer, { assertion } from '@dojo/framework/testing/renderer';

import Home from '../../../src/widgets/Home';
import * as css from '../../../src/widgets/Home.m.css';

const baseTemplate = assertionTemplate(() => <h1 classes={[css.root]}>Home Page</h1>);
const baseAssertion = assertion(() => <h1 classes={[css.root]}>Home Page</h1>);

describe('Home', () => {
it('default renders correctly', () => {
const h = harness(() => <Home />);
h.expect(baseTemplate);
const r = renderer(() => <Home />);
r.expect(baseAssertion);
});
});
```

The `harness` API allows you to verify that the output of a rendered widget is what you expect.
The `renderer` API allows you to verify that the output of a rendered widget is what you expect.

- Does it render as expected?
- Do event handlers work as expected?
Expand Down Expand Up @@ -118,9 +117,9 @@ describe('routing', () => {
});
```

## Using assertion templates
## Using assertions

Assertion templates provide a way to create a base assertion that allow parts of the expected output to vary between tests.
Assertions provide a way to create a base assertion that allow parts of the expected output to vary between tests.

- Given a widget that renders output differently based on property values:

Expand All @@ -145,57 +144,68 @@ const Profile = factory(function Profile({ properties }) {
export default Profile;
```

- Create an assertion template using `@dojo/framework/testing/assertionTemplate`
- Create an assertion using `@dojo/framework/testing/renderer#assertion`

> tests/unit/widgets/Profile.tsx

```ts
```tsx
const { describe, it } = intern.getInterface('bdd');
import { tsx } from '@dojo/framework/core/vdom';
import assertionTemplate from '@dojo/framework/testing/assertionTemplate';
import harness from '@dojo/framework/testing/harness';
import renderer, { assertion } from '@dojo/framework/testing/renderer';

import Profile from '../../../src/widgets/Profile';
import * as css from '../../../src/widgets/Profile.m.css';

// Create an assertion
const profileAssertion = assertionTemplate(() => (
<h1 classes={[css.root]} assertion-key="welcome">
Welcome Stranger!
</h1>
));
const profileAssertion = assertion(() => <h1 classes={[css.root]}>Welcome Stranger!</h1>);

describe('Profile', () => {
it('default renders correctly', () => {
const h = harness(() => <Profile />);
const r = renderer(() => <Profile />);
// Test against my base assertion
h.expect(profileAssertion);
r.expect(profileAssertion);
});
});
```

A value can be provided to any virtual DOM node under test using `assertion-key` properties defined in the assertion template. Note: when `v()` and `w()` from `@dojo/framework/core/vdom` are used, the `~key` property serves the same purpose.
To work with assertion, wrapped nodes can get created using `@dojo/framework/testing/renderer#wrap` in order to use the assertion API. Note: when using wrapped `VNode`s with `v()`, the `.tag` property needs to get used, for example `v(WrappedDiv.tag, {} [])`.

> tests/unit/widgets/Profile.tsx

```ts
```tsx
const { describe, it } = intern.getInterface('bdd');
import { tsx } from '@dojo/framework/core/vdom';
import renderer { wrap, assertion } from '@dojo/framework/testing/renderer';

import Profile from '../../../src/widgets/Profile';
import * as css from '../../../src/widgets/Profile.m.css';

// Create a wrapped test node
const WrappedHeader = wrap('h1');

// Create an assertion
const profileAssertion = assertion(() => (
// Use the wrapped node in place of the normal node
<WrappedHeader classes={[css.root]}>Welcome Stranger!</WrappedHeader>
));

describe('Profile', () => {
it('default renders correctly', () => {
const h = harness(() => <Profile />);
const r = renderer(() => <Profile />);
// Test against my base assertion
h.expect(profileAssertion);
r.expect(profileAssertion);
});

it('renders given username correctly', () => {
// update the expected result with a given username
const namedAssertion = profileAssertion.setChildren('~welcome', () => ['Welcome Kel Varnsen!']);
const h = harness(() => <Profile username="Kel Varnsen" />);
h.expect(namedAssertion);
const namedAssertion = profileAssertion.setChildren(WrappedHeader, () => ['Welcome Kel Varnsen!']);
const r = renderer(() => <Profile username="Kel Varnsen" />);
r.expect(namedAssertion);
});
});
```

Using the `setChildren` method of an assertion template with the assigned `assertion-key` value, ~welcome in this case, will return an assertion template with the updated virtual DOM structure. This resulting assertion template can then be used to test widget output.
Using the `setChildren` method of an assertion with a wrapped testing node, `WrappedHeader` in this case, will return an assertion with the updated virtual DOM structure. This resulting assertion can then be used to test widget output.

[dojo cli]: https://github.com/dojo/cli
[intern]: https://theintern.io/
Expand Down
Loading