如何在javascript/node中动态生成测试用例?
nose测试框架(用于python)支持(文档中的以下内容导致了五个不同的测试用例): 我如何使用诸如mocha或qunit之类的javascript框架实现这个结果?(目前,我并不依附于任何特定的框架。)如何在javascript/node中动态生成测试用例?,javascript,node.js,testing,Javascript,Node.js,Testing,nose测试框架(用于python)支持(文档中的以下内容导致了五个不同的测试用例): 我如何使用诸如mocha或qunit之类的javascript框架实现这个结果?(目前,我并不依附于任何特定的框架。) 我的用例是编写一个测试运行程序来监视外部服务器上的几个项目。我将提供一个资源URL列表。每个测试都尝试轮询该资源,并根据找到的内容返回成功或失败。我有一个用python构建的原型(使用nose),但如果可以的话,我想在node.js中实现。最终,这将包含在CI设置中。是的,您可以使用动态创建
我的用例是编写一个测试运行程序来监视外部服务器上的几个项目。我将提供一个资源URL列表。每个测试都尝试轮询该资源,并根据找到的内容返回成功或失败。我有一个用python构建的原型(使用nose),但如果可以的话,我想在node.js中实现。最终,这将包含在CI设置中。是的,您可以使用动态创建测试套件,其中包含案例。我已经在全球范围内安装了摩卡
npm安装-g mocha
,我使用
使用Mocha1.21.4,您可以按照以下方式在运行时创建套件/测试
require('chai').should()
Mocha = require 'mocha'
Test = Mocha.Test
Suite = Mocha.Suite
mocha = new Mocha
suite = Suite.create mocha.suite, 'I am a dynamic suite'
suite.addTest new Test 'I am a dynamic test', ->
true.should.equal true
mocha.run () ->
console.log("done")
有关更多详细信息,请参见。值得注意的是,除了上述公认的答案之外。我在下面为后代复制了它
var assert = require('assert');
function add() {
return Array.prototype.slice.call(arguments).reduce(function(prev, curr) {
return prev + curr;
}, 0);
}
describe('add()', function() {
var tests = [
{args: [1, 2], expected: 3},
{args: [1, 2, 3], expected: 6},
{args: [1, 2, 3, 4], expected: 10}
];
tests.forEach(function(test) {
it('correctly adds ' + test.args.length + ' args', function() {
var res = add.apply(null, test.args);
assert.equal(res, test.expected);
});
});
});
如果要使用异步获取的数据动态创建
It()
测试,可以(ab)使用带有占位符It()
测试的before()
挂钩,以确保摩卡等待before()
运行。为方便起见,以下是来自的示例:
before(function () {
console.log('Let the abuse begin...');
return promiseFn().
then(function (testSuite) {
describe('here are some dynamic It() tests', function () {
testSuite.specs.forEach(function (spec) {
it(spec.description, function () {
var actualResult = runMyTest(spec);
assert.equal(actualResult, spec.expectedResult);
});
});
});
});
});
it('This is a required placeholder to allow before() to work', function () {
console.log('Mocha should not require this hack IMHO');
});
是的!来自中国的绝妙建议 下面是我使用节点的readline模块生成动态测试的示例:
const Mocha = require('mocha');
var Test = Mocha.Test;
var Suite = Mocha.Suite;
var mocha = new Mocha();
var suite = Suite.create(mocha.suite, 'My test suite with dynamic test cases');
lineReader
.on('line', function (line) {
suite.addTest(new Test(line, function () {
return true;
}));
})
.on('close', function () {
mocha.run();
});
我喜欢@rob3c的答案,但试图简化一下:
describe("Master test suite", function () {
before(async function () {
const rows = await mySQLQuery();
describe(`Testing ${rows.length} rows`, function () {
rows.forEach(function (row, index) {
it(`Test row ${index}`, async function() {
console.log("your row assertions go here")
});
});
});
});
it("stub", async function(){}) // this is important!
});
您可以通过在异步方法返回响应后手动更新tests属性来完成此操作:
describe(`sometest`, function() {
let results = null
before(async () => {
results = await someAsyncMethod();
results.forEach((result, index) => {
// to hold on to the new dynamic tests
const newTest = it(result.name || `test ${index}`, () => {
// do something here in test
});
// update the test objects before the main tests run
this.tests.push(newTest);
});
});
it(`sometest`, () => {
expect(results.length).toBeGreaterThan(2);
});
});
这不使用动态描述等,只是在主测试运行之前更新当前描述块 节点是否与
node.js
中的节点相同?也许您应该标记它,因为在浏览器中,javascript
将被解释为javascript的意思。干得好,这对我来说很有用。一个简单的问题是,您可能不需要使用aysnc。您可能只需要使用['n1','fr','de'].forEach()。如果您的测试是同步的,它们将按顺序运行,并且不会比其他测试慢。如果您的测试是异步的,那么它们将异步运行,但是forEach循环将保持循环,尽管这两种方式都不重要,async.each或[]。forEach应该大致相同。除非我错过了什么,而且它()不知怎么被阻塞了?@Alex Mills你说得对。我更新了代码并删除了async.NB!这只适用于同步动态创建的测试用例。在一般情况下,Mocha不支持这一点。@polkovnikov.ph您是对的,这个被接受的答案只能同步工作,这实际上并没有回答OP关于从服务器请求生成它们的问题(在nodejs中总是异步的)。但是,您可以使用下面我的答案中的hack动态地异步生成测试:@rob3c我已经看到了您的答案,但是它比我准备在项目中放置一个库要复杂一些。我刚刚切换到node tap
,它可以在开箱即用的情况下正常工作。我尝试了所有方法来实现这一点,包括尝试使用几乎没有文档的摩卡TDD框架。上面的方法是有效的,但我只想补充一点,外部的“descripe”实际上只是一个占位符。重要的是内部试块。一旦构建了动态测试,您将需要返回一个新的承诺,并使用一个新的“then”方法钩住该承诺,该方法将创建一个“after”块。因此,有两个承诺。@rob3c如果在()之后添加before
块,那么您会注意到,它不会等待before()
完成。before()
中的循环肯定会创建所有这些descripe()
块,但不会等待它们完成。有没有办法做到这一点?@Harrybefore()
调用在调用任何声明的after()
调用之前完成。然而,在其回调中调用的任何承诺到那时都可能尚未完成,这正是异步javascript的本质。看起来您的问题实际上是关于javascript承诺如何工作和协调的更一般的问题,而不是像这个问题中所问的那样如何动态生成mocha测试。在这里进一步讨论javascript的一般特性可能不太合适,但是如果您在搜索中没有找到满意的答案,我建议您创建一个新问题。我正试图在cypress中使用这个问题-您有没有想过为什么加载我的期望文件并运行It()会不起作用动态测试?@rex我以前没有使用过cypress.io,但FAQ说它是在mocha之上构建的,在浏览器中运行javascript。这个黑客可以在浏览器中使用普通的mocha.js,所以我不知道cypress如何包装它有什么不同。也许这最好作为一个单独的问题来问,因为这个问题是关于直接使用mocha的?这只适用于同步数据。这非常棒,因为当模拟带有“useNock”标志的请求时,它与节点tdd配合得很好
describe("Master test suite", function () {
before(async function () {
const rows = await mySQLQuery();
describe(`Testing ${rows.length} rows`, function () {
rows.forEach(function (row, index) {
it(`Test row ${index}`, async function() {
console.log("your row assertions go here")
});
});
});
});
it("stub", async function(){}) // this is important!
});
describe(`sometest`, function() {
let results = null
before(async () => {
results = await someAsyncMethod();
results.forEach((result, index) => {
// to hold on to the new dynamic tests
const newTest = it(result.name || `test ${index}`, () => {
// do something here in test
});
// update the test objects before the main tests run
this.tests.push(newTest);
});
});
it(`sometest`, () => {
expect(results.length).toBeGreaterThan(2);
});
});