Estou tentando juntar todos os testes de vários arquivos em um arquivo, algo assim:
describe('Controllers', function() {
describe('messages.js', function() {
require('./controllertests/messages').test(options);
})
describe('users.js', function() {
require('./controllertests/users').test(options);
})
})
Tenho quase certeza de que essa não é a melhor maneira de participar de testes, estou tendo dificuldade em encontrar exemplos de como fazer isso: s
node.js
unit-testing
mocha
coiso
fonte
fonte
.only()
que pode ser útil ser capazdescribe.only()
de ainda executar um diretório inteiro de testes. Foi isso que me trouxe aqui.Respostas:
Se você deseja incluir vários módulos em sua
describe
hierarquia como está fazendo em sua pergunta, o que você está fazendo é basicamente isso , a menos que queira escrever um carregador de teste personalizado para o Mocha. Escrever o carregador personalizado não seria mais fácil ou tornaria seu código mais claro do que o que você já possui.Aqui está um exemplo de como eu mudaria algumas coisas. O
test
subdiretório neste exemplo é organizado como:top.js
:function importTest(name, path) { describe(name, function () { require(path); }); } var common = require("./common"); describe("top", function () { beforeEach(function () { console.log("running something before each test"); }); importTest("a", './a/a'); importTest("b", './b/b'); after(function () { console.log("after all tests"); }); });
A
importTest
função é apenas mostrar como seria possível lidar com a repetição de importação de vários módulos sem ter que redigitardescribe(... require...
tudo a cada vez. Ocommon
módulo destina-se a conter o que você precisa usar em vários módulos do conjunto de testes. Na verdade, não estou usando,top
mas pode ser usado lá, se necessário.Notarei aqui que o
beforeEach
executará seu código antes de cada teste registrado comit
se eles aparecem dentro dodescribe
emtop
ou em algum dos módulos importados . Com--recursive
, obeforeEach
código teria que ser copiado em cada módulo ou talvez você tivesse umbeforeEach
gancho em cada módulo que chama uma função importada de um módulo comum.Além disso, o
after
gancho será executado após todos os testes do conjunto. Isso não pode ser replicado com--recursive
. Se você usar--recursive
e adicionar o código deafter
a cada módulo, ele será executado uma vez por módulo em vez de apenas uma vez para todo o teste.Fazer com que todos os testes apareçam sob um único
top
título não pode ser replicado usando--recursive
. Com--recursive
cada arquivo poderia ter,describe("top"
mas isso criaria um novotop
título para cada arquivo.common.js
:var chai = require("chai"); var options = { foo: "foo" }; exports.options = options; exports.chai = chai; exports.assert = chai.assert;
Usar um módulo denominado
common
como este é algo que fiz em alguns dos meus conjuntos de teste para evitar ter derequire
um monte de coisas repetidamente e manter variáveis globais somente leitura ou funções que não mantêm o estado. Eu prefiro não poluir oglobal
objeto como na resposta de thgaskell porque este objeto é realmente global e acessível mesmo em bibliotecas de terceiros que seu código pode estar carregando. Isso não é algo que considero aceitável em meu código.a/a.js
:var common = require("../common"); var options = common.options; var assert = common.assert; it("blah a", function () { console.log(options.foo); assert.isTrue(false); });
b/b.js
:it("blah b", function () {});
fonte
global
escopo, eu uso isso para as bibliotecas de asserção para manter os arquivos de teste mais limpos. Não é como se você estivesse substituindoglobal.process
. As variáveis locais serão substituídas, aglobal
menos que outras bibliotecas estejam chamando explicitamente, oglobal.XYZ
que é improvável. Ele dura apenas durante os testes. Não me machucou ainda, masimportTest
e chamar,require('path')()
por exemplo?importTest
função é apenas uma função de conveniência. O importante que ele faz é agrupar arequire
chamada em umdescribe
bloco. É importante que arequire
chamada seja agrupada,describe
caso contrário, os módulos não serão isolados em seu próprio bloco e qualquer gancho definido pelo arquivo importado será definido no bloco errado. SeimportTest
fosse substituído por uma chamada direta pararequire
sem empacotamentodescribe
, os módulosa/a
eb/b
compartilhariam os ganchos. Por exemplo, umbeforeEach
gancho colocado emb/b
também seria executado antes de cada teste ema/a
.Embora isso possa não estar diretamente relacionado à pergunta, a resposta que eu estava procurando era:
Irá executar todos os testes nos subdiretórios da pasta "test". Arrumado. Evita ter que manter uma lista de testes que desejo carregar e, na verdade, apenas sempre executar tudo.
fonte
describe
blocos,describe
blocos que abrangem arquivos--recursive
não farão isso. Visto que não resolve o problema do OP, não o chamaria de "melhor".describe
blocosdescribe
bloco. Veja a pergunta. Odescribe
bloco "Controladores" deve abranger os testes de./controllertests/messages.js
e./controllertests/users.js
. Bater--recursive
em uma invocação Mocha não cria umdescribe("Controllers"
bloqueio mágico .describe
blocos magicamente - o que eu realmente aprendi a fazer com o próprio Dumbledore.Não há nada que impeça você de executar vários arquivos de teste. Geralmente, cada teste não deve ser dependente dos resultados de outro teste, portanto, compartilhar variáveis não é algo que você gostaria de fazer.
Aqui está um exemplo de como você pode organizar seus arquivos de teste.
Em seguida, dentro do seu
mocha.opts
arquivo, certifique-se de definir a--recursive
opção.mocha.opts
Se houver são módulos comuns que você deseja incluir em todos os arquivos, você pode acrescentar que para o
common.js
arquivo. Os arquivos na raiz dotest
diretório serão executados antes dos arquivos em diretórios aninhados.common.js
global.chai = require('chai'); global.assert = chai.assert; global.expect = chai.expect; chai.should(); chai.config.includeStack = true; process.env.NODE_ENV = 'test'; // Include common modules from your application that will be used among multiple test suites. global.myModule = require('../app/myModule');
fonte
describe('mytest', function() { /* ..... etc */ });
Sei que este é um post antigo, mas queria entrar na conversa com o que tem sido uma boa solução para mim, muito semelhante ao método proposto pelo OP.
O projeto no qual estou trabalhando está bem testado e os testes continuam crescendo. Acabei usando
require
porque é síncrono e, portanto, torna um pouco mais fácil compor seus testes sem muitas mudanças na arquitetura:// inside test/index.js describe('V1 ROUTES', () => { require('./controllers/claims.test'); require('./controllers/claimDocuments.test'); require('./controllers/claimPhotos.test'); require('./controllers/inspections.test'); require('./controllers/inspectionPhotos.test'); require('./controllers/versions.test'); require('./services/login.v1.test'); }); describe('V2 ROUTES', () => { require('./services/login.v2.test'); require('./services/dec-image.v2.test'); }); describe('V3 ROUTES', () => { require('./services/login.v3.test'); require('./services/getInspectionPhotosv3.test'); require('./services/getPolicyInfo.v3.test'); }); describe('ACTIONS', () => { require('./actions/notifications.test'); });
fonte
Eu tive um problema semelhante onde eu tinha um monte de testes para classes na mesma categoria e queria agrupá-los para tornar mais fácil visualizá-los em um IDE. Todos os meus testes e código já estavam usando módulos ES6 - eu não queria reescrever todos eles para usar
require
como vi em outros exemplos.Eu resolvi isso tendo meu "agrupamento"
describe
exportado e, em seguida, importando-o para meus arquivos de teste e adicionando-os programaticamente ao arquivo importadodescribe
. Acabei criando um método auxiliar para abstrair todo o encanamento.Em someCategory.spec.js
const someCategory= describe("someCategory", () => {}); // Use this just like a regular `describe` to create a child of this scope in another file export default function describeMember(skillName, testFn) { return describe(skillName, function configureContext() { // Make context a child of `someCategory` context function Context() {} Context.prototype = someCategory.ctx; this.ctx = new Context(); // Re-parent the suite created by `describe` above (defaults to root scope of file it was created in) this.parent.suites.pop(); someCategory.addSuite(this); // Invoke the fn now that we've properly set up the parent/context testFn.call(this); }); }
Em testes individuais:
import { default as describeCategoryMember } from './someCategory.spec'; describeCategoryMember('something', () => { describe('somethingElse', () => { ... }); it('a test', () => { ... }); })
fonte
describe( 'Running automation test, Please wait for all test to complete!'.red, function () { var run = require( './Test.js' ); for ( var i = 0; i < 2; i++ ) { run.badLogin(); run.loginLimited(); run.acceptJob(); run.drivingToJob(); run.arrivedAtJob(); run.towingJob(); run.arrivedDestination(); run.jobComplete(); run.restrictionLicensePlate(); run.newNodeMainMenu(); run.newNodeMainMenuToDrafts(); run.draftDelete(); run.resetAllData(); run.companyVehicle(); run.actionsScreenClockInOut(); run.mainMenuLogout(); run.loginAdmin(); run.actionsScreenLogout(); } } );
fonte
./Test.js
? Quem sabe? Só para constar, sou atualmente o que mais responde na tag mocha . Eu conheço Mocha por dentro e por fora, mas não consigo entender essa resposta.