Test With A Different Item Every Day

How to pick a new daily item to use in your Cypress tests.

Recently a user asked in Filip Hric's Discord server how to pick a different test item daily to use in their Cypress tests.

How to pick a different test item daily question

An excellent question. Sometimes we have a lot of test items, but we want to pick a random one daily. Here is my solution:

  • take the current timestamp and convert to the number of days since the start of JS epoch (1970)
  • take the module of days vs test items, this gives you a test item's index. The index changes daily and "wraps" around to the first item when all items have been tested.

A sample code to pick an item:

1
2
3
4
5
const now = new Date()
// divide the timestamp by the number of milliseconds in 1 full day
const fullDaysSinceEpoch = Math.floor(now / 8.64e7)
const testIndex = fullDaysSinceEpoch % list.length
const testItem = list[testIndex]

🎁 You can find the full source code in the repo bahmutov/cypress-test-every-day.

Let's say the application is showing a randomized list of fruits. We know we want to eventually test every fruit from the JSON file test-fruits.json

test-fruits.json
1
["Apples 655", "Grapes 1001", "Pears 499"]

Our spec file and test JSON file are placed in the repo folder:

1
2
3
4
5
6
7
8
9
10
app/
test-fruits.json
cypress.config.js

public/
index.html
app.js
cypress/
e2e/
spec.cy.js

Let's pick a random test fruit from the JSON file. We can read the file using cy.readFile command

cypress/e2e/spec.cy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
it('shows one of the fruits', () => {
cy.visit('public/index.html')
cy.readFile('test-fruits.json')
.its('length')
.then((n) => {
cy.get('#fruit li').should('have.length', n)
})

cy.readFile('test-fruits.json').then((list) => {
const now = new Date()
const fullDaysSinceEpoch = Math.floor(now / 8.64e7)
const testFruitIndex = fullDaysSinceEpoch % list.length
const testFruit = list[testFruitIndex]
cy.log(
`picked test fruit ${fullDaysSinceEpoch} ${testFruitIndex}: ${testFruit}`,
)
cy.contains('#fruit li', testFruit)
})
})

The test picks a fruit and confirms it is present on the page

Tip: want to pick a new test item hourly? Divide the timestamp by the number of milliseconds in one hour.

Tip 2: want to pick consistent item locally and on the CI server? Use UTC timestamp.

Of course, if our test data comes from a JSON file, we can simply import it into our spec

cypress/e2e/spec2.cy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import testFruits from '../../test-fruits.json'

it('shows one of the fruits', () => {
cy.visit('public/index.html')
cy.get('#fruit li').should('have.length', testFruits.length)

const now = new Date()
const fullDaysSinceEpoch = Math.floor(now / 8.64e7)
const testFruitIndex = fullDaysSinceEpoch % testFruits.length
const testFruit = testFruits[testFruitIndex]
cy.log(
`picked test fruit ${fullDaysSinceEpoch} ${testFruitIndex}: ${testFruit}`,
)
cy.contains('#fruit li', testFruit)
})

Works the same way

Import the JSON test fixture directly into the spec

For more on JSON fixtures, read my blog post Import Cypress fixtures.