Skip to content

Commit 04df5ab

Browse files
committed
feat: add concise flag to apex run test and apex get test
1 parent 1d0563b commit 04df5ab

File tree

13 files changed

+187
-21
lines changed

13 files changed

+187
-21
lines changed

command-snapshot.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"output-dir",
3131
"result-format",
3232
"target-org",
33-
"test-run-id"
33+
"test-run-id",
34+
"concise"
3435
],
3536
"plugin": "@salesforce/plugin-apex"
3637
},
@@ -82,7 +83,8 @@
8283
"target-org",
8384
"test-level",
8485
"tests",
85-
"wait"
86+
"wait",
87+
"concise"
8688
],
8789
"plugin": "@salesforce/plugin-apex"
8890
},

messages/gettest.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ ID of the test run.
3232

3333
Directory in which to store test result files.
3434

35+
# flags.concise.summary
36+
37+
Only display failed test results for human-readable output.
38+
3539
# apexLibErr
3640

3741
Unknown error in Apex Library: %s

messages/runtest.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ Runs test methods from a single Apex class synchronously; if not specified, test
9696

9797
Display detailed code coverage per test.
9898

99+
# flags.concise.summary
100+
101+
Only display failed test results for human-readable output.
102+
99103
# runTestReportCommand
100104

101105
Run "%s apex get test -i %s -o %s" to retrieve test results

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"bugs": "https://github.com/forcedotcom/cli/issues",
77
"dependencies": {
88
"@oclif/core": "^4",
9-
"@salesforce/apex-node": "^6.1.2",
10-
"@salesforce/core": "^7.4.1",
9+
"@salesforce/apex-node": "^6.2.0",
10+
"@salesforce/core": "^7.5.0",
1111
"@salesforce/kit": "^3.1.6",
1212
"@salesforce/sf-plugins-core": "^11.1.0",
1313
"ansis": "^3.2.0"

src/commands/apex/get/test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ export default class Test extends SfCommand<RunResult> {
4848
summary: messages.getMessage('flags.output-dir.summary'),
4949
}),
5050
'result-format': resultFormatFlag,
51+
concise: Flags.boolean({
52+
summary: messages.getMessage('flags.concise.summary'),
53+
}),
5154
};
5255

5356
public async run(): Promise<RunResult> {
@@ -65,6 +68,7 @@ export default class Test extends SfCommand<RunResult> {
6568
'result-format': flags['result-format'],
6669
json: flags.json,
6770
'code-coverage': flags['code-coverage'],
71+
concise: flags['concise'],
6872
});
6973
}
7074
}

src/commands/apex/run/test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ export default class Test extends SfCommand<RunCommandResult> {
9494
summary: messages.getMessage('flags.detailed-coverage.summary'),
9595
dependsOn: ['code-coverage'],
9696
}),
97+
concise: Flags.boolean({
98+
summary: messages.getMessage('flags.concise.summary'),
99+
}),
97100
};
98101

99102
protected cancellationTokenSource = new CancellationTokenSource();

src/reporters/testReporter.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class TestReporter {
4545
synchronous?: boolean;
4646
json?: boolean;
4747
'code-coverage'?: boolean;
48+
concise: boolean;
4849
}
4950
): Promise<RunResult> {
5051
if (options['output-dir']) {
@@ -55,6 +56,7 @@ export class TestReporter {
5556
options['output-dir'],
5657
options['result-format'] as ResultFormat | undefined,
5758
Boolean(options['detailed-coverage']),
59+
options['concise'],
5860
options.synchronous
5961
);
6062

@@ -69,7 +71,7 @@ export class TestReporter {
6971
}
7072
switch (options['result-format']) {
7173
case 'human':
72-
this.logHuman(result, options['detailed-coverage'] as boolean, options['output-dir']);
74+
this.logHuman(result, options['detailed-coverage'] as boolean, options['concise'], options['output-dir']);
7375
break;
7476
case 'tap':
7577
this.logTap(result);
@@ -87,7 +89,7 @@ export class TestReporter {
8789
}
8890
break;
8991
default:
90-
this.logHuman(result, options['detailed-coverage'] as boolean, options['output-dir']);
92+
this.logHuman(result, options['detailed-coverage'] as boolean, options['concise'], options['output-dir']);
9193
}
9294
} catch (e) {
9395
this.ux.styledJSON(result);
@@ -114,6 +116,7 @@ export class TestReporter {
114116
outputDir: string,
115117
resultFormat: ResultFormat | undefined,
116118
detailedCoverage: boolean,
119+
concise: boolean,
117120
synchronous = false
118121
): OutputDirConfig {
119122
const outputDirConfig: OutputDirConfig = {
@@ -162,7 +165,7 @@ export class TestReporter {
162165
case ResultFormat.human:
163166
outputDirConfig.fileInfos?.push({
164167
filename: 'test-result.txt',
165-
content: new HumanReporter().format(result, detailedCoverage),
168+
content: new HumanReporter().format(result, detailedCoverage, concise),
166169
});
167170
break;
168171
default:
@@ -182,12 +185,12 @@ export class TestReporter {
182185
}
183186
}
184187

185-
private logHuman(result: TestResult, detailedCoverage: boolean, outputDir?: string): void {
188+
private logHuman(result: TestResult, detailedCoverage: boolean, concise: boolean, outputDir?: string): void {
186189
if (outputDir) {
187190
this.ux.log(messages.getMessage('outputDirHint', [outputDir]));
188191
}
189192
const humanReporter = new HumanReporter();
190-
const output = humanReporter.format(result, detailedCoverage);
193+
const output = humanReporter.format(result, detailedCoverage, concise);
191194
this.ux.log(output);
192195
}
193196

test/commands/apex/get/test.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@ import { Config } from '@oclif/core';
1212
import { expect } from 'chai';
1313
import { TestService } from '@salesforce/apex-node';
1414
import Test from '../../../../src/commands/apex/get/test.js';
15-
import { runWithFailures, testRunSimple, testRunSimpleResult, testRunWithFailuresResult } from '../../../testData.js';
15+
import {
16+
runWithCoverage,
17+
runWithFailureAndSuccess,
18+
runWithFailures,
19+
testRunSimple,
20+
testRunSimpleResult,
21+
testRunWithFailuresResult,
22+
} from '../../../testData.js';
1623

1724
let logStub: sinon.SinonStub;
1825
let styledJsonStub: sinon.SinonStub;
@@ -106,6 +113,16 @@ describe('apex:test:report', () => {
106113
).run();
107114
expect(logStub.firstCall.args[0]).to.contain('Test result files written to myDirectory');
108115
});
116+
117+
it('should only display failed test with human format with concise flag', async () => {
118+
sandbox.stub(TestService.prototype, 'reportAsyncResults').resolves(runWithFailureAndSuccess);
119+
await new Test(['--test-run-id', '707xxxxxxxxxxxx', '--result-format', 'human', '--concise'], config).run();
120+
expect(logStub.firstCall.args[0]).to.contain('Test Summary');
121+
expect(logStub.firstCall.args[0]).to.contain('Test Results');
122+
expect(logStub.firstCall.args[0]).to.contain('MyFailingTest');
123+
expect(logStub.firstCall.args[0]).to.not.contain('MyPassingTest');
124+
expect(logStub.firstCall.args[0]).to.not.contain('Apex Code Coverage by Class');
125+
});
109126
});
110127

111128
describe('test success', () => {
@@ -172,5 +189,16 @@ describe('apex:test:report', () => {
172189
).run();
173190
expect(logStub.firstCall.args[0]).to.contain('Test result files written to myDirectory');
174191
});
192+
193+
it('should only display summary with human format and code coverage and concise parameters', async () => {
194+
sandbox.stub(TestService.prototype, 'reportAsyncResults').resolves(runWithCoverage);
195+
await new Test(
196+
['--test-run-id', '707xxxxxxxxxxxx', '--result-format', 'human', '--code-coverage', '--concise'],
197+
config
198+
).run();
199+
expect(logStub.firstCall.args[0]).to.contain('Test Summary');
200+
expect(logStub.firstCall.args[0]).to.not.contain('Test Results');
201+
expect(logStub.firstCall.args[0]).to.not.contain('Apex Code Coverage by Class');
202+
});
175203
});
176204
});

