Handy Tricks in JavaScript Testing
With the boom in JavaScript libraries, frameworks, and people picking this language up, I find common questions every time someone decides to write some tests with JavaScript. Here are some of the most common things I need to do in my tests, and how to do them, across three major tools: Jasmine, Mocha, and Jest.
Run a single test, or suite of tests
Scenario: I’m writing tests and don’t want to run my entire suite of tests across the project. What’s the quickest way to do this?
Mocha
Use only()
—
describe.only('This describe block will run by itself on test run'...// Or a single testit.only('This it block will run by itself on test run'...
Jest
Use only()
or f
— The “f” signifies focus
// Synonymous
describe.only('Your test suite'...
fdescribe('Your test suite'...// Or a single test// Synonymous
it.only('...
fit('...
Jasmine
Use fdescribe
or fit
fdescribe('Your tests...'// Or a single testfit('Your single test...'
Note: If you’re using Karma, you’ll likely be using it in conjunction with one of the options above. They should all work with Karma as written.
Testing Async Code
If you have Async code, such as querying a database or making a call to a server you need to ensure your test runs complete without pausing.
Jasmine/Jest/Mocha
Surprise of surprises… Most popular JS testing frameworks handle async code the same way.
Note: Use ONE of the following patterns, don’t mix and match in the same test!
Use done
— Call this method after your async call is returned to let Mocha know the test is complete.
it('will test async code', (done) => {
myAsyncCall().then((result) => {
expect(result).toBeDefined();
done();
});
});
Return a Promise
it('will test async code', () => {
return myAsyncCall().then((result) => {
expect(result).toBeDefined();
});
});
Note: Do not return a promise AND call done.
Use Async/Await
it('will test async code', async () => {
const result = await myAsyncCall();
expect(result).toBeDefined();
});
References:
Jest: https://jestjs.io/docs/asynchronous
Data-Driven Tests
When you have some functionality that you want to test with multiple parameters, test runners allow you to write a single test that will run multiple times based on the data that you pass in.
Jamine/Mocha
Use forEach
or any other form of a normal JS loop.
const testCases = [
{
one: 1,
two: 5,
result: 6
},
{
one: 1,
two: 5,
result: 6
},
{
one: 1,
two: 5,
result: 6
},
];
testCases.forEach((testCase) => {
it('should add two numbers', () => {
const result = add(testCase.one, testCase.two);
expect(result).toEqual(testCase.result);
});
});
Mocha Reference: https://mochajs.org/#dynamically-generating-tests
Jest
Jest provides a test.each
helper, that lets you pass the data as a parameter to a test and run it a little differently.
test.each([
{
one: 1,
two: 5,
result: 6
},
{
one: 1,
two: 5,
result: 6
},
{
one: 1,
two: 5,
result: 6
},
])('should add two numbers', (testCase) => {
const result = add(testCase.one, testCase.two);
expect(result).toEqual(testCase.result);
});
Reference: https://jestjs.io/docs/api#testeachtablename-fn-timeout