Как я могу динамически генерировать тестовые случаи в javascript/node?
Инфраструктура носового тестирования (для python) поддерживает динамическое создание тестовых случаев во время выполнения (из документации видно, что в пяти различных тестовых случаях):
def test_evens():
for i in range(0, 5):
yield check_even, i, i*3
def check_even(n, nn):
assert n % 2 == 0 or nn % 2 == 0
Как я могу достичь этого результата, используя JavaScript-фреймворки, такие как mocha или qunit? (Я не привязан к какой-либо конкретной структуре на данный момент.)
Мой пример использования - написание тестового прогона для мониторинга нескольких элементов на внешнем сервере. Я хотел бы предоставить список URL ресурсов. Каждый тест пытается опросить этот ресурс и возвращает успех или неудачу в зависимости от того, что он находит. У меня есть прототип, встроенный в python (использующий нос), но я хотел бы реализовать в node.js, если смогу. В конце концов, это будет включено в настройку CI.
5 ответов
Да, вы можете динамически создавать тестовые наборы с кейсами, используя Mocha. Я установил мокко по всему миру npm install -g mocha
и я использую должен.
var should = require('should');
var foo = 'bar';
['nl', 'fr', 'de'].forEach(function(arrElement) {
describe(arrElement + ' suite', function() {
it('This thing should behave like this', function(done) {
foo.should.be.a.String();
done();
});
it('That thing should behave like that', function(done) {
foo.should.have.length(3);
done();
});
});
});
Если вы хотите динамически создавать It()
тесты с использованием данных, полученных асинхронно, вы можете (ab) использовать before()
крюк с заполнителем It()
тест, чтобы убедиться, что мокко ждет, пока 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');
});
С Mocha 1.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")
См. https://gist.github.com/cybertk/fff8992e12a7655157ed для получения дополнительной информации.
Стоит отметить, что в дополнение к принятому ответу, приведенному выше, документы Мокко теперь включают пример того, как этого добиться. Я воспроизвел это ниже для потомков.
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);
});
});
});
Ага! Гениальный совет от Quanlong!
Вот мой пример генерации динамического теста с модулем readline Node:
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);
});
});
При этом не используются динамические описания и т. Д., Просто обновляется текущий блок описания перед запуском основных тестов!