Skip to content

Commit

Permalink
fix test timings (via #1051)
Browse files Browse the repository at this point in the history
  • Loading branch information
baev authored Jul 5, 2024
1 parent 190f3be commit 5a92773
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 33 deletions.
13 changes: 6 additions & 7 deletions packages/allure-cucumberjs/src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export default class AllureCucumberReporter extends Formatter {
labels: [],
links: [],
testCaseId: md5(fullName),
start: Date.now(),
start: data.timestamp.nanos / 1000,
fullName,
};

Expand Down Expand Up @@ -338,7 +338,7 @@ export default class AllureCucumberReporter extends Formatter {
};
}
});
this.allureRuntime.stopTest(testUuid);
this.allureRuntime.stopTest(testUuid, { stop: data.timestamp.nanos / 1000 });
this.allureRuntime.writeTest(testUuid);
this.testResultUuids.delete(data.testCaseStartedId);

Expand Down Expand Up @@ -373,6 +373,7 @@ export default class AllureCucumberReporter extends Formatter {
const fixtureUuid = this.allureRuntime.startFixture(scopeUuid, type, {
name,
stage: Stage.RUNNING,
start: data.timestamp.nanos / 1000,
});
if (fixtureUuid) {
this.fixtureUuids.set(data.testCaseStartedId, fixtureUuid);
Expand All @@ -399,7 +400,7 @@ export default class AllureCucumberReporter extends Formatter {
const stepUuid = this.allureRuntime.startStep(testUuid, undefined, {
...createStepResult(),
name: `${stepKeyword}${stepPickle.text}`,
start: data.timestamp.nanos,
start: data.timestamp.nanos / 1000,
});

if (!stepPickle.argument?.dataTable) {
Expand Down Expand Up @@ -443,8 +444,7 @@ export default class AllureCucumberReporter extends Formatter {
});
}
});
// TODO stop from duration? use data.timestamp.nanos?
this.allureRuntime.stopFixture(fixtureUuid);
this.allureRuntime.stopFixture(fixtureUuid, { stop: data.timestamp.nanos / 1000 });
this.fixtureUuids.delete(data.testCaseStartedId);
return;
}
Expand Down Expand Up @@ -475,8 +475,7 @@ export default class AllureCucumberReporter extends Formatter {
}
});

// TODO stop from duration? use data.timestamp.nanos?
this.allureRuntime.stopStep(currentStep);
this.allureRuntime.stopStep(currentStep, { stop: data.timestamp.nanos / 1000 });
}

private onAttachment(message: messages.Attachment): void {
Expand Down
21 changes: 11 additions & 10 deletions packages/allure-jest/src/environmentFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
this.#handleTestStart(event.test);
break;
case "test_todo":
this.#handleTestTodo();
this.#handleTestTodo(event.test);
break;
case "test_fn_success":
this.#handleTestPass();
this.#handleTestPass(event.test);
break;
case "test_fn_failure":
this.#handleTestFail(event.test);
Expand Down Expand Up @@ -199,6 +199,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
{
name: test.name,
fullName: newTestFullName,
start: test.startedAt ?? undefined,
labels: [
{
name: LabelName.LANGUAGE,
Expand Down Expand Up @@ -235,12 +236,12 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
return testUuid;
}

#stopTest(testUuid: string) {
#stopTest(testUuid: string, duration: number) {
if (!testUuid) {
return;
}

this.runtime.stopTest(testUuid);
this.runtime.stopTest(testUuid, { duration });
this.runtime.writeTest(testUuid);
}

Expand All @@ -256,7 +257,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
});
}

#handleTestPass() {
#handleTestPass(test: Circus.TestEntry) {
const testUuid = this.runContext.executables.pop();

if (!testUuid) {
Expand All @@ -267,7 +268,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
result.stage = Stage.FINISHED;
result.status = Status.PASSED;
});
this.#stopTest(testUuid);
this.#stopTest(testUuid, test.duration ?? 0);
}

#handleTestFail(test: Circus.TestEntry) {
Expand All @@ -291,7 +292,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
...details,
};
});
this.#stopTest(testUuid);
this.#stopTest(testUuid, test.duration ?? 0);
}

#handleTestSkip(test: Circus.TestEntry) {
Expand All @@ -311,10 +312,10 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
result.stage = Stage.PENDING;
result.status = Status.SKIPPED;
});
this.#stopTest(testUuid);
this.#stopTest(testUuid, test.duration ?? 0);
}

#handleTestTodo() {
#handleTestTodo(test: Circus.TestEntry) {
const testUuid = this.runContext.executables.pop();

