This is the main module. All uvu
tests require that either suite
or test
(or both) be imported.
You may declare multiple Suites
in the same file. This helps with organization as it group test output in a more readable fashion and allows related items to remain neighbors.
You should choose uvu.suite
if/when you'd like to leverage the additional organization.
You should choose uvu.test
if you don't care about organization and/or are only planning on testing a single entity.
There is no penalty for choosing uvu.suite
vs uvu.test
. In fact, uvu.test
is an unnamed Suite!
No matter which you choose, the Suite's run
must be called in order for it to be added to uvu
's queue.
Note: Because of this API decision,
uvu
test files can be executed withnode
directly!
Returns: Suite
Creates a new Suite
instance.
Of course, you may have multiple Suite
s in the same file.
However, you must remember to call run()
on each suite!
Returns: void
If you don't want to separate your tests into groups (aka, "suites") – or if you don't plan on testing more than one thing in a file – then you may want to import test
for simplicity sake (naming is hard).
Important: The
test
export is just an unnamedSuite
instance!
Type: String
The name of your test.
Choose a descriptive name as it identifies failing tests.
Type: Function<any>
or Promise<any>
The callback that contains your test code.
Your callback may be asynchronous and may return
any value, although returned values are discarded completely and have no effect.
All uvu
test suites share the same API and can be used in the same way.
In fact, uvu.test
is actually the result of unnamed uvu.suite
call!
The only difference between them is how their results are grouped and displayed in your terminal window.
API
Every suite instance is callable.
This is the standard usage.
For this suite
, only run this test.
This is a shortcut for isolating one (or more) test blocks.
Note: You can invoke
only
on multiple tests!
Skip this test block entirely.
Invoke the provided callback
before this suite begins.
This is ideal for creating fixtures or setting up an environment.
Please see Hooks for more information.
Invoke the provided callback
after this suite finishes.
This is ideal for fixture or environment cleanup.
Please see Hooks for more information.
Invoke the provided callback
before each test of this suite begins.
Please see Hooks for more information.
Invoke the provided callback
after each test of this suite finishes.
Please see Hooks for more information.
Start/Add the suite to the uvu
test queue.
Important: You must call this method in order for your suite to be run!
Example
Check out
/examples
for a list of working demos!
import { suite } from 'uvu';
import * as assert from 'uvu/assert';
import * as dates from '../src/dates';
const Now = suite('Date.now()');
let _Date;
Now.before(() => {
let count = 0;
_Date = global.Date;
global.Date = { now: () => 100 + count++ };
});
Now.after(() => {
global.Date = _Date;
});
// this is not run (skip)
Now.skip('should be a function', () => {
assert.type(Date.now, 'function');
});
// this is not run (only)
Now('should return a number', () => {
assert.type(Date.now(), 'number');
});
// this is run (only)
Now.only('should progress with time', () => {
assert.is(Date.now(), 100);
assert.is(Date.now(), 101);
assert.is(Date.now(), 102);
});
Now.run();
Your suite can implement "hooks" that run before and/or after the entire suite, as well as before and/or after the suite's individual tests.
It may be useful to use suite.before
and suite.after
to set up and teardown suite-level assumptions like:
- environment variables
- database clients and/or seed data
- generating fixtures
- mocks, spies, etc
It may be appropriate to use suite.before.each
and suite.after.each
to reset parts of suite's context, or for passing values between tests. This may include — but of course, is not limited to — rolling back database transactions, restoring a mocked function, etc.
Important: Any
after
andafter.each
hooks will always be invoked – including after failed assertions.
Example: Lifecycle
The following implements all available hooks so that their call patterns can be recorded:
test.before(() => {
console.log('SETUP');
});
test.after(() => {
console.log('CLEANUP');
});
test.before.each(() => {
console.log('>> BEFORE');
});
test.after.each(() => {
console.log('>> AFTER');
});
// ---
test('foo', () => {
console.log('>>>> TEST: FOO');
});
test('bar', () => {
console.log('>>>> TEST: BAR');
});
test.run();
// SETUP
// >> BEFORE
// >>>> TEST: FOO
// >> AFTER
// >> BEFORE
// >>>> TEST: BAR
// >> AFTER
// CLEANUP