当进行分片测试(也就是并行运行测试;即:shardTestFiles: true
)时,而不是在所有测试完成后报告结果时,Protractor会报告每个文件的结果完成后。
有没有人有解决方法?
我尝试使用带有teardown
和postTest
的内联plugin,但都没有改变此行为(仍然是每个测试文件报告)。我也试过在onPrepare
,as suggested here之外设置记者,但也没有喜悦。
我希望能有一个简单的解决方案......但是我发现人们把结果扔到数据库中也不会让我感到惊讶......这也是一个可以接受的答案。
答案 0 :(得分:4)
我担心没有一个简单的答案,因为Protractor在使用任何自定义插件时会覆盖报告文件。但是下面两个对我有用。 选择最适合你的方式
1)修改Jasmine2HtmlReporter的'index.js'以附加文件而不是PhantomJs覆盖其使用
2)通过从onPrepare()函数配置Jasmine2HTML报告器生成唯一的HTML报告,并在以后合并所有报告
解决方案1:Jasmine2HtmlReporter的当前代码库 - index.js
使用两个函数 - phantomWrite()
& nodeWrite()
写入数据。请参阅here
我创建了一个新函数 - appendwrite()
来追加而不是覆盖并修改了代码以获取此函数
查看我从protractor-jasmine2-html-reporter
function appendwrite(path, filename, text){
var fs = require("fs");
var nodejs_path = require("path");
require("mkdirp").sync(path); // make sure the path exists
var filepath = nodejs_path.join(path, filename);
fs.appendFileSync(filepath,text)
return;
}
修改'node_modules / protractor-jasmine2-html-reporter / index.js'中的self.writeFile
函数以获取新函数
try {
appendwrite(path, filename, text);
//phantomWrite(path, filename, text);
return;
} catch (e) { errors.push(' PhantomJs attempt: ' + e.message); }
try {
nodeWrite(path, filename, text);
return;
} catch (f) { errors.push(' NodeJS attempt: ' + f.message); }
并评论以下代码清除新运行的报告,以便您不会看到任何错误清除错误 - CleanUpCode
rmdir(self.savePath);
解决方案2:通过在OnPrepare函数中配置Jasmine报告器,根据并行实例的sessionID生成单独的报告
onPrepare: function() {
return new Promise(function (fulfill, reject) {
browser.getCapabilities().then(function (value) {
reportName = value.get('webdriver.remote.sessionid') + '_' + value.get('browserName') + '_' + Math.floor(Math.random()*1E16);
jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
savePath: 'target/',
screenshotsFolder: 'images',
consolidate: true,
consolidateAll: true,
filePrefix: reportName + ".html"
})
);
fulfill();
})
});
},
步骤2:完成完整测试并关闭所有webdriver会话后,整合afterLaunch()方法中跨并行实例生成的报告
afterLaunch: function afterLaunch() {
var fs = require('fs');
var output = '';
fs.readdirSync('target/').forEach(function(file){
if(!(fs.lstatSync('target/' + file).isDirectory()))
output = output + fs.readFileSync('target/' + file);
});
fs.writeFileSync('target/ConsolidatedReport.html', output, 'utf8');
},
您还会看到使用一个ConsolidatedReport生成类似下面的报告 PS:请忽略任何拼写错误和语法错误。这只是作为一个例子,可以定制
得到了答案答案 1 :(得分:0)
Solution2->步骤1.从最新版本的html-reporter,filePrefix应该是fileNamePrefix,所以函数应该是:
onPrepare: function() {
return new Promise(function (fulfill, reject) {
browser.getCapabilities().then(function (value) {
reportName = value.get('webdriver.remote.sessionid') + '_' + value.get('browserName') + '_' + Math.floor(Math.random()*1E16);
jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
savePath: 'target/',
screenshotsFolder: 'images',
consolidate: true,
consolidateAll: true,
fileNamePrefix: reportName + ".html"
})
);
fulfill();
})
});
},
答案 2 :(得分:0)
这是另一种解决方案,它基于protractor-html-reporter-2
构建在jasmine-reporters
生成的xml文件上,并使用jasmine-reporters
。但是// add relevant packages in package.json
'use strict';
const HTMLReport = require('protractor-html-reporter-2');
const jasmineReporters = require('jasmine-reporters');
const moment = require('moment');
const os = require('os');
const xmldoc = require('xmldoc');
...
const DATE_FORMAT = 'YYYYMMDD-HHmmss-SSS'; // use any other format that gives unique timestamp
const reportDir = path.join(__dirname, '../report');
...
exports.config = {
...
framework: 'jasmine',
capabilities: {
browserName: 'chrome',
maxInstances: 2,
shardTestFiles: true,
},
beforeLaunch: async function () {
// clean up report directory
fs.emptyDirSync(reportDir);
},
onPrepare: async function () {
const NOW = moment().format(DATE_FORMAT);
const reportName = 'index-' + NOW;
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: reportDir,
filePrefix: reportName,
}));
},
onComplete: async function () {
// do something after each instance of browser is closed
},
afterLaunch: async function (exitCode) {
// do something after ALL instances of browser are closed
await consolidateJasmineXmlReports();
},
...
},
...
async function consolidateJasmineXmlReports() {
// there may be better ways to write xml out but this works for me
const files = fs.readdirSync(reportDir).filter(fn => fn.endsWith('.xml'));
let disabledSum = 0;
let errorsSum = 0;
let failuresSum = 0;
let testsSum = 0;
let timeSum = 0;
const allTestSuiteNodes = [];
for (const file of files) {
const pathToXml = reportDir + path.sep + file;
console.log('Reading xml report file: ' + pathToXml);
const xml = fs.readFileSync(pathToXml);
const xmlDoc = new xmldoc.XmlDocument(xml);
const disabled = parseInt(xmlDoc.attr.disabled);
const errors = parseInt(xmlDoc.attr.errors);
const failures = parseInt(xmlDoc.attr.failures);
const tests = parseInt(xmlDoc.attr.tests);
const time = parseFloat(xmlDoc.attr.time);
disabledSum += disabled;
errorsSum += errors;
failuresSum += failures;
testsSum += tests;
timeSum += time;
const testSuiteNodes = xmlDoc.childrenNamed('testsuite');
allTestSuiteNodes.push(testSuiteNodes);
}
let startXml = `<?xml version="1.0" encoding="UTF-8" ?>`;
startXml += `<testsuites disabled="` + disabledSum + `" errors="` + errorsSum + `" failures="` + failuresSum + `" tests="` + testsSum + `" time="` + timeSum + `">`;
const endXml = '</testsuites>';
allTestSuiteNodes.push(endXml);
const finalXml = startXml + allTestSuiteNodes.join('\n');
fs.writeFileSync(reportDir + path.sep + 'consolidated.xml', finalXml, 'utf8');
const testConfig = {
outputPath: reportDir,
outputFilename: 'consolidated',
...
};
new HTMLReport().from(reportDir + path.sep + 'consolidated.xml', testConfig);
}
没有任何选择来处理由多个浏览器实例生成的报告。在找不到理想的解决方案后,我最终在量角器config js文件中执行了以下操作:
afterLaunch
逻辑是
afterLaunch
中的一个有效xml。Open Blue Ocean Jenkins
中生成html。我们使用Jenkins进行测试,并且以上创建的报告在Jenkins中显示良好,并且还可以在div
插件显示的报告中准确显示。
注意:我已经使用shardTestFiles进行了测试,而不是使用multiCapabilities进行了测试,但是我认为它也应该可以使用。
另请参阅: