Jasmine/Selenium 获取正在运行的当前测试的文件名和路径

Posted

技术标签:

【中文标题】Jasmine/Selenium 获取正在运行的当前测试的文件名和路径【英文标题】:Jasmine/Selenium get file name and path of current test being run 【发布时间】:2021-10-07 19:43:07 【问题描述】:

我正在使用 jenkins 并混合使用 jasmine、selenium 和报告门户来运行我的网站的自动化测试,以确保它按预期运行。

在我的 .env 文件中,我可以设置要测试的套件,因此可以是所有测试或只是特定部分。

当我运行所有测试时,它会像这样查找文件:

all: buildTestPaths('uiTests/**/*.js'),

buildTestPaths 函数:

const buildTestPaths = (subdirectoryMask) => [
    `tests/scenarios/$testPath/$subdirectoryMask`,
];

我的 protractor.conf.js 文件是这样设置的:

/* eslint-disable no-undef */
const ReportportalAgent = require('agent-js-jasmine');
const  SpecReporter  = require('jasmine-spec-reporter');
const suiteSettings = require('./suiteSettings');
const settings = require('./settings');
const logger = require('./tests/helpers/logger');


const nodeReduceCount = 5;
let isBrowserOpen = false;

exports.config = 
    framework: 'jasmine',
    seleniumAddress: settings.seleniumHubHost,
    capabilities: 
        'shardTestFiles': true,
        'maxInstances': Math.max(settings.countOfStreams - nodeReduceCount, 1),
        'browserName': settings.browser,
        'loggingPrefs': 
            performance: 'INFO',
        ,
        'moz:firefoxOptions': getFirefoxOptions(),
        'goog:chromeOptions': getChromeOptions(),
    ,
    suites: [
        suiteSettings.suite,
    ],
    jasmineNodeOpts: 
        defaultTimeoutInterval: settings.jasmineTimeout,
        isVerbose: false,
        includeStackTrace: true,
        realtimeFailure: false,
    ,
    onPrepare: async () => 
        const jasmineEnv = jasmine.getEnv();
        const capabilities = await browser.getCapabilities();
        global.consoleReporter = [];

        console.log(capabilities);

        if (!settings.useReportPortal) 
            registerReporter(jasmineEnv);
         else 
            registerConsoleReporter(jasmineEnv);
        

        jasmineEnv.beforeEach(async () => 
            await console.log(jasmine.getEnv().currentSpec.description);

            jasmine.DEFAULT_TIMEOUT_INTERVAL = settings.jasmineTimeout;

            if (isBrowserOpen) 
                browser.restart();
            

            await browser.driver.manage().window().setSize(settings.viewPort.width, settings.viewPort.height);

            isBrowserOpen = true;

            await logger.logMessage(`Opening Link $settings.newPlanUrl()`);

            if (suiteSettings.currentSuite === 'criticalTests') 
                process.env.RUN_WITH_SERVICE_WORKER = true;
             else 
                process.env.RUN_WITH_SERVICE_WORKER = false;
            

            await browser.waitForAngularEnabled(false);
            await browser.get(settings.newPlanUrl());
        );
    ,
;

function registerReporter(jasmineEnv) 
    jasmineEnv.addReporter(new SpecReporter(
        spec: 
            displayStacktrace: true,
        ,
    ));

    const config = 
        id: browser.params.id,
        ...settings.reportPortal,
    ;
    const agent = new ReportportalAgent(config);
    const reporter = agent.getJasmineReporter();

    jasmineEnv.afterAll(async (done) => 
        await agent.getPromiseFinishAllItems(agent.tempLaunchId);

        done();
    );

    global.reporter = reporter;
    jasmineEnv.addReporter(reporter);

    return agent;


function registerConsoleReporter(jasmineEnv) 
    jasmineEnv.afterEach(async () => 
        await browser.takeScreenshot().then((png) => 
            const testSuite = settings.currentSuite;
            const date = new Date();
            const currentDay = `(Time-$date.getHours()-$date.getMinutes()-$date.getSeconds())`;
            logger.writeScreenShot(png, `screenshots/$currentDay_$testSuite.png`);
        );
    );
    jasmineEnv.afterAll(async () => 
        await console.log('\n---------------------------------');
        await console.log('Test Results');
        await global.consoleReporter.forEach((testResult) => 
            console.log(testResult);
        );
        await console.log('---------------------------------');
    );


function getFirefoxOptions() 
    const options = ;

    if (settings.headless) 
        options.args = ['--headless'];
    

    return options;


function getChromeOptions() 
    const options = 
        args: [
            '--disable-gpu',
            '--no-sandbox',
            '--disable-extensions',
            '--disable-dev-shm-usage',
            '--disable-infobars',
        ],
    ;

    if (settings.headless) 
        options.args.push('--headless');

        options.perfLoggingPrefs = 
            enableNetwork: true,
        ;
    

    return options;

