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; + }); });