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:
State | Cypress Term | Execution Status | Marked By |
---|---|---|---|
✅ Ready to run | “test” | Will execute | it(...) with a valid callback |
⏸️ Skipped | “skipped” | Scheduled but didn’t run | Hook failure (e.g., beforeEach ) |
🚫 Pending | “pending” | Never scheduled to run | it.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
orbeforeAll
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.