Unit testing is an incredibly important part of software development. You want to catch errors and breaking changes before they wreak havoc on your customers' integrations.
By creating a series of unit tests for your custom components, your development team can feel comfortable updating custom component code without the risk of introducing regressions. Plus, when you write unit tests you're creating sample use cases for your component, which yields documentation-as-code for your custom component.
Today let's work through adding unit tests to a sample custom component.
We'll first add the appropriate development dependencies to our component package, and then walk through simulating invocations of our component's actions with a couple of tests, so we can catch regressions if they occur in the future.
We developed a "unit converter" component as part of a blog post. TL;DR: a rocket fuel type (like "Kerosene") and amount (like "100 pounds") are passed in as inputs to our component, and the component does some computations and returns the equivalent amount of fuel in gallons. In this example, we pass in 100 pounds of kerosene to our pounds-to-gallons component:
We find that 100 pounds of kerosene is equivalent to about about 14.97 gallons:
Full source code for the unit converter component is available in our GitHub examples repo.
Now, we want to make sure that every time we enter "Kerosene" and "100 pounds" into our component, we get approximately "14.97 gallons" back out. If our developers decide to look up fuel densities from another data source or something, we want to ensure that their changes don't introduce regressions into our component.
So, let's add some tests now to automatically prevent issues in the future.
Next, we'll need to create a
jest.config.js config file to let Jest know that we're working with TypeScript:
Finally, let's add some scripts to our
package.json file so we can simply run
yarn test to invoke unit testing:
Now that we have the prerequisite configuration in place, let's write some Jest tests.
All of our component source code is in
Let's create a corresponding test file,
I'll throw the entire test source code here, and then we'll parse through it line by line:
The first line imports our component's two actions from
src/index.ts, and the second line imports a TypeScript type definition from Prismatic's Spectral library so we can cast our actions' outputs to an object and verify that the object contains correct return values:
The next portion outlines a test that we'd like to run.
test() function takes two arguments: the name of the test - "Convert pounds to gallons" - and the test function to execute:
Next, we invoke our
poundsToGallonsAction action's asynchronous
This is the function that is invoked when an integration is run.
perform function takes two parameters:
context which contains credentials, config variables and a logger, and
params which contains input parameters that are passed into the action.
Since our action doesn't take advantage of the credentials, config variables, or the logger, we can just pass
null in for the
We then pass in an object containing
params, and save the return value of our function to a variable named
Finally, we can use Jest's
toBeCloseTo functions to verify that the output that our action provided was (with some acceptable rounding error) equal to about 14.97 gallons:
The next several lines of code outline a similar test for converting gallons to pounds.
After writing our tests, we can run
yarn test to invoke Jest and verify that our actions' tests pass:
If someone later commits a change to our component that causes a regression, our build pipeline will run
yarn test and reject the committed code with an explanation of why the tests failed:
That's it! Within minutes we have working unit testing that slots nicely into our existing build pipeline.
We were already running
yarn build to build our component. Our CI/CD script just needs a
yarn test line added to it, and it'll begin to catch errors before they reach production.