[node.js] mocha.js로 여러 파일의 테스트 결합

다음과 같이 여러 파일의 모든 테스트를 하나의 파일에 결합하려고합니다.

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

나는 이것이 테스트에 참여하는 가장 좋은 방법이 아니라고 확신합니다.이 작업을 수행하는 방법에 대한 예제를 찾는 데 어려움이 있습니다.



답변

여러 모듈을 포함 할 경우 당신의 describe당신이 당신의 질문을하고있는 같은 계층 구조를, 무슨 일을 꽤 많이 그것은 당신이 모카에 대한 사용자 정의 테스트 로더를 쓰고 싶어하지 않는 한. 커스텀 로더를 작성하는 것은 이미 가지고있는 것보다 코드를 더 명확하게 만들거나 쉽지 않습니다.

다음은 몇 가지 사항을 변경하는 방법의 예입니다. test이 예에서 하위 디렉토리는 다음과 같이 구성되어 있습니다 :

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

importTest기능은 describe(... require...매번 전체 내용을 다시 입력하지 않고도 여러 모듈을 가져 오는 반복을 처리 할 수있는 방법을 보여주는 것입니다. common모듈은 사용자가 테스트 스위트의 여러 모듈에서 사용할 필요 유지하기위한 것입니다. 나는 실제로 그것을 사용하지 top않지만 필요한 경우 거기에서 사용할 수 있습니다.

나는이 점에 유의한다 beforeEach각과에 등록 된 모든 단일 테스트하기 전에 코드를 실행합니다 it그들은 내부에 표시할지 여부 describetop하거나에 표시 가져온 모듈의 . 를 사용 --recursive하면 beforeEach코드를 각 모듈에 복사해야하거나 beforeEach공통 모듈에서 가져온 함수를 호출하는 각 모듈에 후크 가있을 수 있습니다 .

또한 after후크는 제품군의 모든 테스트 후에 실행됩니다 . 로 복제 할 수 없습니다 --recursive. 각 모듈 --recursive에의 코드 를 사용 하여 추가 after하면 전체 테스트에 대해 한 번이 아닌 모듈 당 한 번 실행됩니다 .

모든 테스트가 단일 top제목 아래에 표시되도록하는 것은를 사용하여 복제 할 수 없습니다 --recursive. --recursive각 파일에있을 수 describe("top"있지만 이렇게 하면 각 파일에 대한 새 top제목 이 만들어 집니다.

common.js:

var chai = require("chai");

var options = {
    foo: "foo"
};

exports.options = options;
exports.chai = chai;
exports.assert = chai.assert;

이와 같은 이름 의 모듈을 사용하는 것은 여러 가지 작업을 반복 하지 않고 상태를 유지하지 않는 전역 읽기 전용 변수 또는 함수 를 보유 common하기 위해 일부 테스트 스위트에서 수행 한 작업입니다 . 나는 thgaskell의 대답과 같이 객체 를 오염시키지 않는 것을 선호합니다. 이 객체는 진정으로 전역 적이며 코드가로드 할 수있는 타사 라이브러리에서도 액세스 할 수 있기 때문입니다. 이것은 내 코드에서 허용되는 것이 아닙니다.requireglobal

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


답변

이것이 질문과 직접적으로 연결되어 있지는 않지만 내가 찾고 있던 대답은 다음과 같습니다.

$ mocha --recursive

“test”폴더의 하위 디렉토리에있는 모든 테스트를 실행합니다. 산뜻한. 로드하려는 테스트 목록을 유지하고 실제로 항상 모든 것을 실행해야하는 시간을 절약합니다.


답변

여러 테스트 파일을 실행하는 것을 방해하는 것은 없습니다. 일반적으로 각 테스트는 다른 테스트의 결과에 종속되어서는 안되므로 변수 공유는 원하는 작업이 아닙니다.

다음은 테스트 파일을 구성하는 방법의 예입니다.

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

그런 다음 mocha.opts파일 내부 에서 --recursive옵션 을 설정해야합니다 .

mocha.opts

--ui bdd
--recursive

모든 파일에 포함하려는 공통 모듈 이 있는 경우이를 파일에 추가 할 수 있습니다 common.js. test디렉토리 의 루트에있는 파일은 중첩 된 디렉토리의 파일보다 먼저 실행됩니다.

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


답변

나는 이것이 오래된 게시물이라는 것을 알고 있지만 OP가 제안한 방법과 매우 유사한 나에게 좋은 해결책이었던 것을 차임하고 싶었습니다.

내가 작업중인 프로젝트는 잘 테스트되었으며 테스트는 계속 성장하고 있습니다. 내가 사용하는 결국 require은 동기 때문에 그것을 건축에 너무 많은 변화없이 테스트를 작성하는 데 쉽게 비트 수 있기 때문에 :

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


답변

같은 범주의 클래스에 대한 여러 테스트가있는 비슷한 문제가 있었고 IDE에서 쉽게 볼 수 있도록 그룹화하고 싶었습니다. 내 모든 테스트와 코드는 이미 ES6 모듈을 사용하고있었습니다 require. 다른 예제에서 본 것처럼 모두 사용하도록 다시 작성하고 싶지 않았습니다 .

내 “그룹화”를 describe내 보낸 다음 테스트 파일로 가져 와서 가져온 .NET Framework에 프로그래밍 방식으로 추가하여 문제를 해결했습니다 describe. 결국 모든 배관을 추상화하는 도우미 메서드를 만들었습니다.

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

개별 테스트에서 :

import { default as describeCategoryMember } from './someCategory.spec';

describeCategoryMember('something', () => {
    describe('somethingElse', () => {
        ...
    });

    it('a test', () => {
        ...
    });
})


답변

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


답변