mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
fix(cli): use path name for classname in JUnit reports instead of request URL (#8169)
* fix: 3123 CLI JUnit Report: classname Uses Request URL Instead of Request Name * fix: update classname in JUnit report to use request path instead of name * fix: update testcase classname in JUnit report to use request path instead of request name * fix: update JUnit report classname to use API paths instead of collection paths * fix: update classname in JUnit report to use backslashes for Windows compatibility * fix: update JUnit report file paths to use API paths instead of mock paths
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const xmlbuilder = require('xmlbuilder');
|
||||
const { stripExtension } = require('../utils/filesystem');
|
||||
|
||||
const makeJUnitOutput = async (results, outputPath) => {
|
||||
const output = {
|
||||
@@ -15,6 +16,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
const testCount = result.testResults ? result.testResults.length : 0;
|
||||
const postResponseTestCount = result.postResponseTestResults ? result.postResponseTestResults.length : 0;
|
||||
const totalTests = assertionTestCount + preRequestTestCount + testCount + postResponseTestCount;
|
||||
const classname = stripExtension(result.path);
|
||||
|
||||
const suite = {
|
||||
'@name': result.name,
|
||||
@@ -34,7 +36,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
const testcase = {
|
||||
'@name': `${assertion.lhsExpr} ${assertion.rhsExpr}`,
|
||||
'@status': assertion.status,
|
||||
'@classname': result.request.url,
|
||||
'@classname': classname,
|
||||
'@time': (result.runDuration / totalTests).toFixed(3)
|
||||
};
|
||||
|
||||
@@ -52,7 +54,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
const testcase = {
|
||||
'@name': test.description,
|
||||
'@status': test.status,
|
||||
'@classname': result.request.url,
|
||||
'@classname': classname,
|
||||
'@time': (result.runDuration / totalTests).toFixed(3)
|
||||
};
|
||||
|
||||
@@ -70,7 +72,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
const testcase = {
|
||||
'@name': test.description,
|
||||
'@status': test.status,
|
||||
'@classname': result.request.url,
|
||||
'@classname': classname,
|
||||
'@time': (result.runDuration / totalTests).toFixed(3)
|
||||
};
|
||||
|
||||
@@ -88,7 +90,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
const testcase = {
|
||||
'@name': test.description,
|
||||
'@status': test.status,
|
||||
'@classname': result.request.url,
|
||||
'@classname': classname,
|
||||
'@time': (result.runDuration / totalTests).toFixed(3)
|
||||
};
|
||||
|
||||
@@ -110,7 +112,7 @@ const makeJUnitOutput = async (results, outputPath) => {
|
||||
{
|
||||
'@name': 'Test suite has no errors',
|
||||
'@status': 'fail',
|
||||
'@classname': result.request.url,
|
||||
'@classname': classname,
|
||||
'@time': result.runDuration.toFixed(3),
|
||||
'error': [{ '@type': 'error', '@message': result.error }]
|
||||
}
|
||||
|
||||
@@ -103,6 +103,36 @@ describe('makeJUnitOutput', () => {
|
||||
expect(failcase.failure[0]['@type']).toBe('failure');
|
||||
});
|
||||
|
||||
it('should use the request path as the testcase classname instead of the request url', () => {
|
||||
const results = [
|
||||
{
|
||||
name: '1st API',
|
||||
path: 'f1/1st API.bru',
|
||||
test: {
|
||||
filename: 'f1/1st API.bru'
|
||||
},
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: 'https://ima.test'
|
||||
},
|
||||
testResults: [
|
||||
{
|
||||
description: 'Status is 200',
|
||||
status: 'pass'
|
||||
}
|
||||
],
|
||||
runDuration: 1.2345678
|
||||
}
|
||||
];
|
||||
|
||||
makeJUnitOutput(results, '/tmp/testfile.xml');
|
||||
|
||||
const junit = xmlbuilder.create.mock.calls[0][0];
|
||||
const testcase = junit.testsuites.testsuite[0].testcase[0];
|
||||
|
||||
expect(testcase['@classname']).toBe('f1/1st API');
|
||||
});
|
||||
|
||||
it('should handle request errors', () => {
|
||||
const results = [
|
||||
{
|
||||
|
||||
@@ -10,11 +10,7 @@ function normalizeJunitReport(xmlContent: string): string {
|
||||
// Replace hostnames with fixed value
|
||||
.replace(/hostname="[^"]*"/g, 'hostname="test-host"')
|
||||
// Replace execution times with fixed value
|
||||
.replace(/time="[^"]*"/g, 'time="0.100"')
|
||||
// Replace file paths with normalized path
|
||||
.replace(/file="[^"]*[\\/][^"]*"/g, 'file="/mock/path/to/file.bru"')
|
||||
// Replace test paths with normalized path
|
||||
.replace(/classname="[^"]*[\\/][^"]*"/g, 'classname="/test/path/collection"');
|
||||
.replace(/time="[^"]*"/g, 'time="0.100"');
|
||||
}
|
||||
|
||||
test.describe('Collection Run Report Tests', () => {
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<testsuites>
|
||||
<testsuite name="Get User Info" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Get User Info" file="api/v1/users.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Get UUID" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Get UUID" file="api/v1/posts.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="api/v1/posts" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 404"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Login Request" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Login Request" file="auth/login.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="auth/login" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="auth/login" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="auth/login" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Logout Request" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Logout Request" file="auth/logout.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="auth/logout" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 500"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="auth/logout" time="0.100"/>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
@@ -1,29 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<testsuites>
|
||||
<testsuite name="Get User Info" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Get User Info" file="api/v1/users.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="api/v1/users" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Get UUID" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Get UUID" file="api/v1/posts.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="api/v1/posts" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 404"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="api/v1/posts" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Login Request" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Login Request" file="auth/login.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="auth/login" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="auth/login" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="auth/login" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Logout Request" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Logout Request" file="auth/logout.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="auth/logout" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 500"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="auth/logout" time="0.100"/>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
@@ -1,29 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<testsuites>
|
||||
<testsuite name="Get User Info" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Get User Info" file="api\v1\users.bru" errors="0" failures="0" skipped="0" tests="4" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="api\v1\users" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api\v1\users" time="0.100"/>
|
||||
<testcase name="Response has slideshow property" status="pass" classname="api\v1\users" time="0.100"/>
|
||||
<testcase name="Slideshow has title" status="pass" classname="api\v1\users" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Get UUID" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Get UUID" file="api\v1\posts.bru" errors="0" failures="1" skipped="0" tests="5" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will fail" status="fail" classname="api\v1\posts" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 404"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="api\v1\posts" time="0.100"/>
|
||||
<testcase name="Response is an object" status="pass" classname="api\v1\posts" time="0.100"/>
|
||||
<testcase name="Response has uuid property" status="pass" classname="api\v1\posts" time="0.100"/>
|
||||
<testcase name="UUID is a string" status="pass" classname="api\v1\posts" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Login Request" file="/mock/path/to/file.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testsuite name="Login Request" file="auth\login.bru" errors="0" failures="0" skipped="0" tests="3" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="Status code is 200" status="pass" classname="auth\login" time="0.100"/>
|
||||
<testcase name="Response has json field" status="pass" classname="auth\login" time="0.100"/>
|
||||
<testcase name="Response json has username" status="pass" classname="auth\login" time="0.100"/>
|
||||
</testsuite>
|
||||
<testsuite name="Logout Request" file="/mock/path/to/file.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="/test/path/collection" time="0.100">
|
||||
<testsuite name="Logout Request" file="auth\logout.bru" errors="0" failures="1" skipped="0" tests="2" timestamp="2024-01-01T00:00:00.000" hostname="test-host" time="0.100">
|
||||
<testcase name="This test will also fail" status="fail" classname="auth\logout" time="0.100">
|
||||
<failure type="failure" message="expected 200 to equal 500"/>
|
||||
</testcase>
|
||||
<testcase name="Status code is 200" status="pass" classname="/test/path/collection" time="0.100"/>
|
||||
<testcase name="Status code is 200" status="pass" classname="auth\logout" time="0.100"/>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
Reference in New Issue
Block a user