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

后端 未结 5 1555
鱼传尺愫
鱼传尺愫 2021-01-14 20:04

Recently we have configured our e2e-tests to be on Jenkins & soon we realized that we have to use shared test files: true options as complete suite run is taking very lo

5条回答
  •  遥遥无期
    2021-01-14 20:30

    Here is another solution, building on top of this answer, using protractor-html-reporter-2 which works on the xml file produced by jasmine-reporters. But jasmine-reporters does not have any option to work with reports generated by multiple instances of browsers. After failing to find an ideal solution, I ended up doing following in the protractor config js file:

    // 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 = ``;
        startXml += ``;
        const endXml = '';
        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);
    }
    

    The logic is

    1. Ensure unique names for all xml files.
    2. Combine all the xml files to one valid xml in the afterLaunch.
    3. Use any package that uses that xml file to produce html in the afterLaunch.

    We use Jenkins to run the tests and the report created by above displays well in Jenkins and also shows up accurately on the report displayed by Open Blue Ocean Jenkins plugin.

    Note: I have tested with shardTestFiles and not with multiCapabilities but I think it should work with that as well.

    See Also:

    • Protractor config file
    • Setting up jasmine reporter

自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题