프로그래밍 방식으로 모카에서 테스트를 건너 뛰는 방법은 무엇입니까?


142

CI 환경에서 특정 테스트가 항상 실패하는 코드가 있습니다. 환경 조건에 따라 비활성화하고 싶습니다.

런타임 실행 중에 프로그래밍 방식으로 모카에서 테스트를 건너 뛰는 방법은 무엇입니까?


3
프로그래밍 방식으로 테스트를 건너 뛰는 방법은 mochajs.org/#inclusive-tests 및 아래 @zatziky의 답변 this.skip()에서 다룹 니다. 나머지 답변은 Mocha v3 +에서 더 이상 사용되지 않습니다
Patrick

1
describe.skip ( 'description', () => {}) / describe.only ( 'description', () => {}) / it.skip ( 'description', () => {}) / it. only ( 'description', () => {})
Jun711

수락 된 답변이 있습니까?
Paul Rooney

답변:


168

describe 또는 it 블록 앞에 x를 배치하거나 .skip뒤에 배치하여 테스트를 건너 뛸 수 있습니다 .

xit('should work', function (done) {});

describe.skip('features', function() {});

테스트를 수행하여 단일 테스트를 실행할 수도 있습니다 .only. 예를 들어

describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});

이 경우 기능 2 블록 만 실행됩니다.

프로그래밍 방식으로 테스트를 건너 뛸 수있는 방법은 없지만 beforeEach명령문 에서 일종의 검사를 수행하고 플래그가 설정된 경우에만 테스트를 실행할 수 있습니다.

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,
         }
    }
}

8
실행 순서가 생각하는 순서가 아니기 때문에 솔루션에 대한 두 번째 시도는 작동하지 않습니다. beforeEach호출이 실행될 때 Mocha 는 나중에 사용할 수 있도록 익명 함수 ( "후크")를 기록 하고 호출이 실행될 때 Mocha 는 전달 된 익명 함수를 즉시 실행합니다. 따라서 시간 이 지나면 후크 가 실행되지 않습니다. describeif (runTest)beforeEach
Louis

23
이 답변에는 어떻게 27 개의 공감대가 있습니까? 이 질문은 프로그래밍 방식으로 테스트를 건너 뛰는 것에 대한 질문이므로 ".skip"또는 ".only"를 추가하는 것은 도움이되지 않습니다. 그런 다음 다른 답변에서 방법을 알려주는 사실에도 불구하고 OP가 원하는 것을 할 수 없다고 명시 적으로 말합니다.
Graeme Perrow

3
질문에 대한 답변이 아니라 작동하지 않습니다. 대신 @Gajus의 응답을 참조하십시오.
NorTicUs

1
이 답변은 여기에 묻지 않은 다른 질문에 대한 장점이 있습니다. 나는 여기서 아무것도 바꿀 힘이 없다. this.skip () 답변을 참조하십시오.
앤드류 마르티네즈

3
이 질문에 대답하지 않습니다
잉고 레너

110

프로그래밍 방식으로 테스트를 건너 뛰는 문서화되지 않은 방법이 있습니다.

// test.js

describe('foo', function() {
  before(function() {
    this.skip();
  });

  it('foo', function() {
    // will not run
    console.log('This will not be printed');
  });
});

달리는:

$ mocha test.js


  foo
    - foo


  0 passing (9ms)
  1 pending

이것은 https://github.com/mochajs/mocha/issues/1901 에서 논의됩니다 .


14
독자들은 이것이 전체 describe를 건너 뛴 것으로 표시한다는 것을 알고 싶어 할 것입니다 (즉,의 모든 테스트 describe는 건너 뜁니다).
Louis

Mocha의 "보류중인 테스트"문서 : mochajs.org/#pending-tests
lasec0203

describe.skip ( 'description', () => {}) / describe.only ( 'description', () => {}) / it.skip ( 'description', () => {}) / it. only ( 'description', () => {})
Jun711

나는 왜 이런 종류의 대답이 찬성되는지 이해하지 못한다. 그것의 해킹-그리고 preety가 아닙니다.
Chenop

2
실제 문서 mochajs.org/#inclusive-tests , 그것은 어떤 식 으로든 해킹이 아니지만 런타임 설정에 따라 일부 테스트를 제외하는 올바른 방법입니다. 즉, 원래의 질문에 정확히 답변합니다. 감사합니다 @xavdid
WowPress.host

