Node.js testing
- Use mocha for writing tests.
- Use chai for assertions.
- Use timekeeper for mocking or freezing time.
- Use [chai-as-promised])(https://github.com/domenic/chai-as-promised) for testing promise rejection/resolve. See
server/src/user/spec/user.spec.js
for examples. - Use chai-change for expectation blocks.
- Use local variables to mimic RSpec’s
let
functionality:describe('example test', () => { let user beforeEach(async () => { user = await models.User.findOne() }) it('user has name', () => { return expect(user.name).to.eql('John') }) })
Unit tests
- Place unit tests in
spec
folder which exists in the same folder as the code. e.g.user/interactors/Create.js
spec should be found atuser/interactors/spec/Create.spec.js
.
Feature tests
- Place feature tests in
test/features
directory. - Use Puppeteer for interaction with a browser. This has several benefits:
- Tests are faster compared to Selenium WebDriver or WebDrive.IO.
- Easy to run tests in headless mode.
- Brings it’s own chromium browser, so no more issues with chromedriver and chrome browser versions mismatch.
- Add
await
before each expectation when a test has multiple assertions. - However Puppeteer has very low-level API, so few helpers are needed to reduce tests verbosity. You can find them (or add your own) in
tests/helpers
folder. - Each feature test starts with
feature
directive instead of regulardescribe
. Make sure to usefeature
only at the top. If you need to nest feature tests, usedescribe
:feature('logging in', () => { describe('with correct login details', () => { it('logins user', async () => { await page.goto('http://localhost:3000/login', { waitUntil: 'networkidle' }) await page.typeText('input[name=username]', 'admin') await page.typeText('input[name=password]', 'secret123') await page.clickOn('#signin') await page.waitForNetworkIdle() expect(await page.plainText()).to.include('admin') }) }) })