0

我刚刚开始学习 nightwatchjs 来测试我的 web 应用程序。我需要分别在其他所有操作之前和之后调用“设置”和“拆卸”脚本。这些脚本在数据库中创建测试运行的必要条件(创建测试许可证、用户等),然后将其删除。我的应用程序中有一个触发这些的 API 调用。

在 globals.js 中,如果我没记错的话,您可以设置应该在其他所有操作之前和之后执行的方法,以及before应该在每个测试套件之前和之后执行的和。似乎and方法接受对象和回调作为参数。然而, and方法只获得回调。afterbeforeEachafterEachbeforeEachafterEachbrowserdonebeforeafterdone

在特定的测试套件中,可以添加相同的四个方法,但在这种情况下,beforeandafter分别在所有内容之前beforeEachafterEach之后运行,and 在套件中的每个单独测试之前和之后运行。

理想情况下,我会在全局和方法中调用我的setupteardown脚本,但那些没有获得夜间值守(浏览器)的实例,所以我不知道该怎么做。beforeafter

beforeEach在我的全局方法中,我可以很好地触发“设置”调用。这对我来说并不理想,但它仍然可以工作,但这只是多余的(在每个测试套件之前调用它,而不是在所有东西之前调用它)。

但是,当我尝试从全局方法调用teardown脚本时遇到问题。afterEach当我运行测试时,输出在最后挂起,直到我点击CTRL+C.

这是我的 nightwatch.conf.js:

const seleniumServer = require("selenium-server");
const chromedriver = require("chromedriver");


// we use a nightwatch.conf.js file so we can include comments and helper functions
module.exports = {
    "src_folders": [
        "tests",
    ],
    "page_objects_path": './pages',
    "globals_path": "./globals.js",
    "output_folder": "./reports", // reports (test outcome) output by nightwatch
    "custom_commands_path" : "./commands",
    "selenium": {
        "start_process": true, // tells nightwatch to start/stop the selenium process
        "server_path": seleniumServer.path,
        "host": "127.0.0.1",
        "port": 4444, // standard selenium port
        "cli_args": {
            "webdriver.chrome.driver" : chromedriver.path
        }
    },
    "test_settings": {
        "default": {
            "silent": true,
            "launchUrl": 'http://local.mytestwebsite.com',
            "screenshots": {
                "enabled": true, // if you want to keep screenshots
                "path": "./screenshots/" // save screenshots here
            },
            "globals": {
                "waitForConditionTimeout": 5000 // sometimes internet is slow so wait.
            },
            "desiredCapabilities": { // use Chrome as the default browser for tests
                "browserName": "chrome",
                "chromeOptions": {
                    "args": [
                        "window-size=1366,768",
                        "--incognito"
                    ]
                }
            }
        }
    }
}

这是我的 globals.js:

var chromedriver = require('chromedriver');
module.exports = {


    beforeEach: function(browser, done) {
        console.log('Executing the global `beforeEach`');

        browser.url('http://www.vulfpeck.com');
        browser.expect.element('body').to.be.present;
        browser.end();

        // getting the session info
        browser.status(function(result) {
            console.log("Session Info: ", result.value);
            done();
        });
    },


    afterEach: function(browser, done){
        console.log('Executing the global `afterEach`');

        browser.url('http://www.vulfpeck.com');
        browser.expect.element('body').to.be.present;
        browser.end();

        // getting the session info
        browser.status(function(result) {
            console.log("Session Info: ", result.value);
            done();
        });
    },


    before: function(done) {
        console.log('Executing the global `before`');
        console.log('starting the chromedriver');
        chromedriver.start();
        done();
    },


    after: function(done) {
        console.log('Executing the global `after`');
        console.log('stoppin the chromedriver');
        chromedriver.stop();
        done();
    }
};

这是我的测试套件:

module.exports = {
    'Test 1': function(browser){
        browser.url('http://www.google.com');
        browser.expect.element('body').to.be.present;
        browser.end();
    },
    'Test 2': function(browser){
        browser.url('http://www.vulfpeck.com');
        browser.expect.element('body').to.be.present;
        browser.end();
    },
    before: function(browser, done){
        console.log('test before');
        done();
    },
    beforeEach: function(browser, done){
        console.log('test beforeEach');
        done();
    },
    after: function(browser, done){
        console.log('test after');
        done();
    },
    afterEach: function(browser, done){
        console.log('test afterEach');
        done();
    }
};

这是输出。

$ nightwatch
Executing the global `before`
starting the chromedriver
Starting selenium server... started - PID:  11772

[Login] Test Suite
======================
Executing the global `beforeEach`
 √ Expected element <body> to be present - element was present in 31ms
Session Info:  { ready: true,
  message: 'Server is running',
  build:
   { revision: '63f7b50',
     time: '2018-02-07T22:42:28.403Z',
     version: '3.9.1' },
  os: { arch: 'amd64', name: 'Windows 10', version: '10.0' },
  java: { version: '9' } }
test before

Running:  Test 1
test beforeEach
 √ Expected element <body> to be present - element was present in 30ms
test afterEach

OK. 1 assertions passed. (3.56s)

Running:  Test 2
test beforeEach
 √ Expected element <body> to be present - element was present in 20ms
test afterEach

OK. 1 assertions passed. (2.503s)
test after
Executing the global `afterEach`
Session Info:  { ready: true,
  message: 'Server is running',
  build:
   { revision: '63f7b50',
     time: '2018-02-07T22:42:28.403Z',
     version: '3.9.1' },
  os: { arch: 'amd64', name: 'Windows 10', version: '10.0' },
  java: { version: '9' } }
 × Expected element <body> to be present - element was not found  - expected "present" but got: "not present"
    at Object.afterEach (C:\sites\mytestwebsite.com\selenium\globals.js:29:21)

那么,我错过了什么吗?为什么我不能在全局 afterEach 方法中点击 URL 而不会挂起?(我刚刚发现,如果我browser.end();从套件中的最后一个测试中删除 ,我的全局afterEach将正常工作。为什么会这样?)。在运行所有测试之前和之后是否有其他推荐的方法来访问 URL?

谢谢!任何帮助表示赞赏!

4

1 回答 1

0

虽然我还没有完全回答我自己的问题,但我想出了另一种方法来调用全局beforeafter挂钩中的设置和拆卸脚本。

为此,我安装了节点库child_process(通过键入npm install child_process),它允许我在命令行上执行命令。

在我的globals.js中,我需要顶部的库:

const { exec } = require('child_process');

在我的beforeafter钩子中,我像这样使用它:

exec('php ../run.php api selenium setup', (err, stdout, stderr) => {
            if (err) {
                // node couldn't execute the command
                console.log("node couldn't execute the command",err);
                done();
                return;
            }

            // the *entire* stdout and stderr (buffered)
            console.log(`stdout: ${stdout}`);
            console.log(`stderr: ${stderr}`);
            done();
        });

希望这可以帮助某人。

于 2018-02-23T19:32:30.733 回答