Some years ago (2017) I discovered Jest.
But what is Jest:
Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
More information on jest.io
In this blog post I will not explain what jest is, but I will explain one of the features I really love: Using tables to test your code. You can build a test matrix, and then just run it through your code
Example
We have this code snippet that we want to test. As you see there can be 3 cases to test,
function calculate(a: number, b: number): number {
if (a < b) return a + b;
if (a === b) return a * b;
return a - b;
}
How we are used to do it.
With Jasmine our Jest we would write a test that looks like something bellow.
test('calculate(2, 3) should return 5', () => {
expect(calculate(2, 3)).toBe(5);
});
test('calculate(3, 2) should return 1', () => {
expect(calculate(3,2)).toBe(1);
});
test('calculate(3, 3) should return 9', () => {
expect(calculate(3, 3)).toBe(9);
});
We define the different test cases, and just write some tests for it.
But if we need to cover more test cases, then we will end up in copy pasting all these cases again and again.
Maybe we forget to update the description and finally we will end up in test cases that are no longer correct.
Add arrays that contains the test cases
Another option is to compose an array, with an array.
[[2, 3, 5]
[3, 2, 1]
[3, 3, 9]]
Then we write our test while looping over the result
test.each([[2, 3, 5], [3, 2, 1], [3, 3, 9]])
('calculate(%i, %i) should return $expected', (a, b, expected) => {
expect(calculate(a, b)).toBe(expected);
});
But again this is not maintainable and hard to read.
Also if you read the test again, you don’t know what the first value want to say, or how many values we should have.
Testing should be the documentation of your code
If we want to use the tests as the documentation of our code, then we need to make sure that the tests are readable and maintainable.
But we can use another solution in Jest, let’s look at a table
Add a table that contains the test results
But in fact our test data is a table:
| a | b | expected |
| 2 | 3 | 5 |
| 3 | 2 | 1 |
| 3 | 3 | 9 |
A table would be more readable for our code, also extending the test results would be much easier
We could write our tests as bellow
test.each`
a | b | expected
${2} | ${3} | ${5}
${3} | ${2} | ${1}
${3} | ${3} | ${9}
`('calculate($a, $b) should return $expected', ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});
And we could go further. We are working with typescript, so we want to add some type checking. We can define the type of our TestData just before and make more complicated test cases.
interface TestData {
a: number,
b: number,
expected: number
}
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
${2} | ${1} | ${3}
`('calculate($a, $b) should return $expected', ({ a, b, expected }: TestData) => {
expect(a + b).toBe(expected);
});
Top comments (0)