Skip to content

Commit 3d8aae7

Browse files
committed
Docs: Write "Reduce code duplication" chapter for QUnit.test.each()
1 parent 4349fa5 commit 3d8aae7

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

docs/api/QUnit/test.each.md

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,82 @@ Add tests using a data provider.
3030
| `assert` (object) | A new instance object with the [assertion methods](../assert/index.md) |
3131
| `data` (any) | Data item |
3232

33-
Use this method to add multiple tests that are similar, but with different data passed in.
33+
Use this method to define many similar tests, with different data passed in.
3434

35-
`QUnit.test.each()` generates multiple calls to [`QUnit.test()`](./test.md) internally, and has all the same capabilities such support for async functions, returning a Promise, and the `assert` argument.
35+
`QUnit.test.each()` generates multiple calls to [`QUnit.test()`](./test.md), and provides the same features, such as support for async functions and test context.
3636

3737
Each test case is passed one item from your dataset.
3838

3939
The [`only`](./test.only.md), [`todo`](./test.todo.md), [`skip`](./test.skip.md), and [`if`](./test.if.md) variants are also available, as `QUnit.test.only.each`, `QUnit.test.todo.each`, `QUnit.test.skip.each`, and `QUnit.test.if.each` respectively.
4040

41+
### Reduce code duplication
42+
43+
You can use `QUnit.test.each()` to write a single test, run once for each item in a dataset. This avoids code duplication and prevents unintentional drift over time between similar tests.
44+
45+
This tends to cut unintentional, unimportant, or undocumented differences. That in turn improves readability and comprehension to future contributors. When multiple tests do similar things, there can be _intentional_ and _unintentional_ differences. The intentional difference is motivated by what you want to cover (e.g. input A and input B). The _unintentional_ difference may be due to authors having their own coding style, or changing habits over time. As a contributor it can be confusing when your patch causes tests to fail. These unintentional differences make it difficult to judge if a test is "safe" to change. For example, if test A fails but B passes, and A would pass if it was written more like B, is A okay to change because it was only that way by accident? Or was this an intended alternative approach covered by that test?
46+
47+
By writing your tests with `QUnit.test.each()`, you write shared code only once. Any intentional differences are clearly visible through a declarative dataset. By writing it only once, it also encourages writing of code comments as you won’t have to duplicate and maintain these across multiple tests.
48+
49+
```js
50+
// Without QUnit.test.each()
51+
52+
QUnit.test('example', function (assert) {
53+
const mockPage1 = {
54+
title: 'Example',
55+
lastModified: '2011-04-01T12:00:00Z',
56+
content: 'Foo bar.'
57+
};
58+
const mockUser1 = {
59+
name: 'Admin',
60+
registered: '1991-10-18T12:00:00Z',
61+
role: 'administrator'
62+
};
63+
APP.appendToPage(mockPage1, mockUser1, 'Added text here.');
64+
assert.equal(mockPage1.content, 'Foo bar.\n\nAdded text here.');
65+
66+
const mockUser2 = {
67+
name: 'root',
68+
registered: '1963-06-09T03:00:00Z',
69+
role: 'administrator'
70+
};
71+
const mockPage2 = {
72+
title: 'Example',
73+
lastModified: '2011-04-01T12:00:00Z',
74+
content: ''
75+
};
76+
APP.appendToPage(mockPage2, mockUser2, 'Added text here.');
77+
assert.equal(mockPage2.content, 'Added text here.');
78+
});
79+
```
80+
81+
Compared to:
82+
83+
```js
84+
QUnit.test.each('example', {
85+
// Expect an empty line between existing content and appendage.
86+
'existing content': ['Foo.', 'Added text.', 'Foo.\n\nAdded text.'],
87+
88+
// No extra lines if the page started empty.
89+
'empty content': ['', 'Added text here.', 'Added text here.']
90+
91+
}, function (assert, [input, appendage, expected]) {
92+
const mockPage = {
93+
title: 'Example',
94+
lastModified: '2011-04-01T12:00:00Z',
95+
content: input
96+
};
97+
const mockUser = {
98+
name: 'Admin',
99+
registered: '1991-10-18T12:00:00Z',
100+
// Roles are always lowercase
101+
role: 'administrator'
102+
};
103+
APP.appendToPage(mockPage, mockUser, appendage);
104+
105+
assert.equal(mockPage.content, expected);
106+
});
107+
```
108+
41109
## Changelog
42110

43111
| [QUnit 2.23.0](https://github.com/qunitjs/qunit/releases/tag/2.23.0) | Add [automatic labels](https://github.com/qunitjs/qunit/issues/1733) for primitive values in arrays.

0 commit comments

Comments
 (0)