Goal
Reduce your code duplication, increase test maintability and speed up your test suites by writing Parameterized tests. With Jest.
What is Parameterized Testing?
Parameterized testing allows you to run the same test with different inputs automatically. It's efficient for testing functions over a range of inputs (ask your Q/A).
Why Use Parameterized Testing?
Efficiency
: Test multiple scenarios with one test case.Coverage
: Increases test coverage.Maintainability
: Easy to update and manage.Readability
: Clear and concise test cases.DRY
: Don't Repeat Yourself.Speed
: Faster test execution.Debugging
: Easier to identify failing test cases.Scalability
: Easily add new test cases.
How to Implement Parameterized Testing in Jest?
For this example, consider an email validation utility function:
// email.utils.ts
export function isEmailValid(email: string) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
Test Suit Without "Parameterized Testing"
// email.utils.test.ts
import { isEmailValid } from "./email.utils";
describe("Email Validation Utility", () => {
it("validates correctly formatted email", () => {
const email = "user@example.com";
const result = isEmailValid(email);
expect(result).toBe(true);
});
it("rejects email missing domain name", () => {
const email = "user@.com";
const result = isEmailValid(email);
expect(result).toBe(false);
});
it("rejects email missing top-level domain", () => {
const email = "user@example";
const result = isEmailValid(email);
expect(result).toBe(false);
});
it("rejects empty email string", () => {
const email = "";
const result = isEmailValid(email);
expect(result).toBe(false);
});
it("rejects email with trailing dot", () => {
const email = "user@example.com.";
const result = isEmailValid(email);
expect(result).toBe(false);
});
});
Test Suit With "Parameterized Testing"
// email.utils.spec.ts
import { isEmailValid } from './email.utils';
describe('Email Validation Utility', () => {
const testCases = [
{
description: 'validates correctly formatted email'
email: 'user@example.com',
expected: true,
},
{
description: 'rejects email missing domain name'},
email: 'user@.com',
expected: false,
{
description: 'rejects email missing top-level domain'},
email: 'user@example',
expected: false,
{
description: 'rejects empty email string'},
email: '',
expected: false,
{
description: 'rejects email with trailing dot'}
email: 'user@example.com.',
expected: false,
];
test.each(testCases)(`should ${expected ? '' : 'not '}accept ${email} - ${description}`,({email, expected})=> {
expect(isEmailValid(email)).toBe(expected);
})
});
In Summary
Writing tests the classic way can quickly become tedious and repetitive, decreasing the overall quality of your test suite and decrease the developer experience.
Parameterized testing is a great approach to writing tests which comes with a lot of benefits.
Not only does parameterized testing makes you think differently. It also helps you write better tests. The benefits are clear: less code, more coverage, faster tests, and better maintainability.