Slow Tests with Jest
When faced with slow-executing Angular unit tests, even with Jest, debugging can start in a couple of places. 2 of which are unit test setup and Jest setup.
When evaluating the unit test setup, note what is being stubbed and how huge these stubs are. Especially, when testing components. We often use data mocks, and stubs or spies for services. Simply because this practice comes with some notable benefits, mostly with stubs.
For one, it’s harder to call service methods unintentionally since we can specify what exists and what doesn’t. We can also fake taxing & error-prone operations like data fetches or async methods.
Alas, stubs may not be a one-size-fits-all type of testing solution when dealing with large services. They are registered in a beforeEach()
when configuring the testing module. This setup is factored into the test execution time.
If switching from some stubs to some spies does nothing for the test execution time, then evaluate Jest setup.
Right of the bat, there are a couple of Jest CLI options we can use that directly impact test execution time.
When enabled, Jest executes the tests within the same process that it uses to run. Serially. The alternative involves child processes created by Jest in which the tests are run. Parallelly 🧐. The difference in test execution time should be noticeable & immediate.
This option takes a value or percentage that usually represents the max number of cores Jest will use to run tests on a specific machine. The default being totalMachineCores — 1
. It involves a little more trial & error to find that sweet spot for execution time.
This option might be key, more so, for slow test startup than execution time.
Apparently, Jest uses a lot of packages under-the-hood 🤔. One in particular, jest-haste-map
, is concerned with project files and dependencies. It provides files and modification details to Jest.
When watchman is available, by default, Jest uses it to keep track of the projects files and changes. Ideally, it is invoked once by Jest to get the list of files. Thereafter, it is used to provide modification details for those cached files— what has changed since then.
When it’s unavailable, on Windows for example, it uses a custom Node.js implementation to get the project files details. This custom implementation is then invoked every single time jest
is run which contributes to that slower startup time.
References & Further Reading: