Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jasmine 如何在所有测试完成后(而不是每个文件)生成分片量角器测试报告?_Jasmine_Protractor - Fatal编程技术网

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

Jasmine 如何在所有测试完成后(而不是每个文件)生成分片量角器测试报告?,jasmine,protractor,Jasmine,Protractor,当切分测试(也称为并行运行测试;即:shardTestFiles:true)时,量角器不会在所有测试完成时报告结果,而是在完成时报告每个文件的结果 有人对此有解决办法吗? 我尝试过使用内联钩子teardown和postest,但都没有改变这种行为(仍然是每个测试文件报告)。我也尝试过在onPrepare之外设置记者,但也没有乐趣 我希望有一个简单的解决办法。。。但我发现人们把他们的结果放在数据库里也就不足为奇了。。。这也是一个可以接受的答案 恐怕没有一个简单的答案,因为在使用任何自定义插件时,量

当切分测试(也称为并行运行测试;即:
shardTestFiles:true
)时,量角器不会在所有测试完成时报告结果,而是在完成时报告每个文件的结果

有人对此有解决办法吗?

我尝试过使用内联钩子
teardown
postest
,但都没有改变这种行为(仍然是每个测试文件报告)。我也尝试过在
onPrepare
之外设置记者,但也没有乐趣


我希望有一个简单的解决办法。。。但我发现人们把他们的结果放在数据库里也就不足为奇了。。。这也是一个可以接受的答案

恐怕没有一个简单的答案,因为在使用任何自定义插件时,量角器都会覆盖报告文件。但下面这两个对我有用。 选择最适合你的

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

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

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

我创建了一个新函数-
appendwrite()
以进行追加而不是覆盖,并修改了代码以提取此函数 查看我的github代码,它是从


函数appendwrite(路径、文件名、文本){
var fs=要求(“fs”);
var nodejs_path=require(“路径”);
require(“mkdirp”).sync(path);//确保路径存在
var filepath=nodejs_path.join(路径,文件名);
fs.appendFileSync(文件路径,文本)
返回;
}

并修改“node_modules/dragrator-jasmine2-html-reporter/index.js”中的
self.writeFile
函数以获取新函数

试一试{
追加写入(路径、文件名、文本);
//phantomWrite(路径、文件名、文本);
返回;
}catch(e){errors.push('PhantomJs trunt:'+e.message);}
试一试{
nodeWrite(路径、文件名、文本);
返回;
}catch(f){errors.push('NodeJS trunt:'+f.message);}

并注释以下在新运行时清理报告的代码,以便您不会看到任何错误清理错误-

解决方案2:通过在OnPrepare函数中配置Jasmine reporter,基于sessionID为并行实例生成单独的报告

onPrepare:function(){ 返回新承诺(功能(履行、拒绝){ browser.getCapabilities().then(函数(值){ reportName=value.get('webdriver.remote.sessionid')+'+'value.get('browserName')+''+'Math.floor(Math.random()*1E16); jasmine.getEnv().addReporter( 新Jasmine2HtmlReporter({ 保存路径:“目标/”, 截屏文件夹:“图像”, 对,, 是的, filePrefix:reportName+“.html” }) ); 实现(); }) }); },

步骤2:完成测试并关闭所有webdriver会话后,在afterLaunch()方法中合并跨并行实例生成的报告

afterLaunch:函数afterLaunch(){
var fs=需要('fs');
var输出=“”;
fs.readdirSync('target/').forEach(函数(文件){
if(!(fs.lstatSync('target/'+file.isDirectory()))
output=output+fs.readFileSync('target/'+file);
});
writeFileSync('target/ConsolidatedReport.html',output'utf8');
},

您将看到下面生成的报告,其中还包含一个合并的报告 请忽略任何打字错误和语法错误。这只是一个示例,可以定制


我在前面的

解决方案2>步骤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();
            })
        });
    },

下面是另一个解决方案,在这个基础上,使用
gravor-html-reporter-2
,它可以处理由
jasmine reporters
生成的xml文件。但是,
jasmine reporters
没有任何选项来处理由多个浏览器实例生成的报告。在未能找到理想的解决方案后,我最终在量角器配置js文件中执行了以下操作:

// 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);
}
//在package.json中添加相关包
"严格使用",;
常量HTMLReport=require('dragrator-html-reporter-2');
const jasmineReporters=require('jasmine-reporters');
恒力矩=要求的(‘力矩’);
const os=要求('os');
const xmldoc=require('xmldoc');
...
const DATE_格式='YYYYMMDD HHmmss SSS';//使用提供唯一时间戳的任何其他格式
const reportDir=path.join(_dirname,../report');
...
exports.config={
...
框架:“茉莉花”,
能力:{
browserName:“chrome”,
最大实例:2,
shardTestFiles:对,
},
启动前:异步函数(){
//清理报告目录
fs.emptyDirSync(reportDir);
}, 
onPrepare:async函数(){
const NOW=moment().format(日期格式);
const reportName='index-'+NOW;
jasmine.getEnv().addReporter(新的jasmineReporters.JUnitXmlReporter({
是的,
保存路径:reportDir,
filePrefix:reportName,
}));
},
onComplete:异步函数(){
//关闭浏览器的每个实例后执行某些操作
},
启动后:异步功能(exitCo
// 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);
}