Eu tenho um código em que certos testes sempre falham no ambiente de IC. Gostaria de desativá-los com base em uma condição do ambiente.
Como pular programaticamente um teste no mocha durante a execução do tempo de execução?
Eu tenho um código em que certos testes sempre falham no ambiente de IC. Gostaria de desativá-los com base em uma condição do ambiente.
Como pular programaticamente um teste no mocha durante a execução do tempo de execução?
Respostas:
Você pode pular os testes colocando um x na frente do bloco de descrição ou bloco ou colocando um .skip
depois dele.
xit('should work', function (done) {});
describe.skip('features', function() {});
Você também pode executar um único teste colocando um .only
no teste. por exemplo
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
Somente o bloco do recurso 2 seria executado nesse caso.
Não parece haver uma maneira de pular programaticamente os testes, mas você pode apenas fazer algum tipo de verificação em uma beforeEach
instrução e executar o teste apenas se o sinalizador estiver definido.
beforeEach(function(){
if (wrongEnvironment){
runTest = false
}
}
describe('feature', function(){
if(runTest){
it('should work', function(){
// Test would not run or show up if runTest was false,
}
}
}
beforeEach
chamada é executada, o Mocha registra a função anônima (o "gancho") para uso futuro ; quando a describe
chamada é executada, o Mocha executa imediatamente a função anônima passada a ele. Assim, quando o tempo if (runTest)
for executado, o beforeEach
gancho não terá funcionado.
Existe uma maneira não documentada de ignorar programaticamente os testes:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
corrida:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
Isso é discutido em https://github.com/mochajs/mocha/issues/1901 .
describe
como ignorado (ou seja, todos os testes no describe
são ignorados).
Esta resposta funciona para o ES6 .
Ao invés de:
describe('your describe block', () => {
Você quer:
(condition ? describe : describe.skip)('your describe block', () => {
Isso ignora condicionalmente todos os testes no bloco de descrição SE a condição for falsa.
Ou, em vez de:
it('your it block', () => {
Você quer:
(condition ? it : it.skip)('your it block', () => {
Isso ignora condicionalmente um teste se a condição for falsa.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
então você pode usá-lo: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
Eu uso o tempo de execução pulando do Mocha para o mesmo cenário que você está descrevendo. É a pasta de cópia dos documentos :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Como você pode ver, pula o teste com base no ambiente. Minha própria condição é if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- edit: works: D
describe.skip
ouit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
ouit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Mais informações em https://mochajs.org/#inclusive-tests
Depende de como você deseja pular programaticamente o teste. Se as condições para ignorar puderem ser determinadas antes da execução de qualquer código de teste, você poderá chamar it
ou it.skip
conforme necessário, com base em uma condição. Por exemplo, isso ignorará alguns testes se a variável de ambiente ONE
estiver configurada com qualquer valor:
var conditions = {
"condition one": process.env["ONE"] !== undefined
// There could be more conditions in this table...
};
describe("conditions that can be determined ahead of time", function () {
function skip_if(condition, name, callback) {
var fn = conditions[condition] ? it.skip: it;
fn(name, callback);
};
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Se as condições que você deseja verificar puderem ser determinadas apenas no momento do teste, é um pouco mais complicado. Se você não deseja acessar nada que não seja estritamente parte da API de teste, faça o seguinte:
describe("conditions that can be determined at test time", function () {
var conditions = {};
function skip_if(condition, name, callback) {
if (callback.length) {
it(name, function (done) {
if (conditions[condition])
done();
else
callback(done);
});
}
else {
it(name, function () {
if (conditions[condition])
return;
callback();
});
}
};
before(function () {
conditions["condition one"] = true;
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Enquanto meu primeiro exemplo foi marcar os testes como ignorados formalmente (também conhecido como "pendente"), o método que acabei de mostrar evita realizar o teste real, mas os testes não serão marcados como ignorados formalmente. Eles serão marcados como aprovados. Se você deseja que eles sejam ignorados, não conheço nenhuma maneira de acessar partes que não estão falando adequadamente da API de teste:
describe("conditions that can be determined at test time", function () {
var condition_to_test = {}; // A map from condition names to tests.
function skip_if(condition, name, callback) {
var test = it(name, callback);
if (!condition_to_test[condition])
condition_to_test[condition] = [];
condition_to_test[condition].push(test);
};
before(function () {
condition_to_test["condition one"].forEach(function (test) {
test.pending = true; // Skip the test by marking it pending!
});
});
skip_if("condition one", "test one", function () {
throw new Error("skipped!");
});
// async.
skip_if("condition one", "test one (async)", function (done) {
throw new Error("skipped!");
});
skip_if("condition two", "test two", function () {
console.log("test two!");
});
});
Não tenho certeza se isso se qualifica como "salto programático", mas para pular seletivamente alguns testes específicos para o nosso ambiente de IC, eu uso o recurso de marcação do Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). Em describe()
ou it()
mensagens, você pode adicionar uma tag como @ no-ci. Para excluir esses testes, você pode definir um específico "target ci" em sua package.json e uso --grep
e --invert
parâmetros como:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Você pode usar meu pacote mocha-assume para pular os testes programaticamente, mas apenas de fora dos testes. Você usa assim:
assuming(myAssumption).it("does someting nice", () => {});
O Mocha-assume apenas executará seu teste quando myAssumption
estiver true
, caso contrário, o ignorará (usandoit.skip
) com uma boa mensagem.
Aqui está um exemplo mais detalhado:
describe("My Unit", () => {
/* ...Tests that verify someAssuption is always true... */
describe("when [someAssumption] holds...", () => {
let someAssumption;
beforeAll(() => {
someAssumption = /* ...calculate assumption... */
});
assuming(someAssumption).it("Does something cool", () => {
/* ...test something cool... */
});
});
});
Usando dessa maneira, você pode evitar falhas em cascata. Digamos que o teste "Does something cool"
sempre falha quando alguma suposição não é válida - mas essa suposição já foi testada acima (emTests that verify someAssuption is always true"
).
Portanto, a falha no teste não fornece novas informações. De fato, é até um falso positivo: o teste não falhou porque "algo legal" não funcionou, mas porque uma pré-condição para o teste não foi atendida. com mocha-assume
você muitas vezes você pode evitar esses falsos positivos.
beforeAll
é garantido que o gancho funcione antes de todos os testes serem coletados. Na verdade, é muito provável que seja executado apenas depois, mas nesse caso o assuming(someAssumption)
já teria recebido o valor inicial (indefinido). É necessário agrupar essa parte em uma função para obter o efeito desejado.
Podemos escrever uma boa função de wrapper limpo para executar condicionalmente os testes da seguinte maneira:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Isso pode ser necessário e usado em seus testes da seguinte maneira:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Digamos que eu queira pular meu teste parametrizado se a descrição do teste contiver a string "foo", eu faria o seguinte:
// Skip parametrized test if description contains the string "foo"
(test.description.indexOf("foo") === -1 ? it : it.skip)("should test something", function (done) {
// Code here
});
// Parametrized tests
describe("testFoo", function () {
test({
description: "foo" // This will skip
});
test({
description: "bar" // This will be tested
});
});
No seu caso, acredito que se você quiser verificar variáveis de ambiente, poderá usar os NodeJS:
process.env.ENV_VARIABLE
Por exemplo (Aviso: não testei esse código!), Talvez algo como isto:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Onde você pode definir ENV_VARIABLE como o que você está usando e, usando esse valor, pule ou execute o teste. (FYI, a documentação para o process.env do NodeJS está aqui: https://nodejs.org/api/process.html#process_process_env )
Não aceitarei crédito completo pela primeira parte desta solução, encontrei e testei a resposta e ela funcionou perfeitamente para ignorar testes com base em uma condição simples por meio deste recurso: https://github.com/mochajs/mocha/issues / 591
Espero que isto ajude! :)
Isso não é realmente usar os recursos do mocha, mas sim ajustá-lo para obter o comportamento que eu queria.
Eu queria pular qualquer 'é' subsequente nos meus testes de transferidor mocha e um 'ele' falhou. Isso ocorreu porque, uma vez que uma etapa de um teste de jornada falhou, era quase certo que o restante falharia, e pode levar um longo tempo e sobrecarregar o servidor de compilação se eles estiverem usando o navegador aguarda que os elementos apareçam em uma página etc.
Ao apenas executar testes mocha padrão (não transferidor), isso pode ser alcançado com os ganchos globais beforeEach e afterEach, anexando um sinalizador 'skipSubsequent' ao pai do teste (descreva) assim:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
Ao tentar isso com transferidor e mocha, o escopo de 'this' foi alterado e o código acima não funciona. Você acaba com uma mensagem de erro como 'chamada de erro concluída ()' e o transferidor é interrompido.
Em vez disso, acabei com o código abaixo. Não é a mais bonita, mas acaba substituindo a implementação das funções de teste restantes por um this.skip (). Provavelmente, isso parará de funcionar se / quando os internos do mocha mudarem com versões posteriores.
Foi descoberto através de algumas tentativas e erros depurando e inspecionando os componentes internos do mocha ... ajuda a tornar os conjuntos de testes do navegador mais rápidos quando os testes falham.
beforeEach(function() {
var parentSpec = this.currentTest.parent;
if (!parentSpec.testcount) {
parentSpec.testCount = parentSpec.tests.length;
parentSpec.currentTestIndex = 0;
} else {
parentSpec.currentTestIndex = parentSpec.currentTestIndex + 1;
}
if (parentSpec.skipSubsequent) {
parentSpec.skipSubsequent = false;
var length = parentSpec.tests.length;
var currentIndex = parentSpec.currentTestIndex;
for (var i = currentIndex + 1; i < length; i++) {
parentSpec.tests[i].fn = function() {
this.skip();
};
}
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
});
mocha test/ --grep <pattern>
Como @danielstjules respondeu aqui há uma maneira de pular o teste. O autor deste tópico copiou a resposta da discussão do github.com mochajs, mas não há informações sobre qual versão do mocha está disponível.
Estou usando o módulo grunt-mocha-test para integrar a funcionalidade de teste do mocha no meu projeto. Passando para a última versão (por enquanto) - 0.12.7, me traz a versão 2.4.5 do mocha com a implementação deste.skip ().
Então, no meu package.json
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
E depois
npm install
E isso me deixa feliz com esse gancho:
describe('Feature', function() {
before(function () {
if (!Config.isFeaturePresent) {
console.log('Feature not configured for that env, skipping...');
this.skip();
}
});
...
it('should return correct response on AB', function (done) {
if (!Config.isABPresent) {
return this.skip();
}
...
Por favor não. Um teste que não funcione consistentemente em ambientes deve ser reconhecido como tal pela sua infraestrutura de construção. E pode ser muito desorientador quando as compilações de IC têm um número diferente de testes executado que o local.
Também estraga a repetibilidade. Se testes diferentes forem executados no servidor e no local, eu posso ter testes falhando no dev e passando no CI ou vice-versa. Não há função forçante e não tenho como corrigir rápida e precisamente uma compilação com falha.
Se você precisar desativar os testes entre ambientes, em vez de executar condicionalmente, marque seus testes e use um filtro para eliminar testes que não funcionam em determinados destinos de construção. Dessa forma, todo mundo sabe o que está acontecendo e tempera suas expectativas. Ele também permite que todos saibam que há inconsistência na estrutura de teste, e alguém pode ter uma solução que os faça funcionar corretamente novamente. Se você silenciar o teste, eles talvez nem saibam que há um problema.
this.skip()
em mochajs.org/#inclusive-tests e na resposta de @ zatziky abaixo. O restante das respostas são obsoletas para o Mocha v3 + #