Skip to content

Commit e512a2b

Browse files
committed
Parsing test cases to verify order and parallelism
1 parent 189a1d5 commit e512a2b

File tree

2 files changed

+94
-13
lines changed

2 files changed

+94
-13
lines changed

features/parallel_custom_assign.feature

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ Feature: Running scenarios in parallel with custom assignment
44
Given a file named "features/step_definitions/cucumber_steps.js" with:
55
"""
66
const {Then, setParallelCanAssign} = require('@cucumber/cucumber')
7-
const {expect} = require('chai')
8-
let value = 0;
97
setParallelCanAssign(() => false)
108
Then(/^value is (\d+)$/, function(v, cb) {
11-
expect(++value).to.eq(v)
129
setTimeout(cb, 150)
1310
})
1411
"""
@@ -23,6 +20,10 @@ Feature: Running scenarios in parallel with custom assignment
2320
"""
2421
When I run cucumber-js with `--parallel 2`
2522
Then it passes
23+
And tandem tests verified
24+
"""
25+
expect.fail('No tests should have executed at the same time')
26+
"""
2627

2728
Scenario: Both works run tests when a valid assignment helper is used
2829
Given a file named "features/step_definitions/cucumber_steps.js" with:
@@ -33,7 +34,7 @@ Feature: Running scenarios in parallel with custom assignment
3334
setParallelCanAssign(() => true)
3435
Then(/^value is (\d+)$/, function(v, cb) {
3536
expect(++value).to.eq(v)
36-
setTimeout(cb, 150)
37+
setTimeout(cb, 300)
3738
})
3839
"""
3940
And a file named "features/a.feature" with:
@@ -53,12 +54,9 @@ Feature: Running scenarios in parallel with custom assignment
5354
"""
5455
const {Given, setParallelCanAssign} = require('@cucumber/cucumber')
5556
let flag = true
56-
let processed = 0;
5757
setParallelCanAssign(() => (flag = !flag))
5858
Given(/^scenario (\d+)$/, function(scenario, cb) {
5959
setTimeout(cb, 150)
60-
if (scenario === 1) throw Error(`#${scenario} was test ${++processed} on this worker`)
61-
processed++;
6260
})
6361
"""
6462
And a file named "features/a.feature" with:
@@ -74,11 +72,8 @@ Feature: Running scenarios in parallel with custom assignment
7472
Given scenario 3
7573
"""
7674
When I run cucumber-js with `--parallel 2`
77-
Then it fails
78-
And the output contains the text:
79-
"""
80-
#1 was test 2 on this worker
81-
"""
75+
Then it passes
76+
And it runs tests in order b, c, a
8277

8378
Scenario: assignment is appropriately applied and fails at last processed scenario 'a'
8479
Given a file named "features/step_definitions/cucumber_steps.js" with:
@@ -136,4 +131,8 @@ Feature: Running scenarios in parallel with custom assignment
136131
Given scenario simple 3
137132
"""
138133
When I run cucumber-js with `--parallel 2`
139-
Then it passes
134+
Then it passes
135+
And tandem tests verified
136+
"""
137+
expect(_pickle1.tags[0].name).to.not.eq(_pickle2.tags[0].name)
138+
"""
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { Then } from '../../'
2+
import { World } from '../support/world'
3+
import _, { Dictionary } from 'lodash'
4+
import { messages } from '@cucumber/messages'
5+
import { expect } from 'chai'
6+
7+
interface TestCaseParser {
8+
pickles: Dictionary<messages.IPickle>
9+
testCases: Dictionary<string>
10+
running: Set<string>
11+
testStarts: Dictionary<string>
12+
}
13+
14+
function defaultHandlers({
15+
pickles,
16+
testCases,
17+
running,
18+
testStarts,
19+
}: TestCaseParser): Record<string, Function> {
20+
return {
21+
pickle: (p: messages.IPickle) => (pickles[p.id] = p),
22+
testCase: (t: messages.TestCase) => (testCases[t.id] = t.pickleId),
23+
testCaseStarted: (t: messages.TestCaseStarted) => {
24+
running.add(t.testCaseId)
25+
testStarts[t.id] = t.testCaseId
26+
},
27+
testCaseFinished: (t: messages.TestCaseFinished) =>
28+
running.delete(testStarts[t.testCaseStartedId]),
29+
}
30+
}
31+
32+
function parse(
33+
envelopes: messages.IEnvelope[],
34+
handlers: Record<string, Function>
35+
): void {
36+
_.each(envelopes, (envelope) =>
37+
_.forOwn(envelope, (value, key) => {
38+
;(handlers[key] || _.noop)(value)
39+
})
40+
)
41+
}
42+
43+
Then(/^it runs tests in order (.+)$/, function (this: World, order: string) {
44+
const running = new Set<string>()
45+
const pickles: Dictionary<messages.IPickle> = {}
46+
const testCases: Dictionary<string> = {}
47+
const testStarts: Dictionary<string> = {}
48+
const scenarioNames = order.split(/,\s*/)
49+
const handlers = defaultHandlers({ pickles, running, testCases, testStarts })
50+
handlers.testCaseStarted = (t: messages.TestCaseStarted) =>
51+
expect(pickles[testCases[t.testCaseId]].name).to.eq(scenarioNames.shift())
52+
parse(this.lastRun.envelopes, handlers)
53+
})
54+
55+
Then(/^tandem tests verified$/, function (this: World, assertion: string) {
56+
const running = new Set<string>()
57+
const pickles: Dictionary<messages.IPickle> = {}
58+
const testCases: Dictionary<string> = {}
59+
const testStarts: Dictionary<string> = {}
60+
const assertFn = (
61+
_pickle1: messages.IPickle,
62+
_pickle2: messages.IPickle
63+
): boolean => {
64+
// eslint-disable-next-line no-eval
65+
return eval(`
66+
const { expect } = require('chai')
67+
${assertion}
68+
`)
69+
}
70+
71+
const handlers = defaultHandlers({ pickles, running, testCases, testStarts })
72+
handlers.testCaseStarted = _.wrap(
73+
handlers.testCaseStarted,
74+
(fn, t: messages.TestCaseStarted) => {
75+
running.forEach((tcId) =>
76+
assertFn(pickles[testCases[tcId]], pickles[testCases[t.testCaseId]])
77+
)
78+
fn(t)
79+
}
80+
)
81+
parse(this.lastRun.envelopes, handlers)
82+
})

0 commit comments

Comments
 (0)