Skipped vs. Pending Tests in Cypress: Understanding the Terminology Trap


While working with Cypress, you may encounter discrepancies in test reports that appear, at first glance, to be bugs. For example, your test runner or reporter might list a number of tests as “pending,” when you’re sure you deliberately marked them as “skip.” This isn’t a bug in Cypress—it’s a terminology nuance that can easily trip up even experienced developers.

In this post, we’ll unpack the difference between pending and skipped tests in Cypress, show examples of how Cypress distinguishes between the two, and explain why some reporters might present confusing or even misleading summaries.


Cypress Definitions: Pending vs. Skipped

Cypress internally distinguishes between tests that are pending and tests that are skipped, but those terms may not mean what you expect them to mean.

Pending Tests

Pending tests are those that you explicitly choose not to run. Cypress identifies a test as pending in one of the following ways:

// Test explicitly marked as pending
it.skip('should do something but not yet', () => {})

// Group of tests skipped
context.skip('pending test group', () => {
  it('is pending', () => {})
})

// Test with no callback function
it('has no implementation')  // This is also treated as pending

These tests are parsed but never scheduled for execution. You’re signaling to Cypress: I’m aware of this test, but I don’t want it to run yet.

Skipped Tests

Skipped tests, by contrast, are those that Cypress intended to run, but something prevented them from being executed. This usually happens due to a failure in a lifecycle hook like beforeEach.

Example:

beforeEach(() => {
  throw new Error('Setup failed!')
})

it('should run but setup fails', () => {
  // This never runs
})

it('also never runs', () => {
  // This too is skipped
})

Here, Cypress planned to run both tests, but since the beforeEach threw an error, they were skipped at runtime.


Why the Confusion?

The confusion often arises because third-party reporters or test dashboards might label pending tests as “skipped”, conflating the two. While this feels intuitive—after all, the tests didn’t run—the distinction matters to Cypress.

Under the hood, Cypress treats the two states differently:

StateCypress TermExecution StatusMarked By
✅ Ready to run“test”Will executeit(...) with a valid callback
⏸️ Skipped“skipped”Scheduled but didn’t runHook failure (e.g., beforeEach)
🚫 Pending“pending”Never scheduled to runit.skip, missing callback

Thus, Cypress is not misreporting; it is accurately representing test state based on internal semantics.


Recommendations

  • Use it.skip when you’re intentionally deferring a test’s implementation.
  • Expect skipped tests if setup code fails. If you see many skipped tests unexpectedly, check your beforeEach or beforeAll hooks.
  • Review your reporter: If you’re using a custom or third-party reporter, be aware it may merge “pending” and “skipped” into a single category.