Skip to content

runtime: don't fail the test run for undefined/ambiguous when in dry run #1814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
### Removed

### Fixed

* When running with `--dry-run`, undefined or ambiguous steps no longer cause the process to exit with code 1. ([#1814](https://github.com/cucumber/cucumber-js/pull/1814))
* When running the help command, it now shows all available formatters under the --format option.
[#1798](https://github.com/cucumber/cucumber-js/pull/1798)

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ The following documentation is for master. See below the documentation for older
* [Attachments](/docs/support_files/attachments.md)
* [API Reference](/docs/support_files/api_reference.md)
* Guides
* [Dry Run](./docs/dry_run.md)
* [ES Modules](./docs/esm.md)
* [Formatters](./docs/formatters.md)
* [Running in parallel](./docs/parallel.md)
Expand Down
20 changes: 20 additions & 0 deletions docs/dry_run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Dry Run

You can run cucumber-js in "Dry Run" mode like this:

```shell
$ cucumber-js --dry-run
```

The effect is that cucumber-js will still do all the aggregation work of looking at your feature files, loading your support code etc but without actually executing the tests. Specifically:

- No [hooks](./support_files/hooks.md) are executed
- Steps are reported as "skipped" instead of being executed
- Undefined and ambiguous steps are reported, but don't cause the process to fail

A few examples where this is useful:

- Finding unused step definitions with the [usage formatter](./formatters.md#usage)
- Generating [snippets](./snippets.md) for all undefined steps with the [snippets formatter](./formatters.md#snippets)
- Checking if your path, tag expression etc matches the scenarios you expect it to

22 changes: 20 additions & 2 deletions features/dryrun_mode.feature
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Feature: Dryrun mode
Given('a step', function() {})
"""
When I run cucumber-js with `--dry-run`
And it passes
Then scenario "some scenario" step "Given a step" has status "skipped"
And scenario "some scenario" has status "skipped"

Expand All @@ -30,12 +31,29 @@ Feature: Dryrun mode
Given('a(n) step', function() {});
"""
When I run cucumber-js with `--dry-run`
Then it fails
Then it passes
And scenario "some scenario" step "Given a step" has status "ambiguous"

Scenario: pending step

Since steps aren't actually executed in dry run, a step that would resolve to pending
will still show up as skipped.

Given a file named "features/step_definitions/cucumber_steps.js" with:
"""
const {Given} = require('@cucumber/cucumber')

Given('a step', function() {
return 'pending';
});
"""
When I run cucumber-js with `--dry-run`
Then it passes
And scenario "some scenario" step "Given a step" has status "skipped"

Scenario: undefined step
When I run cucumber-js with `--dry-run`
Then it fails
Then it passes
And scenario "some scenario" step "Given a step" has status "undefined"

Scenario: hooks should not execute in dry run, serial runtime
Expand Down
18 changes: 18 additions & 0 deletions src/runtime/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,21 @@ export function retriesForPickle(
}
return 0
}

export function shouldCauseFailure(
status: messages.TestStepResultStatus,
options: IRuntimeOptions
): boolean {
if (options.dryRun) {
return false
}
const failureStatuses: messages.TestStepResultStatus[] = [
messages.TestStepResultStatus.AMBIGUOUS,
messages.TestStepResultStatus.FAILED,
messages.TestStepResultStatus.UNDEFINED,
]
if (options.strict) {
failureStatuses.push(messages.TestStepResultStatus.PENDING)
}
return failureStatuses.includes(status)
}
15 changes: 2 additions & 13 deletions src/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { EventDataCollector, formatLocation } from '../formatter/helpers'
import StackTraceFilter from '../stack_trace_filter'
import UserCodeRunner from '../user_code_runner'
import VError from 'verror'
import { retriesForPickle } from './helpers'
import { retriesForPickle, shouldCauseFailure } from './helpers'
import { IdGenerator } from '@cucumber/messages'
import * as messages from '@cucumber/messages'
import TestCaseRunner from './test_case_runner'
Expand Down Expand Up @@ -109,7 +109,7 @@ export default class Runtime {
worldParameters: this.options.worldParameters,
})
const status = await testCaseRunner.run()
if (this.shouldCauseFailure(status)) {
if (shouldCauseFailure(status, this.options)) {
this.success = false
}
}
Expand Down Expand Up @@ -157,15 +157,4 @@ export default class Runtime {
}
return this.success
}

shouldCauseFailure(status: messages.TestStepResultStatus): boolean {
const failureStatuses: messages.TestStepResultStatus[] = [
messages.TestStepResultStatus.AMBIGUOUS,
messages.TestStepResultStatus.FAILED,
messages.TestStepResultStatus.UNDEFINED,
]
if (this.options.strict)
failureStatuses.push(messages.TestStepResultStatus.PENDING)
return failureStatuses.includes(status)
}
}
11 changes: 2 additions & 9 deletions src/runtime/parallel/coordinator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChildProcess, fork } from 'child_process'
import path from 'path'
import { retriesForPickle } from '../helpers'
import { retriesForPickle, shouldCauseFailure } from '../helpers'
import * as messages from '@cucumber/messages'
import { EventEmitter } from 'events'
import { EventDataCollector } from '../../formatter/helpers'
Expand Down Expand Up @@ -157,7 +157,7 @@ export default class Coordinator {
)
if (
!testCaseFinished.willBeRetried &&
this.shouldCauseFailure(worstTestStepResult.status)
shouldCauseFailure(worstTestStepResult.status, this.options)
) {
this.success = false
}
Expand Down Expand Up @@ -214,11 +214,4 @@ export default class Coordinator {
}
worker.process.send(runCommand)
}

shouldCauseFailure(status: messages.TestStepResultStatus): boolean {
return (
['AMBIGUOUS', 'FAILED', 'UNDEFINED'].includes(status) ||
(status === 'PENDING' && this.options.strict)
)
}
}