我刚刚开始学习nightwatchjs来测试我的webapp。我需要分别在其他所有内容之前和之后调用“setup”和“teardown”脚本。这些脚本在数据库中创建必要的条件,以便运行测试(创建测试许可证,用户等),然后将其删除。我的应用中有一个API调用触发了这些调用。
在globals.js中,您可以设置应在其他所有内容之前和之后执行的before
和after
方法,以及之前应执行的beforeEach
和afterEach
在每个测试套件之后,如果我没有弄错的话。似乎beforeEach
和afterEach
方法接受browser
对象和done
回调作为参数。但是,before
和after
方法仅获得done
回调。
在特定的测试套件中,可以添加相同的四种方法,但在这种情况下,before
和after
分别在所有内容和所有内容之后运行,beforeEach
并且afterEach
在套件中的每个单独测试之前和之后运行。
理想情况下,我会在全局setup
和teardown
方法中调用我的before
和after
脚本,但这些脚本不会获得夜间守望(浏览器)的实例,所以我不知道我该怎么做。
我可以在我的全局beforeEach
方法中启动'setup'调用。这对我来说并不理想,但它仍然可以工作,它只是一个多余的(在每个测试套件之前调用它,而不是在所有测试套件之前调用它)。
但是,当我尝试从全局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?
谢谢!任何帮助表示赞赏!
答案 0 :(得分:0)
虽然我还没有完全回答我自己的问题,但我想出了另一种方法来在全局before
和after
挂钩中调用我的设置和拆卸脚本。
为此,我安装了节点libarary child_process
(通过键入npm install child_process
),这允许我在命令行上执行命令。
在我的globals.js
中,我要求顶部的图书馆:
const { exec } = require('child_process');
在我的before
和after
个钩子中,我正在使用它:
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();
});
希望这有助于某人。