deelnemen aan tests uit meerdere bestanden met mocha.js

Ik probeer alle tests van meerdere bestanden in één bestand samen te voegen, ongeveer als volgt:

 describe('Controllers', function() {
    describe('messages.js', function() {
      require('./controllertests/messages').test(options);
    })
    describe('users.js', function() {
      require('./controllertests/users').test(options);
    })
  })

Ik ben er vrij zeker van dat dit niet de beste manier is om deel te nemen aan tests, ik heb wat problemen om voorbeelden te vinden van hoe ik dit moet doen :s


Antwoord 1, autoriteit 100%

Als u meerdere modules inwilt opnemen in uw describe-hiërarchie zoals u doet in uw vraag, is wat u doet vrijwel het, tenzij u een aangepaste testlader voor Mocha wilt schrijven. Het schrijven van de aangepaste lader zou niet eenvoudiger zijn of uw code duidelijker maken dan wat u al heeft.

Hier is een voorbeeld van hoe ik een paar dingen zou veranderen. De submap testin dit voorbeeld is georganiseerd als:

.
└── test
    ├── a
    │   └── a.js
    ├── b
    │   └── b.js
    ├── common.js
    └── top.js

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");
    });
});

De functie importTestis alleen om te laten zien hoe het mogelijk zou zijn om de herhaling van het importeren van meerdere modules af te handelen zonder de hele describe(... require...ding elke keer. De commonmodule is bedoeld om te bevatten wat je nodig hebt om te gebruiken in meerdere modules van de testsuite. Ik gebruik het niet echt in topmaar het kan daar worden gebruikt, indien nodig.

Ik zal hier opmerken dat de beforeEachzijn code zal uitvoeren vóór elke afzonderlijke test die is geregistreerd bij it, ongeacht of ze verschijnen in de describein topof ze verschijnen in een van de geïmporteerde modules. Met --recursivezou de beforeEachcode naar elke module gekopieerd moeten worden of misschien zou je een beforeEachhook hebben in elke module die roept een functie aan die is geïmporteerd uit een gemeenschappelijke module.

Ook de afterhook wordt uitgevoerd na alletests in de suite. Dit kan niet worden gerepliceerd met --recursive. Als u --recursivegebruikt en de code van afteraan elke module toevoegt, wordt deze één keer per module uitgevoerd in plaats van slechts één keer voor de geheletesten.

Als alle tests onder één top-kop worden weergegeven, kan dit niet worden gerepliceerd met --recursive. Met --recursivekan elk bestand describe("top"hebben, maar dit zou een nieuwe topkop voor elk bestand creëren.

common.js:

var chai = require("chai");
var options = {
    foo: "foo"
};
exports.options = options;
exports.chai = chai;
exports.assert = chai.assert;

Het gebruik van een modulegenaamd commonzoals deze is iets wat ik in sommige van mijn testsuites heb gedaan om te voorkomen dat ik een heleboel requirevan dingen keer op keer en om globale alleen-lezenvariabelen of functies vast te houden die de status niet behouden. Ik geef er de voorkeur aan het commonobject niet te vervuilen zoals in het antwoord van thgaskell, omdat dit object echt globaal en toegankelijk is, zelfs in bibliotheken van derden die uw code mogelijk aan het laden is. Dit vind ik niet acceptabel in mijn code.

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 () {});

Antwoord 2, autoriteit 32%

Hoewel dit misschien niet direct verband houdt met de vraag, was het antwoord dat ik zocht:

$ mocha --recursive

Zal alle tests uitvoeren in submappen van de map “test”. Netjes. Bespaart het bijhouden van een lijst met tests die ik wil laden en eigenlijk gewoon altijd alles moeten uitvoeren.


Antwoord 3, autoriteit 14%

Er is niets dat u ervan weerhoudt meerdere testbestanden uit te voeren. Over het algemeen zou elke test niet afhankelijk moeten zijn van de resultaten van een andere test, dus het delen van variabelen is niet iets wat je zou willen doen.

Hier is een voorbeeld van hoe u uw testbestanden kunt ordenen.

.
├── app.js
└── test
    ├── common.js
    ├── mocha.opts
    │
    ├── controllers
    │   ├── messages-controller.js
    │   └── users-controller.js
    │
    └── models
        ├── messages-model.js
        └── users-model.js

Zorg ervoor dat u in uw mocha.opts-bestand de optie --recursiveinstelt.

mokka.opts

--ui bdd
--recursive

Als er zijngemeenschappelijke modules die u in alle bestanden wilt opnemen, kunt u die toevoegen aan het bestand common.js. Bestanden in de hoofdmap van de test-map worden uitgevoerd vóór bestanden in geneste mappen.

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');

Antwoord 4, autoriteit 9%

Ik weet dat dit een oud bericht is, maar ik wilde inhaken op wat voor mij een goede oplossing was, die erg lijkt op de methode die door OP is voorgesteld.

Het project waar ik aan werk is goed getest en de tests blijven groeien. Ik heb uiteindelijk requiregebruikt omdat het synchroon is en het daarom een ​​beetje gemakkelijker maakt om je tests samen te stellen zonder al te veel verandering in de architectuur:

// 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');
});

Antwoord 5, autoriteit 3%

Ik had een soortgelijk probleem waarbij ik een heleboel tests had voor klassen in dezelfde categorie en ik wilde ze groeperen om ze in een IDE gemakkelijker te kunnen bekijken. Al mijn tests en code maakten al gebruik van ES6-modules – ik wilde ze niet allemaal herschrijven om requirete gebruiken, zoals ik in andere voorbeelden zag.

Ik heb het opgelost door mijn “groepering” describete exporteren, en deze vervolgens in mijn testbestanden te importeren en ze programmatisch toe te voegen aan de geïmporteerde describe. Uiteindelijk heb ik een hulpmethode ontwikkeld om al het sanitair te abstraheren.

In 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) {
  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);
  });
}

In individuele tests:

import { default as describeCategoryMember } from './someCategory.spec';
describeCategoryMember('something', () => {
    describe('somethingElse', () => {
        ...
    });
    it('a test', () => {
        ...
    });
})

Antwoord 6

probeer dit om alle bestanden die eindigen op _test.js in de map testsuit te voeren (als het niet werkt, controleer dan of je het doet in de map ./tests)

"scripts": {
  "test": "find ./tests -name '*_test.js' | xargs mocha -R spec"
},

Antwoord 7

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();
    }
} );

Other episodes