Skip to content

Commit 563076c

Browse files
random feature execution order (#1055)
1 parent d53e404 commit 563076c

File tree

11 files changed

+101
-1
lines changed

11 files changed

+101
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
22

33
### [Unreleased](https://github.com/cucumber/cucumber-js/compare/v4.1.0...master) (In Git)
44

5+
* add cli option `--order <TYPE[:SEED]>` to run scenarios in the specified order. Type should be `defined` or `random`
6+
57
### [4.1.0](https://github.com/cucumber/cucumber-js/compare/v4.0.0...v4.1.0) (2018-03-27)
68

79
#### New Features

features/order.feature

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
Feature: Set the execution order
2+
3+
Background:
4+
Given a file named "features/a.feature" with:
5+
"""
6+
Feature: some feature
7+
@a
8+
Scenario: first scenario
9+
Given a step
10+
11+
@b
12+
Scenario Outline: second scenario - <ID>
13+
Given a step
14+
15+
@c
16+
Examples:
17+
| ID |
18+
| X |
19+
| Y |
20+
21+
@d
22+
Examples:
23+
| ID |
24+
| Z |
25+
"""
26+
And a file named "features/step_definitions/cucumber_steps.js" with:
27+
"""
28+
import {Given} from 'cucumber'
29+
30+
Given(/^a step$/, function() {})
31+
"""
32+
33+
Scenario: run in defined order scenario
34+
When I run cucumber-js with `--order defined`
35+
Then it runs the scenarios:
36+
| NAME |
37+
| first scenario |
38+
| second scenario - X |
39+
| second scenario - Y |
40+
| second scenario - Z |
41+
42+
Scenario: run in random order with seed
43+
When I run cucumber-js with `--order random:234119`
44+
Then it runs the scenarios:
45+
| NAME |
46+
| second scenario - Z |
47+
| second scenario - X |
48+
| second scenario - Y |
49+
| first scenario |

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
"indent-string": "^3.1.0",
156156
"is-generator": "^1.0.2",
157157
"is-stream": "^1.1.0",
158+
"knuth-shuffle-seeded": "^1.0.6",
158159
"lodash": "^4.17.4",
159160
"mz": "^2.4.0",
160161
"progress": "^2.0.0",

src/cli/argv_parser.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ export default class ArgvParser {
8282
[]
8383
)
8484
.option('--no-strict', 'succeed even if there are pending steps')
85+
.option(
86+
'--order <TYPE[:SEED]>',
87+
'run scenarios in the specified order. Type should be `defined` or `random`',
88+
'defined'
89+
)
8590
.option(
8691
'-p, --profile <NAME>',
8792
'specify the profile to use (repeatable)',

src/cli/configuration_builder.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export default class ConfigurationBuilder {
4646
formatOptions: this.getFormatOptions(),
4747
listI18nKeywordsFor,
4848
listI18nLanguages,
49+
order: this.options.order,
4950
parallel: this.options.parallel,
5051
profiles: this.options.profile,
5152
pickleFilterOptions: {

src/cli/configuration_builder_spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('Configuration', () => {
3535
formats: [{ outputTo: '', type: 'progress' }],
3636
listI18nKeywordsFor: '',
3737
listI18nLanguages: false,
38+
order: 'defined',
3839
parallel: 0,
3940
pickleFilterOptions: {
4041
featurePaths: ['features/**/*.feature'],

src/cli/helpers.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Gherkin from 'gherkin'
55
import path from 'path'
66
import ProfileLoader from './profile_loader'
77
import Promise from 'bluebird'
8+
import shuffle from 'knuth-shuffle-seeded'
89

910
export async function getExpandedArgv({ argv, cwd }) {
1011
const { options } = ArgvParser.parse(argv)
@@ -21,6 +22,7 @@ export async function getTestCasesFromFilesystem({
2122
eventBroadcaster,
2223
featureDefaultLanguage,
2324
featurePaths,
25+
order,
2426
pickleFilter,
2527
}) {
2628
let result = []
@@ -36,6 +38,7 @@ export async function getTestCasesFromFilesystem({
3638
})
3739
)
3840
})
41+
orderTestCases(result, order)
3942
return result
4043
}
4144

@@ -65,3 +68,23 @@ export async function getTestCases({
6568
})
6669
return result
6770
}
71+
72+
// Orders the testCases in place - morphs input
73+
export function orderTestCases(testCases, order) {
74+
let [type, seed] = order.split(':')
75+
switch (type) {
76+
case 'defined':
77+
break
78+
case 'random':
79+
if (!seed) {
80+
seed = Math.floor(Math.random() * 1000 * 1000).toString()
81+
console.warn(`Random order using seed: ${seed}`)
82+
}
83+
shuffle(testCases, seed)
84+
break
85+
default:
86+
throw new Error(
87+
'Unrecgonized order type. Should be `defined` or `random`'
88+
)
89+
}
90+
}

src/cli/helpers_spec.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('helpers', () => {
3535
cwd: this.tmpDir,
3636
eventBroadcaster: this.eventBroadcaster,
3737
featurePaths: [featurePath],
38+
order: 'defined',
3839
pickleFilter: new PickleFilter({}),
3940
})
4041
})
@@ -79,6 +80,7 @@ describe('helpers', () => {
7980
cwd: this.tmpDir,
8081
eventBroadcaster: this.eventBroadcaster,
8182
featurePaths: [featurePath],
83+
order: 'defined',
8284
pickleFilter: new PickleFilter({
8385
featurePaths: [`${this.relativeFeaturePath}:5`],
8486
}),
@@ -119,6 +121,7 @@ describe('helpers', () => {
119121
cwd: this.tmpDir,
120122
eventBroadcaster: this.eventBroadcaster,
121123
featurePaths: [featurePath],
124+
order: 'defined',
122125
pickleFilter: new PickleFilter({}),
123126
})
124127
})

src/cli/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export default class Cli {
8888
eventBroadcaster,
8989
featureDefaultLanguage: configuration.featureDefaultLanguage,
9090
featurePaths: configuration.featurePaths,
91+
order: configuration.order,
9192
pickleFilter: new PickleFilter(configuration.pickleFilterOptions),
9293
})
9394
let success

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import supportCodeLibraryBuilder from './support_code_library_builder'
33

44
// Top level
55
export { default as Cli } from './cli'
6-
export { getTestCases, getTestCasesFromFilesystem } from './cli/helpers'
6+
export {
7+
getTestCases,
8+
getTestCasesFromFilesystem,
9+
orderTestCases,
10+
} from './cli/helpers'
711
export { default as PickleFilter } from './pickle_filter'
812
export { default as Runtime } from './runtime'
913
export { default as Status } from './status'

0 commit comments

Comments
 (0)