41

이 답변은 ES6에서 작동합니다 .

대신에:

describe('your describe block', () => {

당신이 원하는 :

(condition ? describe : describe.skip)('your describe block', () => {

조건이 거짓이면 설명 블록의 모든 테스트를 조건부로 건너 뜁니다.

또는 대신 :

it('your it block', () => {

당신이 원하는 :

(condition ? it : it.skip)('your it block', () => {

조건이 거짓 인 경우 조건부로 하나의 테스트를 건너 뜁니다.


4
나는 당신이 제안하는 것을 얻지 만 먼저 다음 과 같은 문맥 설명 을 정의해야합니다 . const contextualDescribe = shouldAvoidTests ? describe.skip : describe그런 다음 사용할 수 있습니다 : contextualDescribe('your it block', () => {
Ser

3
@Ser 한 줄을 타기 위해 다음과 같이 사용했습니다.(condition ? describe : describe.skip)('your describe block', () => {
joshden

이 비동기 작업을 수행하는 방법? 비동기 작업 인 redis 플래그를 기반으로 건너 뛰기 조건을 찾아야합니다 (우리는 기능 플래그를 redis에 저장합니다).
Patrick Finnigan

정확한 세부 사항을 기억하지 못할 - 난 그냥 비동기 콜백이 완료된 후 호출 된 함수의 모든 모카 물건 포장 생각 오랜만하지만 너무 전에 필요의이 종류를 가지고 살아야
danday74

나는이 기술을 사용했지만 지금은 실패합니다. 간단히 작성해보십시오(it)('my test', () => {})
cyrf

33

설명하는 것과 동일한 시나리오에서 Mocha에서 런타임 건너 뛰기를 사용합니다. 문서 의 사본 붙여 넣기입니다 .

it('should only test in the correct environment', function() {
  if (/* check test environment */) return this.skip();

  // make assertions
});

보시다시피 환경에 따른 테스트를 건너 뜁니다. 내 자신의 상태는 if(process.env.NODE_ENV === 'continuous-integration')입니다.


2
동의했다! 아마 일찍 귀국하여 한 명의 라이너가 될 수 있습니까? 좋아요 : if (/* skipTestCondition */) return this.skip();-편집 : 작품 : D
SidOfc

12

테스트를 건너 뛰려면 describe.skip또는it.skip

describe('Array', function() {
  it.skip('#indexOf', function() {
    // ...
  });
});

사용할 수있는 테스트를 포함 describe.only하거나it.only


describe('Array', function() {
  it.only('#indexOf', function() {
    // ...
  });
});

https://mochajs.org/#inclusive-tests 에서 자세한 정보


6

프로그래밍 방식으로 테스트를 건너 뛰려는 방법에 따라 다릅니다. 테스트 코드를 실행 하기 전에 건너 뛰기 조건을 결정할 수 있으면 조건에 따라 호출 it하거나 it.skip필요에 따라 호출 할 수 있습니다 . 예를 들어 환경 변수 ONE가 임의의 값으로 설정된 경우 일부 테스트를 건너 뜁니다 .

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

});

확인하려는 조건을 테스트 할 때만 확인할 수 있으면 좀 더 복잡합니다. 테스트 API의 일부를 엄격하게 말하지 않는 것에 액세스하지 않으려면 다음을 수행하십시오.

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

});

첫 번째 예제는 테스트를 공식적으로 건너 뛴 것으로 표시하는 반면 (일명 "보류 중") 방금 보여준 방법은 실제 테스트를 수행하지 않고 테스트는 공식적으로 건너 뛴 것으로 표시되지 않습니다. 합격으로 표시됩니다. 절대로 건너 뛰기를 원한다면 테스트 API의 일부를 올바르게 말하지 않는 부분에 액세스하는 방법이 부족합니다.

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

});

3

이것이 "프로그래밍 건너 뛰기"인지 여부는 확실하지 않지만 CI 환경에 대한 특정 테스트를 선택적으로 건너 뛰려면 Mocha의 태깅 기능 ( https://github.com/mochajs/mocha/wiki/Tagging )을 사용합니다. 에서 describe()또는 it()메시지, 당신은 @없는 CI 같은 태그를 추가 할 수 있습니다. 이러한 테스트를 제외하기 위해 package.json에 특정 "ci 대상"을 정의하고 다음 --grep--invert같은 매개 변수를 사용합니다 .

"scripts": {
  "test": "mocha",
  "test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}

이것은 테스트를 건너 뛰는 방법 중 하나입니다. 작은 예가 정말 유용 할 것입니다. 그러나 나는 당신이 공유 한 링크가 처음에 예제를 가지고 있음에 분명히 동의합니다. @ 마틴
크리슈나

2

패키지 mocha-assume 을 사용하여 프로그래밍 방식으로 테스트를 건너 뛸 수 있지만 테스트 외부에서만 테스트를 건너 뛸 수 있습니다 . 당신은 이것을 다음과 같이 사용합니다 :

assuming(myAssumption).it("does someting nice", () => {});

Mocha-assume은 myAssumptionis true일 때만 테스트를 실행 하고 그렇지 않으면 it.skip좋은 메시지와 함께 테스트 를 건너 뜁니다 (사용 ).

보다 자세한 예는 다음과 같습니다.

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

이 방법을 사용하면 계단식 오류를 피할 수 있습니다. "Does something cool"someAssumption이 유지되지 않으면 테스트 가 항상 실패 한다고 가정하십시오. 하지만이 가정은 이미 위에서 테스트되었습니다 Tests that verify someAssuption is always true".

따라서 테스트 실패는 새로운 정보를 제공하지 않습니다. 사실, 그것은 거짓 양성이기도합니다. "멋진 것"이 효과가 없기 때문에 테스트가 실패하지 않았지만 테스트의 전제 조건이 충족되지 않았기 때문에 테스트가 실패했습니다. 함께 mocha-assume하면 종종 거짓의 양성을 피할 수 있습니다.


프로젝트가 버린 것 같다는 것이 정말 시원하고 슬프다 ...
Victor Schröder

@ VictorSchröder 글쎄, 나는 아무도 그것을 사용하지 않았다는 인상을 받았다. 내가 시간이 있다면, 앞으로 몇 주 안에 그것을 개선 할 수있을 것입니다. github에서 이슈를 열어보고 싶은 것을 말해 줄 수 있습니까?
David Tanzer

@David Tanzer, 나는 그것을 아직 사용하지 않고 있습니다. 방금 아이디어가 정말 멋지다는 것을 알았습니다 . 나는 테스트 준비와 조건부 건너 뛰기를 꽤 많이하고 있으며 이런 종류의 인터페이스는 훨씬 더 읽기 쉽습니다. 여전히 시도해보아야하지만 여러 가정을 연결하고 비동기 함수를 가정으로 지원하는 것이 멋지다고 생각합니다. 어쩌면이 모든 것이 이미 지원되고 있지만 확인하지 않았습니다.
빅터 슈뢰더

1
그러나이 답변의 두 번째 예에는 문제가 있습니다. beforeAll후크는 모든 테스트가 수집되기 전에 실행을 보장 할 수 없습니다. 실제로 나중에 실행될 가능성이 매우 높지만이 경우 assuming(someAssumption)이미 초기 값 (정의되지 않은)을 받았을 것입니다. 원하는 효과를 얻으려면 해당 부분을 함수로 감싸 야합니다.
빅터 슈뢰더

2

조건부로 테스트를 실행하기 위해 다음과 같이 깔끔한 랩퍼 함수를 ​​작성할 수 있습니다.

function ifConditionIt(title, test) {
  // Define your condition here
  return condition ? it(title, test) : it.skip(title, test);
}

그런 다음 다음과 같이 테스트에서 필요하고 사용할 수 있습니다.

ifConditionIt('Should be an awesome test', (done) => {
  // Test things
  done();
});

나는 이것이 여기에 제시된 가장 우아한 해결책이라고 생각합니다. 보다 복잡한 논리를 수행하기 위해 쉽게 확장 할 수 있으며, 이런 방식으로 건너 뛴 테스트는 테스트 보고서에서 건너 뛴 것으로 표시되는 추가 보너스가 있습니다.
Joshua Evans

0

테스트 설명에 "foo"라는 문자열이 포함되어 있으면 매개 변수화 된 테스트를 건너 뛰고 싶다고 가정 해 보겠습니다.

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

귀하의 경우 환경 변수를 확인하려면 NodeJS를 사용할 수 있다고 생각합니다.

process.env.ENV_VARIABLE

예를 들어 (경고 :이 코드를 테스트하지 않았습니다!), 아마도 다음과 같습니다.

(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
    // Code here
});

ENV_VARIABLE을 키로 설정하고 해당 값을 사용하여 테스트를 건너 뛰거나 실행할 수있는 경우. (참고로 NodeJS 'process.env에 대한 설명서는 여기에 있습니다 : https://nodejs.org/api/process.html#process_process_env )

나는이 솔루션의 첫 번째 부분에 대해 완전한 신용을 얻지 못하고 답을 찾아 테스트 했으며이 리소스를 통해 간단한 조건에 따라 테스트를 건너 뛰는 데 완벽하게 작동했습니다. https://github.com/mochajs/mocha/issues / 591

도움이 되었기를 바랍니다! :)


0

이것은 실제로 mocha의 기능을 사용하지 않고 원하는 동작을 얻도록 조정합니다.

나는 각도기 모카 테스트에서 후속 'it 's'를 건너 뛰고 싶었고 'it'는 실패했습니다. 여행 테스트의 한 단계가 실패하면 나머지 부분이 실패 할 것이 거의 확실했기 때문에 브라우저를 사용하는 경우 빌드 서버가 페이지에 요소가 나타날 때까지 대기하는 경우 시간이 오래 걸리고 빌드 서버를 낭비 할 수 있기 때문입니다.

각도기가 아닌 표준 모카 테스트를 실행하는 경우 다음과 같이 'skipSubsequent'플래그를 테스트의 상위 (설명)에 첨부하여 전역 beforeEach 및 afterEach 후크를 사용하여이를 달성 할 수 있습니다.

    beforeEach(function() {
      if(this.currentTest.parent.skipSubsequent) {
            this.skip();
      }
    }); 


    afterEach(function() {
      if (this.currentTest.state === 'failed') {
        this.currentTest.parent.skipSubsequent = 'true'
      }
    })

각도기와 모카로 이것을 시도하면 'this'의 범위가 변경되고 위의 코드가 작동하지 않습니다. 'error calling done ()'과 같은 오류 메시지가 표시되고 각도기가 멈 춥니 다.

대신 나는 아래 코드로 끝났다. 가장 예쁘지는 않지만 나머지 테스트 함수의 구현을 this.skip ()로 대체합니다. 모카의 내부가 이후 버전으로 변경되면 작동이 멈출 것입니다.

그것은 모카의 내부를 디버깅하고 검사함으로써 시행 착오를 통해 알아 냈습니다 ... 테스트가 실패하면 브라우저 테스트 스위트가 더 빨리 완료되도록 도와줍니다.

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


-2

@danielstjules이 여기 에 대답했듯이 테스트를 건너 뛸 수있는 방법이 있습니다. 이 주제의 @author는 github.com mochajs 토론에서 답변을 복사했지만 사용 가능한 mocha 버전에 대한 정보는 없습니다.

프로젝트에 모카 테스트 기능을 통합하기 위해 grunt-mocha-test 모듈을 사용하고 있습니다. 마지막 (현재) 버전-0.12.7로 점프하면 this.skip () 구현으로 모카 버전 2.4.5가 나타납니다.

그래서 내 package.json에서

  "devDependencies": {
    "grunt-mocha-test": "^0.12.7",
    ...

그리고

npm install

그리고이 후크로 나를 행복하게 만듭니다.

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

        ...

-2

제발 하지마 여러 환경에서 일관되게 작동하지 않는 테스트는 빌드 인프라에서 인정해야합니다. CI 빌드가 로컬과 다른 수의 테스트를 실행하면 매우 혼란 스러울 수 있습니다.

또한 반복성을 망칩니다. 서버와 로컬에서 다른 테스트를 실행하면 개발에 실패하고 CI를 통과하거나 그 반대로 테스트를 할 수 있습니다. 강제 기능이 없으며 실패한 빌드를 빠르고 정확하게 수정할 방법이 없습니다.

조건부로 테스트를 실행하는 대신 환경간에 테스트를 꺼야하는 경우 테스트에 태그를 지정하고 필터를 사용하여 특정 빌드 대상에서 작동하지 않는 테스트를 제거하십시오. 그렇게함으로써 모든 사람들은 무슨 일이 일어나고 있는지 알고 있으며 그들의 기대에 부응합니다. 또한 테스트 프레임 워크에 불일치가 있음을 모두에게 알리고 누군가가 다시 제대로 실행되도록하는 솔루션이있을 수 있습니다. 테스트를 음소거하면 문제가 있음을 알지 못할 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.