在测试执行之前从模块加载数据
load data from module before test executes
(我最近问了这个问题并接受了答案,但这仍然不是我需要的。)我真的需要从模块加载的数据创建动态测试。数组中的每个项都将有自己的describe
语句和某些量角器操作。我之前的帖子有一个答案,说要使用it
语句,但我不能这样做,因为有太多的事情要做
我的主要问题是数据没有及时加载到describe
。我有另一个建议,使用VCR.js或类似的东西,但我认为这些不会起作用,因为我使用的是一个模块。有没有一种方法可以将数据保存到一个单独的文件中并加载?这是个好办法吗?
var data = require('get-data'); //custom module here
describe('Test', function() {
var itemsArr;
beforeAll(function(done) {
data.get(function(err, result) {
itemsArr = result; //load data from module
done();
});
})
//error: Cannot read property 'forEach' of undefined
describe('check each item', function() {
itemsArr.forEach(function(item) {
checkItem(item);
});
});
function checkItem (item) {
var itemName = item.name;
describe(itemName, function() {
console.log('describe');
it('should work', function() {
console.log('it');
expect(true).toBeTruthy();
});
});
}
});
更新:
我用了尤金的答案,想出了这个。我无法按照自己的意愿测试每项研究,因为it
语句不会触发。这个问题可以解决吗??
describe('check each item', function () {
it('should load data', function (done) {
browser.wait(itemsPromise, 5000);
itemsPromise.then(function(itemsArr) {
expect(itemsArr).toBeTruthy();
studyArr = itemsArr.filter(function (item) {
return item.enabled && _.contains(item.tags, 'study');
});
studyCount = studyArr.length;
expect(studies.count()).toEqual(studyCount);
checkItems(studyArr);
done();
});
});
function checkItems (itemsArr) {
itemsArr.forEach(function (item) {
describe(item.id, function () {
console.log('checkItems', item.id);
// doesn't work
it('should work', function (done) {
expect(false).toBeTruthy();
done();
});
});
});
}
});
您正在尝试做Jasmine不允许的事情:在测试套件启动后生成测试。请参阅关于Jasmine问题的评论:
Jasmine不支持在套件开始运行后添加规范。通常,当我需要这样做的时候,我能够提前知道选项列表,并通过循环进行it调用。[…]
("添加规格"==="添加测试")
关键是可以动态生成测试,但只能在测试套件开始执行测试之前。由此得出的一个推论是,测试生成不能是异步的。
您的第二次尝试不起作用,因为它试图将测试添加到已经运行的套件中。
您的第一次尝试更接近您的需求,但也不起作用,因为describe
会立即调用其回调,因此在describe
尝试生成测试时,beforeAll
尚未运行。
解决方案
这一切都归结为在测试套件开始执行测试之前计算itemsArr
的值。
您可以创建一个.getSync
方法来同步返回结果。然后,您的代码将类似于:
var data = require('get-data'); //custom module here
var itemsArr = data.getSync();
describe('Test', function() {
describe('check each item', function() {
itemsArr.forEach(function(item) {
checkItem(item);
});
});
[...]
如果无法编写.getSync
函数,可以让一个外部进程负责生成JSON输出,然后将其反序列化为itemsArr
。您可以使用child_process
的一个...Sync
函数来执行这个外部进程。
以下是第二个选项如何工作的示例。我用以下代码创建了一个get-data.js
文件,该文件使用setTimeout
模拟异步操作:
var Promise = require("bluebird"); // Bluebird is a promise library.
var get = exports.get = function () {
return new Promise(function (resolve, reject) {
var itemsArr = [
{
name: "one",
param: "2"
},
{
name: "two",
param: "2"
}
];
setTimeout(function () {
resolve(itemsArr);
}, 1000);
});
};
// This is what we run when were are running this module as a "script" instead
// of a "module".
function main() {
get().then(function (itemsArr) {
console.log(JSON.stringify(itemsArr));
});
};
// Check whether we are a script or a module...
if (require.main === module) {
main();
}
然后,在规范文件中:
var child_process = require('child_process');
var itemsArr = JSON.parse(child_process.execFileSync(
"/usr/bin/node", ["get-data.js"]));
describe('Test', function() {
itemsArr.forEach(function(item) {
checkItem(item);
});
function checkItem (item) {
var itemName = item.name;
describe(itemName, function() {
console.log('describe');
it('should work', function() {
console.log('it');
expect(true).toBeTruthy();
});
});
}
});
我已经使用jasmine-node
测试了上面的代码。以及以下文件结构:
.
├── data.js
├── get-data.js
└── test
└── foo.spec.js
./node_modules
有bluebird
和jasmine-node
。这就是我得到的:
$ ./node_modules/.bin/jasmine-node --verbose test
describe
describe
it
it
Test - 5 ms
one - 4 ms
should work - 4 ms
two - 1 ms
should work - 1 ms
Finished in 0.007 seconds
2 tests, 2 assertions, 0 failures, 0 skipped
尝试使用promise,比如:
var deferred = protractor.promise.defer();
var itemsPromise = deferred.promise;
beforeAll(function() {
data.get(function(err, result) {
deferred.fulfill(result);
});
})
然后:
describe('check each item', function() {
itemsPromise.then(function(itemsArr) {
itemsArr.forEach(function(item) {
checkItem(item);
});
});
});
我能想到的另一个解决方案是使用browser.wait
等待itemsArr不为空。
您的get-data
模块是否使用量角器进行一些浏览器操作?如果是这样,您将需要在controlFlow的上下文中设置/获取itemsArr。否则,它将读取get-data
模块中的所有代码,但推迟执行,而不是等到它完成后再直接转到那些期望语句。
var data = require('get-data'); //custom module here
var itemsArr;
describe('Test', function() {
beforeAll(function() {
// hook into the controlFlow and set the value of the variable
browser.controlFlow().execute(function() {
data.get(function(err, result) {
itemsArr = result; //load data from module
});
});
});
//error: Cannot read property 'forEach' of undefined
describe('check each item', function() {
// hook into the controlFlow and get the value of the variable (at that point in time)
browser.controlFlow().execute(function() {
itemsArr.forEach(function(item) {
checkItem(item);
});
});
});
function checkItem (item) {
var itemName = item.name;
describe(itemName, function() {
console.log('describe');
it('should work', function() {
console.log('it');
expect(true).toBeTruthy();
});
});
}
});
- 带有模块加载程序的Emscripten
- 使用Socket.io的异步模块加载(AMD)
- 角度模块加载错误
- NaCl中的模块加载进度事件,manifest_version=2,没有内联javascript
- 节点.js - 异步模块加载
- Angular2&SystemJS:在生成模块加载器时找不到模块
- 当作为 CommonJS 模块加载时,Angular 是否全局将自己分配给“window.angular”
- 杜兰达尔/要求:模块加载和执行
- 主干木偶:木偶.应用程序导致 Require.js 模块加载错误,“'错误:尚未为上下文加载模块名称'A
- 将库从节点模块加载到 nodeJS 中
- 道场模块加载一般
- 在JS模块加载的上下文中,什么是立即执行的工厂函数
- 如何将angularJS模块加载到应用程序中
- 角度模块加载失败
- require.js模块加载不正确
- 如何等待Angular模块加载
- SystemJS-ES6模块加载器-导入时层次结构过多
- 如何用oclazyload加载的外部模块加载Angular translate
- 运行从ecmascript 6模块加载的函数
- 了解 YUI 模块加载和附加