📜 ⬆️ ⬇️

AVA - Futuristic JavaScript library for testing.

In this article I want to introduce you to a new library for testing AVA . Relatively new, it is already more than 2 years old, and it has acquired a solid number of plug-ins and of course the community that develops it. We will look at the library functionality. Set up the environment and write a couple of tests to look at the library in action.


What does AVA offer?


First of all, the library offers speed. Tests are run in parallel, which accelerates the execution of tests. As an example, the Pageres project is given in which testing was postponed to AVA , which gave an increase of almost 3 times (31 seconds were and 11 became). Tests do not depend on the global state and on other tests, which of course simplifies testing. Out of the box, es2015 is immediately used.


What you need to do to start using AVA now?


Install the appropriate npm module. Set as a dependency to work in a specific folder.


// package.json ..., "scripts": { "test": "ava" }, ... 

 npm install -D ava npm test 

or globally


 npm i -g ava ava 

Running tests


It's time to write the first test, take an example from the official repository. And save it as my-tests.js


 import test from 'ava'; test('foo', t => { t.pass(); }); test('bar', async t => { const bar = Promise.resolve('bar'); t.is(await bar, 'bar'); }); 

Immediately we see the use of es2015 with arrow functions, let and async. In my opinion, the minimalist syntax was not deceived.


Run tests


 npm test my-tests.js // or ava my-tests.js 

And we get the result


 2 passed 

If we want to see more detailed information about each test, we can use the parameters for the module


 ava my-tests.js --verbose // or ava my-tests.js -v 

  foo bar 2 tests passed 

We can also run watcher to develop TDD style.


 ava my-tests.js --watch // or ava my-tests.js -w 

You can see the full list of parameters


 ava --help 

Library API


Simple test:


 test('description', t => { }); 

One of the most common situations when you need to perform only one test of all:


 test.only('test only', t => { t.pass(); }); 

Skip the test, you may need to refactor, search for errors:


 test.only('test only', t => { t.fail(); }); 

Dough cap


Delivered to the API level, which is very interesting. You can make a reminder right in the tests.


 test.todo(''); 

If we need to test the asynchronous part of the code, we can use "cb":


 test.cb('callback', t => { setTimeout(function() { console.log('time'); t.end(); }, 3000); }); 

Orderly execution of tests


The serial parameter allows us to perform tests in a specific sequence. For example, we want to check the existence of a configuration file. If not, you need to create it. We will do 2 tests, one will create our file, and the second to check.


And it will be more convenient for us that they start exactly in sequence.


 import test from 'ava'; import fs from 'fs'; const path = 'serial-test-one.txt'; test.cb('serial 1: create file', t => { fs.writeFile(path, 'test', function(err) { if (err) { t.fail(); } else { t.pass(); } t.end(); }); }); test.cb('serial 2: is file exists', t => { fs.access(path, fs.F_OK, function(err) { if (err) { t.fail(); } else { t.pass(); } t.end(); }); }); 

By writing this code we get


  serial-one › serial 2 serial-one › serial 1 2 tests passed 

And we see that the tests started and ended successfully. But this is not correct, this code does not guarantee the execution in the order we need. If we simulate a situation when there is no file yet, skip the creation test, we will get an error


  - serial-oneserial 1 serial-oneserial 2 Test failed via t.fail() 1 test failed 1 test skipped 1. serial-oneserial 2 AssertionError: Test failed via t.fail() serial-one.js:19:9 FSReqWrap.oncomplete (fs.js:123:15) 

To ensure consistency, we can use the --serial or -s option.


 ava serial-one.js -s serial-one › serial 1 serial-one › serial 2 2 tests passed 

Or use


 test.cb.serial('serial 1', t => { ... }); 

The test falls and we know about it. We can clearly indicate this.


 test.failing('failing', t => { t.fail(); }); 

As a result, we see that this test falls, but we know about it, and ideally we are already doing something.


 1 known failure 

Very pleased that we can combine the parameters. This allows us to implement tests of any complexity and run in only the necessary and in the right order.


 test.only.cb test.cb.only 

Before and After


To configure the test environment there are before and after. They will be executed once at the start of test execution and at the end, respectively.


 test.before(t => { }); test.after(t => { }); 

We can also declare several such functions and they will be called in the order of adding


 test.before(t => { console.log('before'); }); test.before(t => { console.log('before#2'); }); before before#2 

Works for after.


If the text falls, after are not called. To remedy the situation you need to use the always modifier.


 test.after.always(t => { }); 

beforeEach and afterEach


When we need to set up the environment before each test, we use beforeEach and afterEach.


 test.beforeEach(t => { }); test.afterEach(t => { }); 

For them, the same behavior as for before and after is preserved: the declaration order and, if there is an error in the test, the after are not called (if there is not always).


Assertions


 test('test', t => { t.pass(); t.skip.fail(); t.truthy(true); t.truthy('unicorn'); t.falsy(false); t.falsy(1 === 0); t.true(true); t.false(false); t.is(1, 1); t.not(1, 0); t.deepEqual([0, 1, 2], [0, 1, 2]); t.notDeepEqual([0, 2, 2], [0, 1, 2]); }); 

Very convenient deepEqual, and the ability to skip the check.
Separately, we consider the error output, it is very detailed.


 test(t => { const a = /foo/; const b = 'bar'; const c = 'baz'; t.true(a.test(b) || b === c); }); 

 t.true(a.test(b) || b === c) | | | | | "bar" "bar" "baz" false 

Which certainly helps debugging.


Plugins


Before exploring AVA, I wrote tests on Jasmine . I like the Behavior-Driven style. For this AVA has a plugin ava-spec .


 npm i -D ava-spec 

Then we can write tests like this.


 import {describe} from 'ava-spec'; describe('module#1', it => { it('can look almost like jasmine', t => { t.deepEqual([1, 2], [1, 2]); }); it.todo('todo'); it.skip('fail', t => { t.fail(); }); }); 

TAP - Test Anything Protocol


We can customize information about our tests. I liked the tap-summary .


 npm i -D tap-summary 

We use


 ava ava-spec.js -t | tap-summary 

Real modules for testing


Let's make a function, put it in a separate file, connect it and test it.


 // ./test/sum.spec.js import { describe } from 'ava-spec'; import sum from '../src/sum'; describe('sum', it => { it('should return 10', t => { const expected = 10; const actual = sum(3, 7); t.is(actual, expected); }); }); 

 // ./src/sum.js function sum(x, y) { return x + y; } module.exports = sum; 

 ava test/sum.spec.js 

Everything works, our code from the file is connected and tested. But there is a problem, our code is written on ES5, and tests are ES6. Let's fix this situation. AVA out of the box uses Babeljs . And for our code, we will use it too. Configuring configs.


 // .babelrc { "presets": [ "es2015" ] } 

and for AVA. The AVA config is right in package.json.


 // ./package.json ..., "ava": { "babel": "inherit", "require": [ "babel-register" ] }, ... 

We launch without changes.


 ava test/sum.spec.js 

Total


AVA provides an excellent test development platform. This library has everything for it: minimalistic style, quick execution, flexibility in writing tests, work with tests and the environment for them, informative error output. In total, with the ability to customize both the test code itself, based on preferences and necessity, and the output of information on tests.


About the author of the library


I would like to tell a little bit about the author of this library. This is probably one of the most famous people in the JS community of Sindre Sorhus . On his page on github you can look at his projects and treasure in the community. And / or you can get to know him as a person, as far as possible on the Internet, or ask question / s through ama - Ask me anything! .


PS



Useful links:



')

Source: https://habr.com/ru/post/313468/


All Articles