if (!testUuid) {
Expand All @@ -325,7 +326,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
result.stage = Stage.PENDING;
result.status = Status.SKIPPED;
});
this.#stopTest(testUuid);
this.#stopTest(testUuid, test.duration ?? 0);
}

#handleRunFinish() {
Expand Down
50 changes: 43 additions & 7 deletions packages/allure-js-commons/src/sdk/reporter/ReporterRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ import { resolveWriter } from "./writer/loader.js";

interface StepStack {
clear(): void;

removeRoot(rootUuid: string): void;

currentStep(rootUuid: string): string | undefined;

addStep(rootUuid: string, stepUuid: string): void;

removeStep(stepUuid: string): void;
}

Expand Down Expand Up @@ -161,15 +165,18 @@ export class ReporterRuntime {
updateFunc(fixture);
};

stopFixture = (uuid: string, stop?: number): void => {
stopFixture = (uuid: string, opts?: { stop?: number; duration?: number }): void => {
const fixture = this.state.getFixtureResult(uuid);
if (!fixture) {
// eslint-disable-next-line no-console
console.error(`could not stop fixture: no fixture with uuid ${uuid} is found`);
return;
}

fixture.stop = stop ?? Date.now();
const startStop = this.#calculateTimings(fixture.start, opts?.stop, opts?.duration);
fixture.start = startStop.start;
fixture.stop = startStop.stop;

fixture.stage = Stage.FINISHED;
};

Expand Down Expand Up @@ -212,7 +219,7 @@ export class ReporterRuntime {
this.notifier.afterTestResultUpdate(testResult);
};

stopTest = (uuid: string, stop?: number) => {
stopTest = (uuid: string, opts?: { stop?: number; duration?: number }) => {
const testResult = this.state.getTestResult(uuid);
if (!testResult) {
// eslint-disable-next-line no-console
Expand All @@ -223,7 +230,10 @@ export class ReporterRuntime {
this.notifier.beforeTestResultStop(testResult);
testResult.testCaseId ??= getTestResultTestCaseId(testResult);
testResult.historyId ??= getTestResultHistoryId(testResult);
testResult.stop = stop ?? Date.now();

const startStop = this.#calculateTimings(testResult.start, opts?.stop, opts?.duration);
testResult.start = startStop.start;
testResult.stop = startStop.stop;

this.notifier.afterTestResultStop(testResult);
};
Expand Down Expand Up @@ -291,7 +301,7 @@ export class ReporterRuntime {
updateFunc(step);
};

stopStep = (uuid: string, stop?: number) => {
stopStep = (uuid: string, opts?: { stop?: number; duration?: number }) => {
const step = this.state.getStepResult(uuid);
if (!step) {
// eslint-disable-next-line no-console
Expand All @@ -301,7 +311,10 @@ export class ReporterRuntime {

this.notifier.beforeStepStop(step);

step.stop = stop ?? Date.now();
const startStop = this.#calculateTimings(step.start, opts?.stop, opts?.duration);
step.start = startStop.start;
step.stop = startStop.stop;

step.stage = Stage.FINISHED;

this.stepStack.removeStep(uuid);
Expand Down Expand Up @@ -481,7 +494,7 @@ export class ReporterRuntime {
result.statusDetails = { ...result.statusDetails, ...message.statusDetails };
}
});
this.stopStep(stepUuid, message.stop);
this.stopStep(stepUuid, { stop: message.stop });
};

#handleAttachmentContentMessage = (rootUuid: string, message: RuntimeAttachmentContentMessage["data"]) => {
Expand Down Expand Up @@ -547,4 +560,27 @@ export class ReporterRuntime {
afters,
});
};

#calculateTimings = (start?: number, stop?: number, duration?: number): { start?: number; stop?: number } => {
const result: { start?: number; stop?: number } = { start, stop };
if (duration) {
const normalisedDuration = Math.max(0, duration);
if (result.stop !== undefined) {
result.start = result.stop - normalisedDuration;
} else if (result.start !== undefined) {
result.stop = result.start + normalisedDuration;
} else {
result.stop = Date.now();
result.start = result.stop - normalisedDuration;
}
} else {
if (result.stop === undefined) {
result.stop = Date.now();
}
if (result.start === undefined) {
result.start = result.stop;
}
}
return result;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,55 @@ const fixtures = {
] as Link[],
};

const randomInt = (max: number) => Math.floor(Math.random() * max);

describe("ReporterRuntime", () => {
it("should set test stop from duration", () => {
const writer = mockWriter();
const runtime = new ReporterRuntime({ writer });

const start = randomInt(10_000_000);
const duration = randomInt(100_000);
const rootUuid = runtime.startTest({ start });
runtime.stopTest(rootUuid, { duration });
runtime.writeTest(rootUuid);

const [testResult] = writer.writeResult.mock.calls[0];
expect(testResult.start).toBe(start);
expect(testResult.stop).toBe(start + duration);
});

it("should set test stop from stop", () => {
const writer = mockWriter();
const runtime = new ReporterRuntime({ writer });

const start = randomInt(10_000_000);
const duration = randomInt(100_000);
const rootUuid = runtime.startTest({ start });
runtime.stopTest(rootUuid, { stop: start + duration });
runtime.writeTest(rootUuid);

const [testResult] = writer.writeResult.mock.calls[0];
expect(testResult.start).toBe(start);
expect(testResult.stop).toBe(start + duration);
});

it("should update test start from stop and duration", () => {
const writer = mockWriter();
const runtime = new ReporterRuntime({ writer });

const start = randomInt(10_000_000);
const stop = randomInt(10_000_000);
const duration = randomInt(100_000);
const rootUuid = runtime.startTest({ start });
runtime.stopTest(rootUuid, { stop, duration });
runtime.writeTest(rootUuid);

const [testResult] = writer.writeResult.mock.calls[0];
expect(testResult.start).toBe(stop - duration);
expect(testResult.stop).toBe(stop);
});

it("should start/stop steps", () => {
const writer = mockWriter();
const runtime = new ReporterRuntime({ writer });
Expand Down Expand Up @@ -60,8 +108,36 @@ describe("ReporterRuntime", () => {

const rootUuid = runtime.startTest({});

const stepUuid = runtime.startStep(rootUuid, undefined, { name: "some name", start: 123 });
runtime.stopStep(stepUuid!, 321);
const start = randomInt(10_000_000);
const stop = randomInt(10_000_000);
const stepUuid = runtime.startStep(rootUuid, undefined, { name: "some name", start });
runtime.stopStep(stepUuid!, { stop });

runtime.stopTest(rootUuid);
runtime.writeTest(rootUuid);

const [testResult] = writer.writeResult.mock.calls[0];
const [step] = testResult.steps;

expect(step).toEqual(
expect.objectContaining({
name: "some name",
start,
stop,
}),
);
});

it("should set start/stop time from duration for steps", () => {
const writer = mockWriter();
const runtime = new ReporterRuntime({ writer });

const rootUuid = runtime.startTest({});

const start = randomInt(10_000_000);
const duration = randomInt(10_000);
const stepUuid = runtime.startStep(rootUuid, undefined, { name: "some name", start });
runtime.stopStep(stepUuid!, { duration });

runtime.stopTest(rootUuid);
runtime.writeTest(rootUuid);
Expand All @@ -72,8 +148,8 @@ describe("ReporterRuntime", () => {
expect(step).toEqual(
expect.objectContaining({
name: "some name",
start: 123,
stop: 321,
start,
stop: start + duration,
}),
);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/allure-playwright/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export class AllureReporter implements ReporterV2 {
stepResult.statusDetails = { ...getMessageAndTraceFromError(step.error) };
}
});
this.allureRuntime!.stopStep(currentStep, step.startTime.getTime() + step.duration);
this.allureRuntime!.stopStep(currentStep, { duration: step.duration });
}

async onTestEnd(test: TestCase, result: PlaywrightTestResult) {
Expand Down Expand Up @@ -363,7 +363,7 @@ export class AllureReporter implements ReporterV2 {
testResult.labels = newLabels;
});

this.allureRuntime!.stopTest(testUuid, result.startTime.getTime() + result.duration);
this.allureRuntime!.stopTest(testUuid, { duration: result.duration });
this.allureRuntime!.writeTest(testUuid);
}

Expand Down
5 changes: 2 additions & 3 deletions packages/allure-vitest/src/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default class AllureVitestReporter implements Reporter {
const testFullname = getTestFullName(task, cwd());
const testUuid = this.allureReporterRuntime!.startTest({
name: testDisplayName,
start: task.result?.startTime ?? Date.now(),
start: task.result?.startTime,
});

this.allureReporterRuntime!.updateTest(testUuid, (result) => {
Expand Down Expand Up @@ -137,8 +137,7 @@ export default class AllureVitestReporter implements Reporter {
}
}
});
const stop = task.result?.startTime ? task.result.startTime + (task.result.duration ?? 0) : undefined;
this.allureReporterRuntime!.stopTest(testUuid, stop);
this.allureReporterRuntime!.stopTest(testUuid, { duration: task.result?.duration ?? 0 });
this.allureReporterRuntime!.writeTest(testUuid);
}
}

0 comments on commit 5a92773

Please sign in to comment.