Javascript 在测试执行之前从模块加载数据
(我最近问了,并接受了一个答案,但这仍然不是我需要的。)我真的需要从模块加载的数据创建动态测试。数组中的每个项都有自己的Javascript 在测试执行之前从模块加载数据,javascript,node.js,asynchronous,jasmine,protractor,Javascript,Node.js,Asynchronous,Jasmine,Protractor,(我最近问了,并接受了一个答案,但这仍然不是我需要的。)我真的需要从模块加载的数据创建动态测试。数组中的每个项都有自己的description语句,带有某些量角器动作。我上一篇文章的答案是使用it语句,但我不能这样做,因为事情太多了 我的主要问题是,description没有及时加载数据。我有另一个建议使用VCR.js或类似的东西,但我不认为这些会起作用,因为我使用的是一个模块。有没有一种方法可以将数据保存到单独的文件中并加载?那是个好办法吗 var data = require('get-da
description
语句,带有某些量角器动作。我上一篇文章的答案是使用it
语句,但我不能这样做,因为事情太多了
我的主要问题是,description
没有及时加载数据。我有另一个建议使用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();
});
});
});
}
});
尝试使用承诺,比如:
var deferred = protractor.promise.defer();
var itemsPromise = deferred.promise;
beforeAll(function() {
data.get(function(err, result) {
deferred.fulfill(result);
});
})
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);
});
});
[...]
然后:
describe('check each item', function() {
itemsPromise.then(function(itemsArr) {
itemsArr.forEach(function(item) {
checkItem(item);
});
});
});
我能想到的另一个解决方案是使用
浏览器。等待
直到itemsArr变为非空。您的获取数据
模块是否使用量角器执行一些浏览器操作?如果是这样,您将需要在controlFlow的上下文中设置/获取itemsArr。否则,它将读取get data
模块中的所有代码,但推迟其执行,而不是等到它完成后再继续执行那些expect语句
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();
});
});
}
});
您试图做一些Jasmine不允许的事情:在测试套件启动后生成测试。见《茉莉花》一期: Jasmine不支持在套件开始运行后添加规范。通常,当我需要这样做的时候,我能够提前知道选项列表,然后循环使用它们来进行it调用。[……] (“添加规格”==“添加测试”) 关键是,您可以动态生成测试,但只能在测试套件开始执行测试之前生成。由此产生的一个推论是,测试生成不能是异步的 您的第二次尝试不起作用,因为它正在尝试向已运行的套件添加测试 您的第一次尝试更接近您所需要的,但它也不起作用,因为
descripe
立即调用其回调,因此before
在descripe
尝试生成测试时尚未运行
解决
这一切归结为在测试套件开始执行测试之前计算itemsArr
的值
您可以创建一个同步返回结果的.getSync
方法。然后,您的代码将类似于:
var deferred = protractor.promise.defer();
var itemsPromise = deferred.promise;
beforeAll(function() {
data.get(function(err, result) {
deferred.fulfill(result);
});
})
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
。您可以使用的…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节点
测试了上面的代码。以及以下文件结构:
.
├── data.js
├── get-data.js
└── test
└── foo.spec.js
/node\u模块
中有蓝鸟
和茉莉花节点
。这就是我得到的:
$ ./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
您是否在
data.get()
callback中检查了err
?@mscdex我能够得到结果,但是没有及时加载descripe('check each item')
您是否尝试在第二个descripe或it语句中调用done?考虑到它正在等待一个异步事件,这似乎是有意义的。@swestner你是什么意思?如果我在之前调用done()
外部它是未定义的这类工作,但我仍然有相同的问题。查看我的更新帖子当我尝试此操作时,我得到“未找到规格”,并说测试已完成,然后我再次得到forEach错误感谢您的回答。我认为第二个选项对我来说更好。如果我需要将模块放在一个单独的文件中,名为.get()
内模块。导出函数,然后将该文件加载到我的规范中,会有什么不同吗?我已经开始尝试了,但我可能做得不对,或者这不是正确的方法。我看不出这是怎么回事。如果将module.exports
设置为一个函数,并且此函数依赖于从.get()
返回数据,那么您也将模块.exports
设置为异步函数,这是您最初试图避免的问题。是的,您是对的。我想我可以尝试child\u流程
,但我不太熟悉它的工作原理。看起来execSync
或spawnSync
都不错,但我不知道命令行选项如何与我的玩偶配合使用谢谢。我不确定这是否有效,但谢谢你的帮助和努力