UNPKG

6.98 kBMarkdownView Raw
1# Zora
2
3[![npm](https://badgen.net/npm/v/zora)](https://www.npmjs.com/package/zora)
4[![install size](https://badgen.net/packagephobia/install/zora)](https://packagephobia.now.sh/result?p=zora)
5
6## Usage
7
8The library is a _regular_ Javascript module and can be directly imported from a CDN:
9
10```Javascript
11import {test} from 'https://unpkg.com/zora@latest/dist/index.js'
12
13test(`hello from zora`, ({ok}) => {
14 ok(true, 'it worked');
15})
16```
17
18(Like in the [following codepen](https://codepen.io/lorenzofox3/pen/LYWOaYV?editors=1111))
19
20Or installed via a package manager such [NPM](https://www.npmjs.com/) by running the command (assuming you have [Nodejs](https://nodejs.org/en/) installed on your machine):
21
22``npm i -D zora``
23
24You can then build your testing program by using the exported ``test`` function
25
26```Javascript
27import {test} from 'zora';
28
29test(`my very first test`, (assertion) => {
30 const input = false;
31 assertion.ok(input, 'input should be truthy');
32})
33
34```
35
36You can run the testing program (with node's runtime for example) and it will start reporting its execution into the console
37
38<details>
39 <summary>test-output.tap</summary>
40
41```TAP
42TAP version 13
43# my very first test
44not ok 1 - input should be truthy
45 ---
46 actual: false
47 expected: "truthy value"
48 operator: "ok"
49 at: " file:///path/to/sample.js:5:13"
50 ...
51
521..1
53# tests 1
54# pass 0
55# fail 1
56# skip 0
57
58```
59
60</details>
61
62## Reporters
63
64This output format is called [TAP](https://testanything.org/tap-version-13-specification.html) (Test Anything Protocol). It is a standard text based format a machine can easily parse. It means there are [plenty of reporters](https://www.npmjs.com/search?q=tap%20reporter) you can pipe the standard output stream into (not only in the Javascript world). This will help you to tailor the reporting for your particular needs.
65
66for example, you can use [tap-diff](https://www.npmjs.com/package/tap-diff):
67``node path/to/testing/program.js | tap-diff``
68
69You can even use basic bash command:
70
71``node path/to/testing/program.js | grep '^not ok\|^\s'`` will output a basic, straight to the point test report:
72
73```
74not ok 1 - input should be truthy
75 ---
76 actual: false
77 expected: "truthy value"
78 operator: "ok"
79 at: " file:///path/to/sample.js:5:13"
80 ...
81```
82
83That is the beauty of using different processes to run the testing program and to format its output: it remains very flexible.
84
85## Assertion API
86
87When you start a test suite with the ``test`` function. The spec functions you pass as argument will get an instance of the [Assertion object](../assert) so you can write a wide range of different expectations.
88
89For the best performances, all the spec functions run concurrently unless you specifically wait for them within an asynchronous function (if for some reason, you want to run some test one after the other, in a serial mode).
90
91<details>
92 <summary>control-flow.js</summary>
93
94```Javascript
95import {test} from 'zora';
96
97let state = 0;
98
99test('test 1', t => {
100 t.ok(true);
101 state++;
102});
103
104test('test 2', t => {
105 //Maybe yes maybe no, you have no guarantee ! In this case it will work as everything is sync
106 t.equal(state, 1);
107});
108
109//Same thing here even in nested tests
110test('grouped', t => {
111 let state = 0;
112
113 t.test('test 1', t => {
114 t.ok(true);
115 state++;
116 });
117
118 t.test('test 2', t => {
119 //Maybe yes maybe no, you have no guarantee ! In this case it will work as everything is sync
120 t.equal(state, 1);
121 });
122});
123
124//And
125test('grouped', t=>{
126 let state = 0;
127
128 t.test('test 1', async t=>{
129 t.ok(true);
130 await wait(100);
131 state++;
132 });
133
134 test('test 2', t=>{
135 t.equal(state, 0, 'see the old state value as it will have started to run before test 1 is done');
136 });
137});
138
139//But
140test('grouped', async t => {
141 let state = 0;
142
143 //specifically WAIT for the end of this test before moving on !
144 await t.test('test 1', async t => {
145 t.ok(true);
146 await wait(100);
147 state++;
148 });
149
150 test('test 2', t => {
151 t.equal(state, 1, 'see the updated value!');
152 });
153});
154```
155
156</details>
157
158
159## Environment variables
160
161You can _configure_ the testing program with environment variables. With nodejs, simply pass it with the command line:
162
163``ZORA_REPORTER=json node path/to/testing/program.js``
164
165In the browser, you have to set it as a global before the testing program runs:
166
167```HTML
168<script>
169 window.ZORA_REPORTER='json'
170</script>
171<script type="module">
172 import {test} from 'url/to/zora';
173
174 test('some test', (t) => {
175 t.ok(true);
176 })
177</script>
178```
179
180### ZORA_REPORTER=json
181
182By default, the output is a TAP stream; but you can decide to produce a stream defined by [the zora json protocol messages](../reporters) if you which to build a custom reporter on top of it.
183
184### ZORA_ONLY=true
185
186Beside the ``test`` function you can use the ``only`` function if you wish to skip all the other tests. However, from the testing program perspective, ``only`` is meaningless: it is just a convenience for a developer, locally on its machine.
187So if you wish to use ``only`` you need to pass the ``ZORA_ONLY`` environment variable, otherwise the program will throw an exception to prevent ``only`` statement to slip in the remote versioning control system.
188
189Beware that if you want to run only a nested test suite, all the parent test suites must use the ``only statement`:`
190
191<details>
192 <summary>test-with-only.js</summary>
193
194```Javascript
195import {only, test} from 'zora';
196
197test('will be skipped', t => {
198 t.ok(false);
199})
200
201only('some test', t => {
202
203 // will be skipped as well
204 t.test('some nested test', t => {
205 t.ok(false);
206 });
207
208 // will run
209 t.only('some other nested test', t => {
210 t.ok(true);
211 });
212});
213```
214
215</details>
216
217### ZORA_TIMEOUT
218
219In milliseconds: change the default test timeout value (see below)
220
221## test timeout
222
223If a test hangs or takes too long to complete, it will report a failure. By default, the threshold is 5000ms. You can change that global value thanks to the ``ZORA_TIMEOUT`` environment variable.
224You can change that value for a given text as well, thanks to the options object:
225
226<details>
227 <summary>timeout example</summary>
228
229```Javascript
230test(
231 'broken promise',
232 ({ ok }) => {
233 return new Promise(() => {}).then(() => {
234 ok(true);
235 });
236 },
237 { timeout: 500 }
238);
239```
240
241</details>
242
243## skip a test
244
245You can skip a test using the root level ``skip`` function or within a test suite using the ``skip`` method of the assertion object
246
247<details>
248 <summary>test-with-skip.js</summary>
249
250```Javascript
251import {skip, test} from 'zora';
252
253skip('will be skipped', t => {
254 t.ok(false);
255})
256
257test('some test', t => {
258
259 // will be skipped as well
260 t.skip('some nested test', t => {
261 t.ok(false);
262 });
263
264 // will run
265 t.test('some other nested test', t => {
266 t.ok(true);
267 });
268});
269```
270
271</details>