I recently built to address a problem that I often run into when writing tests. I’ve found that in order to create a test suite that is comprehensive, maintainable, and doesn’t have an insane amount of repeated code, I end up using a approach. Using this approach at helps us deliver test code that is both useful in catching regressions, and is also easy to read and comprehend. Sazerac JavaScript data-driven Rocket Insights “Data-driven” tests are boiled down to a set of given inputs and expected outputs. Encapsulating your application code into will help facilitate this input/output testing style, and is generally a good practice to follow. pure functions While the latest JS stacks (like + ) encourage a pure functional approach, the most widely used testing frameworks ( , , and ) aren’t with this approach in mind. They often assume that you’ll be testing code with side-effects. Think code “spying”, and (to a certain extent) mocking. These features were created for testing impure functions, but there’s nothing to use specifically for testing pure functions. React Redux Jasmine Mocha Jest designed I feel strongly about the need for a testing framework with the data-driven approach at its core. Building that framework would be a big undertaking, so I chose a lighter option. I designed as a helper library that works with Jasmine, Mocha, and Jest. Sazerac I might consider turning into a standalone framework, but I’d like to see if people find it useful first. Sazerac Getting Down to It Let’s look at some code. This pure function returns or depending on whether the given parameter is a prime number. isPrime() true false num Here are some tests for given the numbers , , , and . isPrime() , 1 2 3 4 That’s a lot of code to write. If I wanted to add more test cases, I’d have to do some copy and paste. This just doesn’t feel right. Here are the same tests, using . Sazerac Sazerac will use these test cases to run **describe** and **it** functions that work with Jasmine, Mocha, Jest. The describe/it messages are set based on given input and expected output, so test reports are super consistent: isPrime()when given 1✓ should return truewhen given 2✓ should return truewhen given 3✓ should return truewhen given 4✓ should return false In The Real World Things are usually more complicated. Your code isn’t always as simple as the function. Take this React component, for example. isPrime() This component expects a object with 3 props, , , and . If any of those props are missing, it renders an error message and an class at the root element. If all the props have values, it renders a success message and no class. product title price inventory error error I’m going to use (awesome for testing React components) to help test this. In my spec file, I’ll create a function to mount the component. Enzyme This function’s expected return value is complex, so the method that was used for can’t be used here. I’ll use Sazerac’s method instead. .expect() isPrime() .assert() In this example, the object is the return value of given . The test above will pass if the element (at the root of the component) has the class . p ProductComponent() {} product error More expectations can be added using additional **.assert()** calls on the same test case. Each call runs a new test for with the given input, . In this example, these 3 tests are run: .assert() ProductComponent() {} ProductComponent()when given {}✓ should render `error` class✓ should display error message✓ should not display success message And It Gets Better We just tested for the “empty” object case, but what about other cases that might result in a similar state? For example, if , , or is missing, we would expect the component to render with the same error state. title price inventory Sazerac’s **forCases()** method lets you group test cases that share the same expectations. Resulting in the following tests: ProductComponent()when given {}✓ should render `error` class✓ should display error message✓ should not display success messagewhen given {"price":"1.11","inventory":"111"}✓ should render `error` class✓ should display error message✓ should not display success messagewhen given {"title":"p1","inventory":"111"}✓ should render `error` class✓ should display error message✓ should not display success messagewhen given {"title":"p1","price":"1.11"}✓ should render `error` class✓ should display error message✓ should not display success message This ends up being much more concise than the equivalent tests written with , , , etc. It also makes it super easy to add new cases, or to update existing ones as needed. describe it beforeEach Try It Out I’d recommend taking a few of your existing tests and refactoring them to use . My hope is that it will reduce the complexity and increase readability of your tests. Sazerac If you have feedback, get in touch with me on twitter @MikeCalvanese