在所有测试完成后(而不是每个文件),如何进行分片量角器测试报告?

时间:2016-09-14 21:23:49

标签: jasmine protractor

当进行分片测试(也就是并行运行测试;即:shardTestFiles: true)时,而不是在所有测试完成后报告结果时,Protractor会报告每个文件的结果完成后。

有没有人有解决方法?

我尝试使用带有teardownpostTest的内联plugin,但都没有改变此行为(仍然是每个测试文件报告)。我也试过在onPrepareas suggested here之外设置记者,但也没有喜悦。

我希望能有一个简单的解决方案......但是我发现人们把结果扔到数据库中也不会让我感到惊讶......这也是一个可以接受的答案。

3 个答案:

答案 0 :(得分:4)

我担心没有一个简单的答案,因为Protractor在使用任何自定义插件时会覆盖报告文件。但是下面两个对我有用。 选择最适合你的方式

1)修改Jasmine2HtmlReporter的'index.js'以附加文件而不是PhantomJs覆盖其使用

2)通过从onPrepare()函数配置Jasmine2HTML报告器生成唯一的HTML报告,并在以后合并所有报告

解决方案1:Jasmine2HtmlReporter的当前代码库 - index.js使用两个函数 - phantomWrite()& nodeWrite()写入数据。请参阅here

我创建了一个新函数 - appendwrite()来追加而不是覆盖并修改了代码以获取此函数 查看我从protractor-jasmine2-html-reporter

分叉的github代码

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:请忽略任何拼写错误和语法错误。这只是作为一个例子,可以定制

enter image description here

我之前在protractor-jasmine2-html-reporter doesn't consolidate results for all test when tests are shared using 'shardTestFiles': true in conf file

得到了答案

答案 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

逻辑是

  1. 确保所有xml文件的唯一名称。
  2. 将所有xml文件组合为afterLaunch中的一个有效xml。
  3. 使用任何使用该xml文件的软件包在Open Blue Ocean Jenkins中生成html。

我们使用Jenkins进行测试,并且以上创建的报告在Jenkins中显示良好,并且还可以在div插件显示的报告中准确显示。

注意:我已经使用shardTestFiles进行了测试,而不是使用multiCapabilities进行了测试,但是我认为它也应该可以使用。

另请参阅: