Skip to content

Commit

Permalink
feat: add TAP reporter for Apex test results (#91)
Browse files Browse the repository at this point in the history
* feat: add TAP reporter for Apex test results

* chore: added tests

* feat: trap parsing errors for TAP test format
  • Loading branch information
rcoringrato-sfdc authored and sfsholden committed Nov 20, 2020
1 parent 9c6f293 commit 5b7ecae
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
5 changes: 4 additions & 1 deletion packages/plugin-apex/messages/run.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,8 @@
"runTestReportCommandErr": "Run 'sfdx force:apex:test:report -i %s -u %s' to retrieve test results",
"classSuiteTestErr": "Specify either classnames, suitenames, or tests",
"syncClassErr": "Synchronous test runs can include test methods from only one Apex class. Omit the --synchronous flag or include tests from only one class",
"testLevelErr": "When specifying classnames, suitenames, or tests, indicate RunSpecifiedTests as the testlevel"
"testLevelErr": "When specifying classnames, suitenames, or tests, indicate RunSpecifiedTests as the testlevel",
"testResultProcessErr": "Encountered an error when processing test results\n%s",
"apexTestReportFormatHint":
"Run \"sfdx force:apex:test:report %s --resultformat <format>\" to retrieve test results in a different format."
}
27 changes: 26 additions & 1 deletion packages/plugin-apex/src/commands/force/apex/test/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { TestService } from '@salesforce/apex-node';
import { TapReporter, TestService } from '@salesforce/apex-node';
import {
AsyncTestConfiguration,
AsyncTestArrayConfiguration,
Expand Down Expand Up @@ -190,6 +190,10 @@ export default class Run extends SfdxCommand {
this.ux.log(this.formatHuman(result, this.flags.detailedcoverage));
}

if (this.flags.resultformat === 'tap') {
this.formatTap(result);
}

if (!this.flags.resultformat) {
const id = result.summary.testRunId;
const username = result.summary.username;
Expand Down Expand Up @@ -447,4 +451,25 @@ export default class Run extends SfdxCommand {
}
return processedLines;
}

private formatTap(result: TestResult): void {
try {
const reporter = new TapReporter();
const hint = this.formatReportHint(result);
this.ux.log(reporter.format(result, [hint]));
} catch (err) {
this.ux.logJson(result);
const msg = messages.getMessage('testResultProcessErr', [err]);
this.ux.error(msg);
}
}

private formatReportHint(result: TestResult): string {
let reportArgs = `-i ${result.summary.testRunId}`;
if (this.flags.targetusername) {
reportArgs += ` -u ${this.flags.targetusername}`;
}
const hint = messages.getMessage('apexTestReportFormatHint', [reportArgs]);
return hint;
}
}
74 changes: 74 additions & 0 deletions packages/plugin-apex/test/commands/force/apex/test/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,55 @@ describe('force:apex:test:run', () => {
expect(result).to.not.contain('Apex Code Coverage by Class');
});

test
.withOrg({ username: TEST_USERNAME }, true)
.loadConfig({
root: __dirname
})
.stub(process, 'cwd', () => projectPath)
.stub(TestService.prototype, 'runTestAsynchronous', () => testRunSimple)
.stdout()
.command([
'force:apex:test:run',
'--tests',
'MyApexTests',
'--resultformat',
'tap'
])
.it('should return a success tap format message with async run', ctx => {
const result = ctx.stdout;
expect(result).to.not.be.empty;
expect(result).to.contain('1..1');
expect(result).to.contain('ok 1 MyApexTests.testConfig');
expect(result).to.contain('# Run "sfdx force:apex:test:report');
expect(result).to.not.contain('Apex Code Coverage by Class');
});

test
.withOrg({ username: TEST_USERNAME }, true)
.loadConfig({
root: __dirname
})
.stub(process, 'cwd', () => projectPath)
.stub(TestService.prototype, 'runTestAsynchronous', () => ({ tests: [] }))
.stdout()
.stderr()
.command([
'force:apex:test:run',
'--tests',
'MyApexTests',
'--resultformat',
'tap'
])
.it('should handle a tap format parsing error', ctx => {
expect(ctx.stdout).to.contain('{\n "tests": []\n}\n');
expect(ctx.stderr).to.contain(
messages.getMessage('testResultProcessErr', [
"TypeError: Cannot read property 'testRunId' of undefined"
])
);
});

test
.withOrg({ username: TEST_USERNAME }, true)
.loadConfig({
Expand All @@ -89,6 +138,31 @@ describe('force:apex:test:run', () => {
expect(result).to.not.contain('Apex Code Coverage by Class');
});

test
.withOrg({ username: TEST_USERNAME }, true)
.loadConfig({
root: __dirname
})
.stub(process, 'cwd', () => projectPath)
.stub(TestService.prototype, 'runTestSynchronous', () => testRunSimple)
.stdout()
.command([
'force:apex:test:run',
'--tests',
'MyApexTests',
'--resultformat',
'tap',
'--synchronous'
])
.it('should return a success tap format message with sync run', ctx => {
const result = ctx.stdout;
expect(result).to.not.be.empty;
expect(result).to.contain('1..1');
expect(result).to.contain('ok 1 MyApexTests.testConfig');
expect(result).to.contain('# Run "sfdx force:apex:test:report');
expect(result).to.not.contain('Apex Code Coverage by Class');
});

test
.withOrg({ username: TEST_USERNAME }, true)
.loadConfig({
Expand Down

0 comments on commit 5b7ecae

Please sign in to comment.