From 0fc484c25e69e06c2e4808e56d1d1a0fd0406ea0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sat, 4 Jul 2026 16:58:16 +0100 Subject: [PATCH] fix: only warn about incomplete coverage when tests were rerun (#85) store.reruns is an array initialised to [], so the truthiness guard in getCoverage was always true and the 'coverage report may not be complete' warning fired on every run with coverage enabled. Check store.reruns.length instead so the warning only appears when tests were actually rerun or the run spanned multiple run ids. --- CHANGELOG.md | 1 + src/command/Testall.ts | 2 +- test/command/Testall.spec.ts | 78 ++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 886edac..bc364ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Abort and abandon a run that stalls before it starts processing (e.g. while stuck queued), rather than leaving it in-flight to be re-run. * Test run status logging now shows a `No progress /` suffix while a run is stalling, and resets log the reuse summary and a `Reset /` count. * `numberOfResets` in `TestRunSummary` now reports the total resets across all runs in a `Testall` invocation (including missing-test reruns), not just the outer run's count. +* Only warn that the coverage report may be incomplete when tests were actually rerun or the run was split across multiple run ids, instead of on every run with coverage enabled (#85). ## 3.3.1-beta.0 - 2026-06-14 diff --git a/src/command/Testall.ts b/src/command/Testall.ts index 86cc064..91fe13c 100644 --- a/src/command/Testall.ts +++ b/src/command/Testall.ts @@ -353,7 +353,7 @@ export class Testall { } private async getCoverage(store: TestResultStore): Promise { - if (store.runIds.length > 1 || store.reruns) { + if (store.runIds.length > 1 || store.reruns.length > 0) { this._logger.logWarning( 'Test run has reruns, so coverage report may not be complete' ); diff --git a/test/command/Testall.spec.ts b/test/command/Testall.spec.ts index 6871cf7..4fc4d77 100644 --- a/test/command/Testall.spec.ts +++ b/test/command/Testall.spec.ts @@ -30,6 +30,8 @@ import { testRunId, } from '../Setup'; import { Logger } from '../../src/log/Logger'; +import { ResultCollector } from '../../src/collector/ResultCollector'; +import { CoverageReport } from '../../src/model/ApexCodeCoverage'; function mockDefaultCollector(logger: Logger, connection: Connection) { const { classId, className, methodName } = defaultTestInfo; @@ -762,4 +764,80 @@ describe('TestAll', () => { expect(result.numberOfResets).to.equal(3); }); + + it('should not warn about incomplete coverage when there were no reruns', async () => { + // Regression for #85: store.reruns is an array, so the truthiness check + // `|| store.reruns` was always true and the warning fired on every run. + const logger = new CapturingLogger(); + const mockRunResult: ApexTestRunResult = createMockRunResult(); + const mockTestResults: ApexTestResult[] = [createMockTestResult()]; + const runner = new MockTestRunner({ + run: mockRunResult, + tests: mockTestResults, + numberOfResets: 0, + }); + const testMethods = mockDefaultCollector(logger, mockConnection); + const coverage: CoverageReport = { table: 'coverage table', data: [] }; + const coverageStub = sandbox + .stub(ResultCollector, 'getCoverageReport') + .resolves(coverage); + + const result = await Testall.run( + logger, + mockConnection, + '', + testMethods, + runner, + [new MockOutputGenerator()], + { codeCoverage: true } + ); + + expect(coverageStub.calledOnce).to.be.true; + expect(result.reruns.length).to.equal(0); + expect(result.runIds.length).to.equal(1); + const warned = logger.entries.some(e => + /coverage report may not be complete/.test(e) + ); + expect(warned).to.be.false; + }); + + it('should warn about incomplete coverage when tests were rerun', async () => { + const logger = new CapturingLogger(); + const mockRunResult: ApexTestRunResult = createMockRunResult({ + Status: 'Failed', + }); + const mockTestResults: ApexTestResult[] = [ + createMockTestResult({ + Outcome: 'Fail', + Message: 'UNABLE_TO_LOCK_ROW', + }), + ]; + const runner = new MockTestRunner({ + run: mockRunResult, + tests: mockTestResults, + numberOfResets: 0, + }); + const testMethods = mockDefaultCollector(logger, mockConnection); + testingServiceSyncStub.resolves({ + tests: [{ asyncApexJobId: 'retryId', outcome: 'Pass', message: null }], + }); + const coverage: CoverageReport = { table: 'coverage table', data: [] }; + sandbox.stub(ResultCollector, 'getCoverageReport').resolves(coverage); + + const result = await Testall.run( + logger, + mockConnection, + '', + testMethods, + runner, + [new MockOutputGenerator()], + { codeCoverage: true } + ); + + expect(result.reruns.length).to.equal(1); + const warned = logger.entries.some(e => + /coverage report may not be complete/.test(e) + ); + expect(warned).to.be.true; + }); });