fix(test runner): make sure we always teardown all fixtures (#8158)

Even if one of the fixtures throws, we should teardown all of them
so that we can run afterAll hooks.
This commit is contained in:
Dmitry Gozman 2021-08-12 09:08:56 -07:00 committed by GitHub
parent f3b35b2bbd
commit d32d50a906
2 changed files with 63 additions and 2 deletions

View file

@ -223,14 +223,23 @@ export class FixtureRunner {
} }
async teardownScope(scope: FixtureScope) { async teardownScope(scope: FixtureScope) {
let error: Error | undefined;
// Teardown fixtures in the reverse order. // Teardown fixtures in the reverse order.
const fixtures = Array.from(this.instanceForId.values()).reverse(); const fixtures = Array.from(this.instanceForId.values()).reverse();
for (const fixture of fixtures) { for (const fixture of fixtures) {
if (fixture.registration.scope === scope) if (fixture.registration.scope === scope) {
await fixture.teardown(); try {
await fixture.teardown();
} catch (e) {
if (error === undefined)
error = e;
}
}
} }
if (scope === 'test') if (scope === 'test')
this.testScopeClean = true; this.testScopeClean = true;
if (error !== undefined)
throw error;
} }
async resolveParametersAndRunHookOrTest(fn: Function, workerInfo: WorkerInfo, testInfo: TestInfo | undefined, paramsStepCallback?: CompleteStepCallback) { async resolveParametersAndRunHookOrTest(fn: Function, workerInfo: WorkerInfo, testInfo: TestInfo | undefined, paramsStepCallback?: CompleteStepCallback) {

View file

@ -349,3 +349,55 @@ test('beforeAll failure should prevent the test, but not afterAll', async ({ run
'%%afterAll', '%%afterAll',
]); ]);
}); });
test('fixture error should not prevent afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.js': `
const test = pwt.test.extend({
foo: async ({}, use) => {
await use('foo');
throw new Error('bad fixture');
},
});
test('good test', ({ foo }) => {
console.log('\\n%%test');
});
test.afterAll(() => {
console.log('\\n%%afterAll');
});
`,
});
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1);
expect(result.output).toContain('bad fixture');
expect(result.output.split('\n').filter(line => line.startsWith('%%'))).toEqual([
'%%test',
'%%afterAll',
]);
});
test('afterEach failure should not prevent afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.js': `
const { test } = pwt;
test('good test', ({ }) => {
console.log('\\n%%test');
});
test.afterEach(() => {
console.log('\\n%%afterEach');
throw new Error('bad afterEach');
})
test.afterAll(() => {
console.log('\\n%%afterAll');
});
`,
});
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1);
expect(result.output).toContain('bad afterEach');
expect(result.output.split('\n').filter(line => line.startsWith('%%'))).toEqual([
'%%test',
'%%afterEach',
'%%afterAll',
]);
});