Imagine you work on an end-to-end web test. The test works locally, you commit the code, open a pull request and ... wait for 10-30 minutes for the tests to finish. Of course, your testing CI pipeline might be optimized like mine and finish quickly. Still, running all E2E tests to give you feedback on the spec you modified seems weird, doesn't it?
Run the changed spec first.
That's it. That is my advice. Normally, Cypress runs all specs it finds alphabetically. But if you pass the list of specs using the --spec ...
parameter, Cypress runs them in that order:
1 | $ npx cypress run --spec "cypress/e2e/spec-z.cy.js,cypress/e2e/spec-a.cy.js" |
So you can control the list of specs and their execution order. You can find the last commit date for each spec using the git
command with a custom pretty format:
1 | git log -1 --pretty=format:"%ct" -- <filename> |
For example, this blog post has the following recent commit Unix timestamp
1 | $ git log -1 --pretty=format:"%ct" -- source/_posts/run-changed-specs-first.md |
You just run this command for all specs, sort the results with the latest modified timestamp being first, and pass it to Cypress. I even implemented this approach in my utility find-cypress-specs.
1 | $ npx cypress run --spec $(npx find-cypress-specs --sort-by-modified) |
github actions
You can split finding the specs from running Cypress. For example, if you use Trying GitHub Actions:
1 | name: ci |
Note: this approach only looks at the spec files themselves. If you modify a utility file a spec imports, we won't use the modified dependency timestamp. You can look at just the changed specs including dependencies using the find-cypress-specs using --branch main
option, then it traces the spec module dependencies and imports.
cypress-fail-fast
Improvement: for pull requests you can use early termination to stop running specs if one fails. I use the plugin cypress-fail-fast to stop on the first failed test. Since we run the specs in the modified order, an error in the spec I just changed will stop the build quickly.
Nice!
cypress-split
Make it even faster: using the cypress-split plugin to run specs in parallel using multiple CI containers. When using the spec order, make sure to pass the specs using the environment variable in addition to the spec
parameter.
1 | - name: Find E2E specs ๐ |
This should do the trick across N machines