我要做的是记录当前正在运行的测试的规格,即当我运行“全部”时的文件名和测试路径,但是我真的不知道该怎么做这。有什么我可以放进去的:

     jasmineEnv.beforeEach(async () => 

函数,以便记录当前正在运行的测试的这些规范?

TIA 寻求帮助

编辑:

所以我注意到在运行我的测试时它有时会记录测试路径,我无法弄清楚它来自哪里。我发现它来自我的节点模块中的一个文件,在量角器中称为 taskLogger.js

"use strict";
Object.defineProperty(exports, "__esModule",  value: true );
const os = require("os");
const logger_1 = require("./logger");
let logger = new logger_1.Logger('testLogger');
class TaskLogger 
    /**
     * Log output such that metadata are appended.
     * Calling log(data) will not flush to console until you call flush()
     *
     * @constructor
     * @param object task Task that is being reported.
     * @param number pid PID of process running the task.
     */
    constructor(task, pid) 
        this.task = task;
        this.pid = pid;
        this.buffer = '';
        this.insertTag = true;
        this.logHeader_();
    
    /**
     * Log the header for the current task including information such as
     * PID, browser name/version, task Id, specs being run.
     *
     * @private
     */
    logHeader_() 
        let output = 'PID: ' + this.pid + os.EOL;
        if (this.task.specs.length === 1) 
            output += 'Specs: ' + this.task.specs.toString() + os.EOL + os.EOL;
        
        this.log(output);
    
    /**
     * Prints the contents of the buffer without clearing it.
     */
    peek() 
        if (this.buffer) 
            // Flush buffer if nonempty
            logger.info(os.EOL + '------------------------------------' + os.EOL);
            logger.info(this.buffer);
            logger.info(os.EOL);
        
    
    /**
     * Flushes the buffer to stdout.
     */
    flush() 
        if (this.buffer) 
            this.peek();
            this.buffer = '';
        
    
    /**
     * Log the data in the argument such that metadata are appended.
     * The data will be saved to a buffer until flush() is called.
     *
     * @param string data
     */
    log(data) 
        let tag = '[';
        let capabilities = this.task.capabilities;
        tag += (capabilities.logName) ? capabilities.logName :
            (capabilities.browserName) ? capabilities.browserName : '';
        tag += (capabilities.version) ? (' ' + capabilities.version) : '';
        tag += (capabilities.platform) ? (' ' + capabilities.platform) : '';
        tag += (capabilities.logName && capabilities.count < 2) ? '' : ' #' + this.task.taskId;
        tag += '] ';
        data = data.toString();
        for (let i = 0; i < data.length; i++) 
            if (this.insertTag) 
                this.insertTag = false;
                // This ensures that the '\x1B[0m' appears before the tag, so that
                // data remains correct when color is not processed.
                // See https://github.com/angular/protractor/pull/1216
                if (data[i] === '\x1B' && data.substring(i, i + 4) === '\x1B[0m') 
                    this.buffer += ('\x1B[0m' + tag);
                    i += 3;
                    continue;
                
                this.buffer += tag;
            
            if (data[i] === '\n') 
                this.insertTag = true;
            
            this.buffer += data[i];
        
    

exports.TaskLogger = TaskLogger;

它有一个附带的 d.ts 文件:

export declare class TaskLogger 
    private task;
    private pid;
    private buffer;
    private insertTag;
    /**
     * Log output such that metadata are appended.
     * Calling log(data) will not flush to console until you call flush()
     *
     * @constructor
     * @param object task Task that is being reported.
     * @param number pid PID of process running the task.
     */
    constructor(task: any, pid: number);
    /**
     * Log the header for the current task including information such as
     * PID, browser name/version, task Id, specs being run.
     *
     * @private
     */
    private logHeader_();
    /**
     * Prints the contents of the buffer without clearing it.
     */
    peek(): void;
    /**
     * Flushes the buffer to stdout.
     */
    flush(): void;
    /**
     * Log the data in the argument such that metadata are appended.
     * The data will be saved to a buffer until flush() is called.
     *
     * @param string data
     */
    log(data: string): void;

所以我最感兴趣的是:

输出 += '规格:' + this.task.specs.toString() + os.EOL + os.EOL;

有没有办法在我的 protractor.conf.js 文件中的 jasmineEnv.beforeEach 函数中使用它?

【问题讨论】:

【参考方案1】:

更新

事实证明,之前提出的方法行不通。但我找到了一个更漂亮的解决方案

只有这两行到你的 onPrepare

let config = await browser.getProcessedConfig()
        console.log(config.specs)

注意,onPrepare 必须是异步的才能在其中使用await

您可能还需要过滤规格数组,因为 jasmine 还注册了一些它运行的内部文件

【讨论】:

谢谢,现在对它有了更好的理解,但是我还是有点困惑。对于suiteStarted,它只是控制台记录自定义报告的存储目录和文件名,而不是测试。正如你所说,我在 onPrepare 中注册了报告,但是当它记录事情时,它们会显示为“未定义”。你有什么建议吗? 天哪,是的,你是对的。这种方法行不通。我正在更新答案

以上是关于Jasmine/Selenium 获取正在运行的当前测试的文件名和路径的主要内容,如果未能解决你的问题,请参考以下文章

MS ACCESS - 如何在更改事件中获取未绑定组合框的当前列值

如何在我的 DataGrid 中获取所选单元格的当前列(C# WPF 应用程序)

pandas使用to_datetime函数将字符串时间数据列转化为时间对象数据列通过DatetimeProperties对象获取日期对象的当年第几个月信息(month)

我们如何让 NSTimer 在 iOS 中为我​​的音频播放器在后台运行

JavaScript jQuery TOOLS事件中的当前项

css实现的当鼠标悬浮弹出说明层效果