Skip to content

Commit cd532fd

Browse files
committed
fix(tinybench-plugin): make sure beforeEach and afterEach are called for every benchmark iteration
1 parent 571fa46 commit cd532fd

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

packages/tinybench-plugin/src/index.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,29 @@ export function withCodSpeed(bench: Bench): Bench {
4747
console.log(`[CodSpeed] running with @codspeed/tinybench v${__VERSION__}`);
4848
setupCore();
4949
for (const task of bench.tasks) {
50-
// run before hooks
51-
if (task.opts.beforeAll != null) {
52-
await task.opts.beforeAll.call(task);
53-
}
54-
if (task.opts.beforeEach != null) {
55-
await task.opts.beforeEach.call(task);
56-
}
57-
58-
// run the actual benchmark, with instrumentation
5950
const uri = isCodSpeedBenchOptions(task.opts)
6051
? task.opts.uri
6152
: `${rootCallingFile}::${task.name}`;
62-
await optimizeFunction(task.fn);
53+
54+
await task.opts.beforeAll?.call(task);
55+
56+
// run optimizations
57+
await optimizeFunction(async () => {
58+
await task.opts.beforeEach?.call(task);
59+
await task.fn();
60+
await task.opts.afterEach?.call(task);
61+
});
62+
63+
// run instrumented benchmark
64+
await task.opts.beforeEach?.call(task);
6365
await (async function __codspeed_root_frame__() {
6466
Measurement.startInstrumentation();
6567
await task.fn();
6668
Measurement.stopInstrumentation(uri);
6769
})();
70+
await task.opts.afterEach?.call(task);
6871

69-
// run after hooks
70-
if (task.opts.afterEach != null) {
71-
await task.opts.afterEach.call(task);
72-
}
73-
if (task.opts.afterAll != null) {
74-
await task.opts.afterAll.call(task);
75-
}
72+
await task.opts.afterAll?.call(task);
7673

7774
// print results
7875
console.log(` ✔ Measured ${uri}`);

packages/tinybench-plugin/tests/index.integ.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ describe("Benchmark.Suite", () => {
131131

132132
it("should run before and after hooks", async () => {
133133
mockCore.Measurement.isInstrumented.mockReturnValue(true);
134+
mockCore.optimizeFunction.mockImplementation(async (fn) => {
135+
await fn();
136+
});
134137
const beforeAll = jest.fn();
135138
const beforeEach = jest.fn();
136139
const afterEach = jest.fn();
@@ -153,9 +156,11 @@ describe("Benchmark.Suite", () => {
153156
)
154157
.run();
155158

159+
// since the optimization is running the benchmark once before the actual run, the each hooks are called twice
160+
expect(beforeEach).toHaveBeenCalledTimes(4);
161+
expect(afterEach).toHaveBeenCalledTimes(4);
162+
156163
expect(beforeAll).toHaveBeenCalledTimes(2);
157-
expect(beforeEach).toHaveBeenCalledTimes(2);
158-
expect(afterEach).toHaveBeenCalledTimes(2);
159164
expect(afterAll).toHaveBeenCalledTimes(2);
160165
});
161166

0 commit comments

Comments
 (0)