Know Your Tests

Find Cypress specs and list all tests and their tags from the command line.

If you have a repository with large number of Cypress specs, pretty soon they get out of control. What if you have 200 tests, how do you find which tests cover what feature? How do you run all the tests testing X or Y? I the blog post How To Tag And Run End-to-End Tests I have described how we organize, tag, and run end-to-end tests at Mercari US. In this blog post I will demo a little CLI utility find-cypress-specs I use to keep track of the tests in the project.

📦 You can find the example repository with the specs I am using in this blog post at bahmutov/test-todomvc-using-app-actions.

Print just the specs

Cypress finds its integration specs inside cypress/integration folder - but you might have renamed it into tests/e2e. So just to find the spec files requires looking at the cypress.json file and using the config settings to glob for files. For example, in my project I ignore the utils.js and some other files.

cypress.json
1
2
3
4
5
6
7
{
"ignoreTestFiles": [
"*.page.js",
"utils.js",
"*.d.ts"
]
}

By default find-cypress-specs simply finds spec files following the settings from my configuration file

1
2
3
4
5
$ npx find-cypress-specs
cypress/integration/adding-spec.js,cypress/integration/clear-completed-spec.js,
cypress/integration/complete-all-spec.js,cypress/integration/editing-spec.js,
cypress/integration/item-spec.js,cypress/integration/persistence-spec.js,
cypress/integration/routing-spec.js,cypress/integration/spec.js

What if we want to see the tests and the suites inside each spec file?

Print all tests

Let's get an idea of what is inside each spec file. Using find-cypress-specs --names get the tests and their tags:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
$ npx find-cypress-specs --names

cypress/integration/adding-spec.js (7 tests)
└─ TodoMVC
├─ New Todo [@adding]
│ ├─ should allow me to add todo items [@regression]
│ ├─ adds items [@sanity, @regression]
│ ├─ should clear text input field when an item is added [@regression]
│ ├─ should append new items to the bottom of the list
│ ├─ should trim text input [@regression]
│ └─ should show #main and #footer when items added
└─ Adds items (spy example)
└─ calls inform

cypress/integration/clear-completed-spec.js (3 tests)
└─ TodoMVC
└─ Clear completed button [@complete]
├─ should display the correct text
├─ should remove completed items when clicked [@sanity, @regression]
└─ should be hidden when there are no items that are completed [@regression]

cypress/integration/complete-all-spec.js (3 tests)
└─ TodoMVC
└─ Mark all as completed [@complete]
├─ should allow me to mark all items as completed [@regression]
├─ should allow me to clear the complete state of all items [@sanity, @regression]
└─ complete all checkbox should update state when items are completed / cleared

cypress/integration/editing-spec.js (5 tests)
└─ TodoMVC
└─ Editing [@editing]
├─ should hide other controls when editing
├─ should save edits on blur [@sanity]
├─ should trim entered text
├─ should remove the item if an empty text string was entered
└─ should cancel edits on escape

cypress/integration/item-spec.js (3 tests)
└─ TodoMVC
└─ Item [@item]
├─ should allow me to mark items as complete [@sanity, @regression]
├─ should allow me to un-mark items as complete [@regression]
└─ should allow me to edit an item

cypress/integration/persistence-spec.js (1 test)
└─ TodoMVC
└─ Persistence [@persistence]
└─ should persist its data [@sanity, @regression]

cypress/integration/routing-spec.js (5 tests)
└─ TodoMVC
└─ Routing [@routing]
├─ should allow me to display active items [@regression]
├─ should respect the back button
├─ should allow me to display completed items [@sanity, @regression]
├─ should allow me to display all items [@regression]
└─ should highlight the currently applied filter

cypress/integration/spec.js (3 tests)
└─ TodoMVC
├─ When page is initially opened [@regression]
│ └─ should focus on the todo input field
├─ No Todos
│ └─ should hide #main and #footer [@regression]
└─ Counter
└─ should display the current number of todo items [@sanity, @regression]

found 8 specs (30 tests)

Ughh, the line height on my blog separates the individual lines, in the terminal it looks much better, maybe I should add some color

find-cypress-specs --names output in the terminal

Great, what if we had some tests pending? The find-cypress-specs would tell us.

1
2
3
4
5
6
7
8
9
10
cypress/integration/spec.js (3 tests, 1 pending)
└─ TodoMVC
├─ When page is initially opened [@regression]
│ └─ should focus on the todo input field
├─ No Todos
│ └─ should hide #main and #footer [@regression]
└─ Counter
└⊙ should display the current number of todo items [@sanity, @regression]

found 8 specs (30 tests, 1 pending)

Each skipped block / test is marked and the count is shown. Pending tests are warning signs: they are either flaky or test a feature that is not working. Like commented out code, they eventually become a historical anomaly and must be removed.

Print and count the tags

Some tests have their own tags, and the suites might have their own tags. The suite tags apply to the tests inside them. We can count the tags across all specs and report the numbers.

1
2
3
4
5
6
7
8
9
10
11
12
$ npx find-cypress-specs --tags

Tag Tests
------------ -----
@adding 6
@complete 6
@editing 5
@item 3
@persistence 1
@regression 17
@routing 5
@sanity 8

Nice, we have tags covering individual features like @editing and @routing, and a few coverage sets of tests like @sanity and @coverage. These numbers are effective tags - if a tag is present on the parent suite, it applies and counts towards each test inside.

Tips for finding tests

I love looking at tests using find-cypress-specs.

Find all tests with a tag

To only show the tests tagged @sanity, use the grep CLI utility.

1
2
3
4
5
6
7
8
9
$ npx find-cypress-specs --names | grep @sanity
│ ├─ adds items [@sanity]
├─ should remove completed items when clicked [@sanity]
├─ should allow me to clear the complete state of all items [@sanity]
├─ should save edits on blur [@sanity]
├─ should allow me to mark items as complete [@sanity]
└─ should persist its data [@sanity]
├─ should allow me to display completed items [@sanity]
└─ should display the current number of todo items [@sanity]

To count the number of @sanity tests, pipe the output from the grep CLI utility to wc utility

1
2
$ npx find-cypress-specs --names | grep @sanity | wc -l
8

I must say this is very crude way, since it only supports tags on the test level. Follow my work in the repository to see if I release a better implementation.

Find test with its suite

To find a test by name and print its suite and file, use grep -B <N> to print N text lines before the match.

1
2
3
4
5
6
$ npx find-cypress-specs --names | grep 'adds items' -B 4
cypress/integration/adding-spec.js (7 tests)
└─ TodoMVC
├─ New Todo [@adding]
│ ├─ should allow me to add todo items
│ ├─ adds items [@sanity]