test/commands/apex/run/test.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { TestService } from '@salesforce/apex-node';
1414
import Test from '../../../../src/commands/apex/run/test.js';
1515
import {
1616
runWithCoverage,
17+
runWithFailureAndSuccess,
1718
runWithFailures,
1819
testRunSimple,
1920
testRunSimpleResult,
@@ -115,6 +116,19 @@ describe('apex:test:run', () => {
115116
expect(logStub.firstCall.args[0]).to.not.contain('Apex Code Coverage by Class');
116117
});
117118

119+
it('should only display failed test with human format with concise flag', async () => {
120+
sandbox.stub(TestService.prototype, 'runTestSynchronous').resolves(runWithFailureAndSuccess);
121+
await new Test(
122+
['--tests', 'MyApexTests', '--result-format', 'human', '--synchronous', '--concise'],
123+
config
124+
).run();
125+
expect(logStub.firstCall.args[0]).to.contain('Test Summary');
126+
expect(logStub.firstCall.args[0]).to.contain('Test Results');
127+
expect(logStub.firstCall.args[0]).to.contain('MyFailingTest');
128+
expect(logStub.firstCall.args[0]).to.not.contain('MyPassingTest');
129+
expect(logStub.firstCall.args[0]).to.not.contain('Apex Code Coverage by Class');
130+
});
131+
118132
it('will build the sync correct payload', async () => {
119133
const buildPayloadSpy = sandbox.spy(TestService.prototype, 'buildSyncPayload');
120134
const runTestSynchronousSpy = sandbox.stub(TestService.prototype, 'runTestSynchronous').resolves(runWithFailures);
@@ -457,6 +471,17 @@ describe('apex:test:run', () => {
457471
],
458472
});
459473
});
474+
475+
it('should only display summary with human format and code coverage and concise parameters', async () => {
476+
sandbox.stub(TestService.prototype, 'runTestSynchronous').resolves(runWithCoverage);
477+
await new Test(
478+
['--tests', 'MyApexTests', '--result-format', 'human', '--synchronous', '--code-coverage', '--concise'],
479+
config
480+
).run();
481+
expect(logStub.firstCall.args[0]).to.contain('Test Summary');
482+
expect(logStub.firstCall.args[0]).to.not.contain('Test Results');
483+
expect(logStub.firstCall.args[0]).to.not.contain('Apex Code Coverage by Class');
484+
});
460485
});
461486

462487
describe('validateFlags', () => {

test/testData.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,68 @@ export const failureResult = {
375375
],
376376
};
377377

378+
export const runWithFailureAndSuccess: TestResult = {
379+
summary: {
380+
failRate: '50%',
381+
testsRan: 2,
382+
orgId: '00D4xx00000FH4IEAW',
383+
outcome: 'Failed',
384+
passing: 1,
385+
failing: 1,
386+
skipped: 0,
387+
passRate: '50%',
388+
skipRate: '0%',
389+
testStartTime: '2020-08-25T00:48:02.000+0000',
390+
testExecutionTimeInMs: 53,
391+
commandTimeInMs: 60,
392+
testTotalTimeInMs: 53,
393+
hostname: 'https://na139.salesforce.com',
394+
testRunId: '707xx0000AUS2gH',
395+
userId: '005xx000000uEgSAAU',
396+
username: '[email protected]',
397+
},
398+
tests: [
399+
{
400+
id: '07Mxx00000ErgiHUAR',
401+
queueItemId: '709xx000001IlUMQA0',
402+
stackTrace: 'Error running test',
403+
message: null,
404+
asyncApexJobId: '707xx0000AUS2gHQQT',
405+
methodName: 'failingTestConfig',
406+
outcome: ApexTestResultOutcome.Fail,
407+
apexLogId: null,
408+
apexClass: {
409+
id: '01pxx00000NWwb3AAD',
410+
name: 'MyFailingTest',
411+
namespacePrefix: '',
412+
fullName: 'MyFailingTest',
413+
},
414+
runTime: 53,
415+
testTimestamp: '2020-08-25T00:48:02.000+0000',
416+
fullName: 'MyFailingTest.testConfig',
417+
},
418+
{
419+
id: '07Mxx00000ErgiHUAR',
420+
queueItemId: '709xx000001IlUMQA0',
421+
stackTrace: '',
422+
message: '',
423+
asyncApexJobId: '707xx0000AUS2gHQQT',
424+
methodName: 'passingTestConfig',
425+
outcome: ApexTestResultOutcome.Pass,
426+
apexLogId: null,
427+
apexClass: {
428+
id: '01pxx00000NWwb3AAD',
429+
name: 'MyPassingTest',
430+
namespacePrefix: '',
431+
fullName: 'MyPassingTest',
432+
},
433+
runTime: 53,
434+
testTimestamp: '2020-08-25T00:48:02.000+0000',
435+
fullName: 'MyPassingTest.testConfig',
436+
},
437+
],
438+
};
439+
378440
export const jsonResult: RunResult = {
379441
summary: {
380442
commandTime: '60 ms',

0 commit comments

Comments
 (0)