Taking Control of Your Cypress Test Runs With Tags
Tags: cypress, testing
Published: 2020-05-29 18:48:41

## Intro

[Cypress](https://www.cypress.io/) is a phenomenal end-to-end testing tool. It's certainly not perfect but it's being [updated consistently](https://docs.cypress.io/guides/references/changelog.html) and it's expandable with [plugins](https://docs.cypress.io/plugins/index.html). I recently came upon a problem that required more granular control over my test runs than Cypress provides out of the box. Using our imagination, we'll take a similar journey to what I believe is a sweet solution to a problem you'll likely have. Let's go!

## Problem

Imagine you have a great set of Cypress tests for your calculator app, perfectly organized by feature:
```
cypress
└───integration
│   └───add
│   │   │   add.spec.js
│   └───subtract
│   │   │   subtract.spec.js
│   └───multiply
│   │   │   multiply.spec.js
│   └───divide
│   │   │   divide.spec.js
```
Within each of these spec files are several tests:
```javascript
// add.spec.js
it('add two numbers', () => {
 ...
})
it('add three fractions', () => {
 ...
})
```
```javascript
// subtract.spec.js
it('subtract a negative number from a positive number', () => {
 ...
})
it('subtract two whole numbers', () => {
 ...
})
```
You get the idea.

The time it takes to test your calculator app end-to-end with Cypress is a lot longer than your unit tests take so you run them nightly. In an effort to catch bugs sooner, you and your team have determined that a certain set of tests need to be executed as part of your [continuous integration](https://martinfowler.com/articles/continuousIntegration.html) pipeline. What's the best way to implement this?

## Solution
You figure out your best course of action through an iterative process:
### Good Solution - Separating Tests
First, you create `important-tests.spec.js` and move all the relevant tests into that file. You considered copying the tests but didn't want the hassle of keeping them in sync.
Then you run Cypress like this:
```bash
$ npx cypress run --spec 'path/to/important-tests.spec.js'
```
Easy enough, but you soon find out that maintenance is tricky because you now have double the number of files for each feature you need to maintain tests for. While this solution works, the additional complexity and cognitive load are too significant to scale effectively.
### Better Solution - Tagging Tests
You discover a great plugin [`cypress-select-tests`](https://github.com/bahmutov/cypress-select-tests) developed by Cypress' own [Gleb Bahmutov](https://glebbahmutov.com/), that provides a way to select or `grep` the specific tests you want to run. 

#### Setup
1. Install: 
```bash
$ npm install --save-dev cypress-select-tests
```
2. Update your `plugins/index.js` file:
```javascript
import selectTestsWithGrep from 'cypress-select-tests/grep'
export default (on, config) => {
  on('file:preprocessor', selectTestsWithGrep(config))
}
```
Now running tests like this:
```bash
$ npx cypress run --env grep='fraction' 
```
will execute only tests that contain `fraction` in the title. Sweet!

#### Tagging
The tests that need to run in CI are titled,
* `add three fractions`
* `subtract two whole numbers`
* `divide by zero`
* `subtract fractions`

You ask yourself,
> What search term will result in only these tests running?

and find that there aren't any, so you toy around with the idea of adding one:
* `ci divide by zero`
* `important: divide by zero`
* `divide by zero, important`
* `divide by zero, #important`

Settling on the last format makes sense to you because it's not ambiguous, it's out of the way and, and most importantly, it's _distinguishable_ from the other text, which reduces the risk that it'll be casually edited or a test that happens to have the term `important` in it won't be included in the run unintentionally. Phew!

### Finally
Finally, running Cypress like this:
```bash
$ npx cypress run --env grep="#important" 
```
results in a run - containing really important tests - that can be added to your pipeline so you can find critical bugs sooner without adding significant complexity to your workflow.

## Conclusion
Many thanks to [Gleb Bahmutov](https://glebbahmutov.com/blog) for his work on `cypress-select-tests`. I hope this was helpful to you!