Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for console output #90

Merged
merged 3 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ yarn add --dev jest-junit
```

## Important Notice
In an upcoming major version 5.x jest-junit will no longer function as a testResultProcessor. It will only work as a jest reporter. See the docs just below this for how to transition your project.
In an upcoming major version 7.x jest-junit will no longer function as a testResultProcessor. It will only work as a jest reporter. See the docs just below this for how to transition your project.

## Usage
In your jest config add the following entry:
Expand Down Expand Up @@ -51,22 +51,23 @@ jest --ci --testResultsProcessor="jest-junit"

## Configuration

`jest-junit` offers seven configurations based on environment variables or a `jest-junit` key defined in `package.json` or a reporter option.
`jest-junit` offers several configurations based on environment variables or a `jest-junit` key defined in `package.json` or a reporter option.
Environment variable and package.json configuration should be **strings**.
Reporter options should also be strings exception for suiteNameTemplate, classNameTemplate, titleNameTemplate that can also accept a function returning a string.

| Variable Name | Description | Default | Possible Injection Values
|--|--|--|--|
| `JEST_SUITE_NAME` | `name` attribute of `<testsuites>` | `"jest tests"` | N/A
| `JEST_JUNIT_OUTPUT` | File path to save the output. | `"./junit.xml"` | N/A
| `JEST_JUNIT_OUTPUT_DIR` | Directory to save the output. | `null` | N/A
| `JEST_JUNIT_OUTPUT_NAME` | File name for the output. | `"./junit.xml"` | N/A
| `JEST_JUNIT_SUITE_NAME` | Template string for `name` attribute of the `<testsuite>`. | `"{title}"` | `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_CLASSNAME` | Template string for the `classname` attribute of `<testcase>`. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_TITLE` | Template string for the `name` attribute of `<testcase>`. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_ANCESTOR_SEPARATOR` | Character(s) used to join the `describe` blocks. | `" "` | N/A
| `JEST_JUNIT_ADD_FILE_ATTRIBUTE` | Add file attribute to the output. This config is primarily for Circle CI. This setting provides richer details but may break on other CI platforms. | `false` | N/A
| `JEST_USE_PATH_FOR_SUITE_NAME` | **DEPRECATED. Use `suiteNameTemplate` instead.** Use file path as the `name` attribute of `<testsuite>` | `"false"` | N/A
| Environment Variable Name | Reporter Config Name| Description | Default | Possible Injection Values
|--|--|--|--|--|
| `JEST_SUITE_NAME` | `suiteName` | `name` attribute of `<testsuites>` | `"jest tests"` | N/A
| `JEST_JUNIT_OUTPUT` | `output` | File path to save the output. | `"./junit.xml"` | N/A
| `JEST_JUNIT_OUTPUT_DIR` | `outputDirectory` | Directory to save the output. | `null` | N/A
| `JEST_JUNIT_OUTPUT_NAME` | `outputName` | File name for the output. | `"./junit.xml"` | N/A
| `JEST_JUNIT_SUITE_NAME` | `suiteNameTemplate` | Template string for `name` attribute of the `<testsuite>`. | `"{title}"` | `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_CLASSNAME` | `classNameTemplate` | Template string for the `classname` attribute of `<testcase>`. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_TITLE` | `titleTemplate` | Template string for the `name` attribute of `<testcase>`. | `"{classname} {title}"` | `{classname}`, `{title}`, `{filepath}`, `{filename}`, `{displayName}`
| `JEST_JUNIT_ANCESTOR_SEPARATOR` | `ancestorSeparator` | Character(s) used to join the `describe` blocks. | `" "` | N/A
| `JEST_JUNIT_ADD_FILE_ATTRIBUTE` | `addFileAttribute` | Add file attribute to the output. This config is primarily for Circle CI. This setting provides richer details but may break on other CI platforms. | `false` | N/A
| `JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT` | `includeConsoleOutput` | Adds console output to any testSuite that generates stdout during a test run. | `false` | N/A
| `JEST_USE_PATH_FOR_SUITE_NAME` | `usePathForSuiteName` | **DEPRECATED. Use `suiteNameTemplate` instead.** Use file path as the `name` attribute of `<testsuite>` | `"false"` | N/A


