An Overview of JavaScript Testing in 2017

Vitali Zaidman
Apr 19, 2017 · 17 min read

***** Important update: ****

A new version of this guide for 2019 was released.

Test Types

Test Tools Types

describe('calculator', function() {  // describes a module with nested "describe" functions
describe('add', function() {
// specify the expected behavior
it('should add 2 numbers', function() {
//Use assertion functions to test the expected behavior
})
})})
// Chai expect
expect(foo).to.be.a('string')
expect(foo).to.equal('bar')
// Jasmine expect
expect(foo).toBeString()
expect(foo).toEqual('bar')
// Chai assert
assert.typeOf(foo, 'string')
assert.equal(foo, 'bar')
// Unexpected expect
expect(foo, 'to be a', 'string')
expect(foo, 'to be', 'bar')
it('should call method once with the argument 3', () => {
const spy = sinon.spy(object, 'method')
spy.withArgs(3) object.method(3) assert(spy.withArgs(3).calledOnce)
})
sinon.stub(user, 'isValid').returns(true) // SinonspyOn(user, 'isValid').andReturns(true) // Jasmine
it('resolves with the right name', done => {  const stub = sinon.stub(User.prototype, 'fetch')
.resolves({ name: 'David' })

User.fetch()
.then(user => {
expect(user.name).toBe('David')
done()
})
})
it('returns an object containing all users', done => {  const server = sinon.fakeServer.create()  server.respondWith('GET', '/users', [
200,
{ 'Content-Type': 'application/json' },
'[{ "id": 1, "name": "Gwen" }, { "id": 2, "name": "John" }]'
])
Users.all()
.done(collection => {
const expectedCollection = [
{ id: 1, name: 'Gwen' },
{ id: 2, name: 'John' }
]
expect(collection.toJSON()).to.eql(expectedCollection) done()
})

server.respond()
server.restore()
});
it('renders correctly', () => {
const linkInstance = (
<Link page="http://www.facebook.com">Facebook</Link>
)
const tree = renderer.create(linkInstance).toJSON() expect(tree).toMatchSnapshot()
})

Putting it All Together

List of General Prominent Testing Tools

Choose Your Framework

// "describe" is in the global scope already
// so no these require lines are not required:
//
// const jasmine = require('jasmine')
// const describe = jasmine.describe
describe('calculator', function() {
...
})

Unit Tests

Integration Tests

Functional Tests

describe('login form', () => {  before(() => {
return driver.navigate().to('http://path.to.test.app/')
})
it('autocompletes the name field', () => { driver.findElement(By.css('.autocomplete'))
.sendKeys('John')
driver.wait(until.elementLocated(By.css('.suggestion'))) driver.findElement(By.css('.suggestion')).click() return driver.findElement(By.css('.autocomplete'))
.getAttribute('value')
.then(inputValue => {
expect(inputValue).to.equal('John Doe')
})
})

after(() => {
return driver.quit()
})
})
Feature: A reader can share an article to social networks
As a reader
I want to share articles
So that I can notify my friends about an article I liked
Scenario: An article was opened
Given I'm inside an article
When I share the article
Then the article should change to a "shared" state
module.exports = function() {
this.Given(/^I'm inside an article$/, function(callback) {
// functional testing tool code
})
this.When(/^I share the article$/, function(callback) {
// functional testing tool code
})

this.Then(/^the article should change to a "shared" state$/, function(callback) {
// functional testing tool code
})
}

Contribute

Conclusion

In the end, the best decisions regarding application architecture today are made by understanding general solution patterns that are developed by the very active community, and combining them with your own experience and understanding of the characteristics of your application and it’s special needs.

Oh, and writing, and rewriting, and rewriting, and rewriting, and testing different solutions :)

Suggested Articles

General

testdouble, Sinon

Unexpected.js

Testing Frameworks Comparison

Jest

Ava

Tape

Selenium

TestCafe

powtoon-engineering

on animation, video, design, software and what's between them

Vitali Zaidman

Written by

https://vzaidman.com

powtoon-engineering

on animation, video, design, software and what's between them