You can configure these options via the command line as seen below:
Expand Down
128 changes: 128 additions & 0 deletions __mocks__/test-with-console-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"numFailedTestSuites": 0,
"numFailedTests": 0,
"numPassedTestSuites": 2,
"numPassedTests": 2,
"numPendingTestSuites": 0,
"numPendingTests": 0,
"numRuntimeErrorTestSuites": 0,
"numTodoTests": 0,
"numTotalTestSuites": 2,
"numTotalTests": 2,
"openHandles": [],
"snapshot": {
"added": 0,
"didUpdate": false,
"failure": false,
"filesAdded": 0,
"filesRemoved": 0,
"filesUnmatched": 0,
"filesUpdated": 0,
"matched": 0,
"total": 0,
"unchecked": 0,
"uncheckedKeysByFile": [],
"unmatched": 0,
"updated": 0
},
"startTime": 1552322034304,
"success": false,
"testResults": [
{
"console": [
{
"message": "I am bar",
"origin": "/path/to/my/test/__tests__/bar.test.js:5",
"type": "log"
},
{
"message": "Some output here from a lib",
"origin": "/path/to/my/test/sample.js:3",
"type": "log"
}
],
"failureMessage": null,
"numFailingTests": 0,
"numPassingTests": 1,
"numPendingTests": 0,
"numTodoTests": 0,
"perfStats": {
"end": 1552322035185,
"start": 1552322034769
},
"snapshot": {
"added": 0,
"fileDeleted": false,
"matched": 0,
"unchecked": 0,
"unmatched": 0,
"updated": 0,
"uncheckedKeys": []
},
"testFilePath": "/path/to/my/test/__tests__/bar.test.js",
"testResults": [
{
"ancestorTitles": [
"bar"
],
"duration": 5,
"failureMessages": [],
"fullName": "bar should bar",
"location": null,
"numPassingAsserts": 0,
"status": "passed",
"title": "should bar"
}
],
"sourceMaps": {},
"skipped": false,
"leaks": false
},
{
"console": [
{
"message": "I am foo",
"origin": "/path/to/my/test/__tests__/foo.test.js:3",
"type": "log"
}
],
"failureMessage": null,
"numFailingTests": 0,
"numPassingTests": 1,
"numPendingTests": 0,
"numTodoTests": 0,
"perfStats": {
"end": 1552322035238,
"start": 1552322035196
},
"snapshot": {
"added": 0,
"fileDeleted": false,
"matched": 0,
"unchecked": 0,
"unmatched": 0,
"updated": 0,
"uncheckedKeys": []
},
"testFilePath": "/path/to/my/test/__tests__/foo.test.js",
"testResults": [
{
"ancestorTitles": [
"foo"
],
"duration": 1,
"failureMessages": [],
"fullName": "foo should foo",
"location": null,
"numPassingAsserts": 0,
"status": "passed",
"title": "should foo"
}
],
"sourceMaps": {},
"skipped": false,
"leaks": false
}
],
"wasInterrupted": false
}
19 changes: 19 additions & 0 deletions __tests__/buildJsonResults.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,23 @@ describe('buildJsonResults', () => {
expect(jsonResults.testsuites[1].testsuite[1].testcase[0]._attr.file).toBe('path/to/test/__tests__/foo.test.js');
});

it('should show output of console if includeConsoleOutput is true', () => {
const reportWithConsoleOutput = require('../__mocks__/test-with-console-output.json');
const jsonResults = buildJsonResults(reportWithConsoleOutput, '/',
Object.assign({}, constants.DEFAULT_OPTIONS, {
includeConsoleOutput: "true"
}));

expect(jsonResults.testsuites[1].testsuite[1]['system-out']).toBeDefined();
});

it('should NOT show output of console if includeConsoleOutput is not set or false', () => {
const reportWithConsoleOutput = require('../__mocks__/test-with-console-output.json');
const jsonResults = buildJsonResults(reportWithConsoleOutput, '/',
Object.assign({}, constants.DEFAULT_OPTIONS, {
includeConsoleOutput: "false"
}));

expect(jsonResults.testsuites[1].testsuite[1]['system-out']).not.toBeDefined();
});
});
2 changes: 2 additions & 0 deletions constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {
JEST_JUNIT_TITLE: 'titleTemplate',
JEST_JUNIT_ANCESTOR_SEPARATOR: 'ancestorSeparator',
JEST_JUNIT_ADD_FILE_ATTRIBUTE: 'addFileAttribute',
JEST_JUNIT_INCLUDE_CONSOLE_OUTPUT: 'includeConsoleOutput',
JEST_USE_PATH_FOR_SUITE_NAME: 'usePathForSuiteName',
},
DEFAULT_OPTIONS: {
Expand All @@ -26,6 +27,7 @@ module.exports = {
ancestorSeparator: ' ',
usePathForSuiteName: 'false',
addFileAttribute: 'false',
includeConsoleOutput: 'false',
},
CLASSNAME_VAR: 'classname',
FILENAME_VAR: 'filename',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
],
"scripts": {
"test": "jest",
"pretest:ci": "npm install jest@$JEST_VERSION",
"pretest:ci": "npm uninstall jest babel-jest && npm install jest@$JEST_VERSION babel-jest@$JEST_VERSION --no-save",
"test:ci": "jest --ci"
},
"dependencies": {
Expand Down
16 changes: 15 additions & 1 deletion utils/buildJsonResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ module.exports = function (report, appDirectory, options) {
jsonResults.testsuites[0]._attr.failures += suite.numFailingTests;
jsonResults.testsuites[0]._attr.tests += suiteNumTests;

// Write stdout console output if available
if (options.includeConsoleOutput === 'true' && suite.console && suite.console.length) {
// Stringify the entire console object
// Easier this way because formatting in a readable way is tough with XML
// And this can be parsed more easily
let testSuiteConsole = {
'system-out': {
_cdata: JSON.stringify(suite.console, null, 2)
}
};

testSuite.testsuite.push(testSuiteConsole);
}

// Iterate through test cases
suite.testResults.forEach((tc) => {
const classname = tc.ancestorTitles.join(options.ancestorSeparator);
Expand Down Expand Up @@ -153,4 +167,4 @@ module.exports = function (report, appDirectory, options) {
});

return jsonResults;
};
};