Làm thế nào để lập trình bỏ qua một bài kiểm tra trong mocha?


142

Tôi có một mã trong đó các thử nghiệm nhất định sẽ luôn thất bại trong môi trường CI. Tôi muốn vô hiệu hóa chúng dựa trên một điều kiện môi trường.

Làm thế nào để lập trình bỏ qua một bài kiểm tra trong mocha trong khi thực hiện thời gian chạy?


3
Lập trình bỏ qua một bài kiểm tra được đề cập this.skip()trong mochajs.org/#inclusive-tests và @ zatziky câu trả lời dưới đây. Phần còn lại của các câu trả lời đã lỗi thời đối với Mocha v3 +
Patrick

1
description.skip ('description', () => {}) / description.only ('description', () => {}) / it.skip ('description', () => {}) / it. chỉ ('mô tả', () => {})
Jun711

bất kỳ câu trả lời được chấp nhận?
Paul Rooney

Câu trả lời:


168

Bạn có thể bỏ qua các bài kiểm tra bằng cách đặt một x ở phía trước mô tả hoặc chặn nó hoặc đặt một dấu .skipsau nó.

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

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

Bạn cũng có thể chạy một bài kiểm tra bằng cách đặt một .onlybài kiểm tra. ví dụ

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

Chỉ có khối 2 tính năng sẽ chạy trong trường hợp này.

Dường như không có cách nào để bỏ qua các bài kiểm tra theo chương trình, nhưng bạn chỉ có thể thực hiện một số loại kiểm tra trong một beforeEachtuyên bố và chỉ chạy thử nghiệm nếu cờ được đặt.

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
Nỗ lực thứ 2 của bạn tại một giải pháp sẽ không hiệu quả, bởi vì thứ tự thực hiện không phải là thứ bạn nghĩ. Khi beforeEachcuộc gọi thực thi, Mocha ghi lại chức năng ẩn danh ("hook") để sử dụng trong tương lai , khi describecuộc gọi thực hiện, Mocha ngay lập tức thực thi chức năng ẩn danh được truyền cho nó. Vì vậy, đến lúc if (runTest)được thực thi, beforeEach hook sẽ không chạy.
Louis

22
Làm thế nào để câu trả lời này có 27 upvote? Câu hỏi hỏi về các bài kiểm tra bỏ qua lập trình, vì vậy việc thêm ".skip" hoặc ".only" không hữu ích. Sau đó, nó nói rõ ràng rằng bạn không thể làm những gì OP muốn làm, mặc dù thực tế là các câu trả lời khác cho bạn biết cách thực hiện.
Graeme Perrow

3
Sẽ không hoạt động, không phải là một câu trả lời cho câu hỏi, thay vào đó hãy xem câu trả lời của
@Gajus

1
Câu trả lời này có giá trị cho một câu hỏi khác không được hỏi ở đây. Tôi không có quyền thay đổi bất cứ điều gì ở đây. Xem câu trả lời này.skip ().
Andrew Martinez

3
điều này không trả lời câu hỏi
Ingo Renner

109

Có một cách không có giấy tờ về các bài kiểm tra bỏ qua lập trình:

// test.js

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

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

đang chạy:

$ mocha test.js


  foo
    - foo


  0 passing (9ms)
  1 pending

Điều này được thảo luận trong https://github.com/mochajs/mocha/issues/1901 .


13
Người đọc có thể muốn biết rằng điều này đánh dấu toàn bộ describelà bỏ qua (tức là tất cả các bài kiểm tra trong describeđược bỏ qua).
Louis

Tài liệu "các bài kiểm tra đang chờ xử lý" của Mocha: mochajs.org/#pending-tests
lasec0203

description.skip ('description', () => {}) / description.only ('description', () => {}) / it.skip ('description', () => {}) / it. chỉ ('mô tả', () => {})
Jun711

Tôi không hiểu tại sao loại câu trả lời này được nâng cấp. đó là một hack - và không phải là một preety.
chenop

2
tài liệu thực tế mochajs.org/#inclusive-tests , đây không phải là hack btw theo bất kỳ cách nào, nhưng là phương pháp chính xác để loại trừ một số thử nghiệm dựa trên cài đặt thời gian chạy. tức là nó trả lời chính xác những gì câu hỏi ban đầu. Cảm ơn @xavdid
WowPress.host

41

Câu trả lời này không hoạt động cho ES6 .

Thay vì:

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

Bạn muốn:

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

Điều kiện này bỏ qua tất cả các thử nghiệm trong khối mô tả NẾU điều kiện là sai.

Hoặc, thay vì:

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

Bạn muốn:

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

Điều kiện này bỏ qua một thử nghiệm NẾU điều kiện là sai.


4
Tôi hiểu những gì bạn đang đề xuất nhưng trước tiên bạn cần xác định một mô tả theo ngữ cảnh như thế này: const contextualDescribe = shouldAvoidTests ? describe.skip : describe sau đó bạn có thể sử dụng nó: contextualDescribe('your it block', () => {
Ser

3
@Ser Để có được một dòng duy nhất, tôi đã sử dụng một cái gì đó như thế này:(condition ? describe : describe.skip)('your describe block', () => {
joshden 21/12/17

Làm thế nào để làm điều này không đồng bộ? Tôi cần tra cứu điều kiện bỏ qua dựa trên cờ redis, đây là thao tác không đồng bộ (chúng tôi lưu trữ các cờ tính năng trong redis).
Patrick Finnigan

đã được một thời gian nhưng tôi cũng có loại nhu cầu này trước đây, tôi nghĩ rằng tôi chỉ gói tất cả các công cụ mocha trong một chức năng được gọi sau khi hoàn thành cuộc gọi lại async - không thể nhớ chi tiết chính xác
danday74 17/03/18

Tôi đã từng sử dụng kỹ thuật này nhưng bây giờ nó thất bại đối với tôi. hãy thử viết đơn giản(it)('my test', () => {})
cyrf

33

Tôi sử dụng bỏ qua thời gian chạy từ Mocha cho cùng một kịch bản như bạn đang mô tả. Đây là bản sao dán từ các tài liệu :

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

  // make assertions
});

Như bạn có thể thấy, nó bỏ qua bài kiểm tra dựa trên môi trường. Điều kiện riêng của tôi là if(process.env.NODE_ENV === 'continuous-integration').


2
Đã đồng ý! Có thể là một lót bằng cách trở lại sớm có lẽ? Giống như: if (/* skipTestCondition */) return this.skip();- chỉnh sửa: hoạt động: D
SidOfc

12

bỏ qua các bài kiểm tra, sử dụng describe.skiphoặcit.skip

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

để bao gồm các bài kiểm tra bạn có thể sử dụng describe.onlyhoặcit.only


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

Thêm thông tin tại https://mochajs.org/#inclusive-tests


6

Nó phụ thuộc vào cách bạn muốn lập trình bỏ qua bài kiểm tra. Nếu các điều kiện bỏ qua có thể được xác định trước khi bất kỳ mã kiểm tra nào được chạy, thì bạn chỉ có thể gọi ithoặc it.skipkhi cần, dựa trên một điều kiện. Chẳng hạn, điều này sẽ bỏ qua một số thử nghiệm nếu biến môi trường ONEđược đặt thành bất kỳ giá trị nào:

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

});

Nếu các điều kiện bạn muốn kiểm tra chỉ có thể được xác định tại thời điểm kiểm tra, thì nó phức tạp hơn một chút. Nếu bạn không muốn truy cập bất cứ điều gì không nói đúng một phần của API thử nghiệm, thì bạn có thể làm điều này:

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

});

Trong khi ví dụ đầu tiên của tôi là đánh dấu các bài kiểm tra là chính thức bị bỏ qua (còn gọi là "đang chờ xử lý"), phương pháp tôi vừa trình bày sẽ chỉ tránh thực hiện kiểm tra thực tế nhưng các bài kiểm tra sẽ không được đánh dấu là chính thức bị bỏ qua. Họ sẽ được đánh dấu là thông qua. Nếu bạn hoàn toàn muốn bỏ qua chúng, tôi không biết cách nào để truy cập vào các phần không nói đúng một phần của API thử nghiệm:

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

Tôi không chắc liệu điều này có đủ điều kiện là bỏ qua chương trình, nhưng để bỏ qua có chọn lọc một số thử nghiệm cụ thể cho môi trường CI của chúng tôi, tôi sử dụng tính năng gắn thẻ của Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). Trong describe()hoặc it()tin nhắn, bạn có thể thêm một thẻ như @ no-ci. Để loại trừ các thử nghiệm đó, bạn có thể xác định một "mục tiêu ci" cụ thể trong gói.json của mình và sử dụng --grep--invertcác tham số như:

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

Đây là một trong những cách để bỏ qua các bài kiểm tra. Một ví dụ nhỏ sẽ thực sự hữu ích. Nhưng tôi chắc chắn đồng ý rằng liên kết bạn chia sẻ có một ví dụ ngay từ đầu. @martin
Krishna Pravin

2

Bạn có thể sử dụng gói mocha-giả định của tôi để bỏ qua các bài kiểm tra theo chương trình, nhưng chỉ từ bên ngoài các bài kiểm tra. Bạn sử dụng nó như thế này:

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

Mocha-giả sử sẽ chỉ chạy thử nghiệm của bạn khi myAssumptiontrue, nếu không nó sẽ bỏ qua nó (sử dụng it.skip) với một thông điệp tốt đẹp.

Đây là một ví dụ chi tiết hơn:

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

Sử dụng nó theo cách này, bạn có thể tránh được các thất bại xếp tầng. Giả sử thử nghiệm "Does something cool"sẽ luôn thất bại khi một số Giả định không được giữ - Nhưng giả định này đã được thử nghiệm ở trên (trong Tests that verify someAssuption is always true").

Vì vậy, thất bại kiểm tra không cung cấp cho bạn bất kỳ thông tin mới. Trên thực tế, nó thậm chí là dương tính giả: Thử nghiệm không thất bại vì "thứ gì đó tuyệt vời" không hoạt động, nhưng vì điều kiện tiên quyết cho thử nghiệm không được thỏa mãn. với mocha-assumebạn thường có thể tránh những dương tính giả như vậy.


Điều này thực sự tuyệt vời, thật đáng buồn khi dự án dường như bị bỏ rơi ...
Victor Schröder

@ VictorSchröder Vâng, tôi có ấn tượng không ai sử dụng nó. Có thể xem xét cải thiện nó trong vài tuần tới, nếu tôi có thời gian. Bạn có thể mở một vấn đề trên github và cho tôi biết những gì bạn muốn xem không?
David Tanzer

Tôi chưa sử dụng nó, @David Tanzer, tôi chỉ thấy ý tưởng của bạn thực sự tuyệt vời . Tôi thấy bản thân mình đang chuẩn bị kiểm tra và bỏ qua điều kiện khá nhiều và loại giao diện này dễ đọc hơn nhiều. Tôi vẫn phải thử, nhưng tôi tưởng tượng rằng sẽ rất tuyệt nếu có thể xâu chuỗi một số giả định và hỗ trợ các chức năng không đồng bộ như các giả định. Có lẽ tất cả điều này đã được hỗ trợ, tôi chưa kiểm tra.
Victor Schröder

1
Tuy nhiên, có một vấn đề với ví dụ thứ hai trong câu trả lời này. Các beforeAllmóc không được bảo đảm để chạy trước khi tất cả các bài kiểm tra được thu thập. Trên thực tế, rất có thể chỉ chạy sau đó, nhưng trong trường hợp này, assuming(someAssumption)nó đã nhận được giá trị ban đầu (không xác định). Cũng cần phải bọc phần đó trong một chức năng để đạt được hiệu quả mong muốn.
Victor Schröder

2

Chúng ta có thể viết một hàm bao bọc sạch đẹp để chạy thử nghiệm có điều kiện như sau:

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

Điều này sau đó có thể được yêu cầu và sử dụng trong các thử nghiệm của bạn như sau:

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

Tôi nghĩ rằng đây là giải pháp thanh lịch nhất được trình bày ở đây. Nó có thể được mở rộng dễ dàng để thực hiện logic phức tạp hơn và có thêm phần thưởng mà các bài kiểm tra bỏ qua theo cách này được đánh dấu là bỏ qua trong báo cáo thử nghiệm
Joshua Evans

0

Nói rằng tôi muốn bỏ qua bài kiểm tra tham số của mình nếu mô tả kiểm tra của tôi có chứa chuỗi "foo", tôi sẽ làm điều này:

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

Trong trường hợp của bạn, tôi tin rằng nếu bạn muốn kiểm tra các biến môi trường, bạn có thể sử dụng NodeJS:

process.env.ENV_VARIABLE

Ví dụ: (Cảnh báo: Tôi chưa kiểm tra đoạn mã này!), Có thể giống như thế này:

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

Nơi bạn có thể đặt ENV_VARIABLE thành bất cứ điều gì bạn đang khóa và sử dụng giá trị đó, bỏ qua hoặc chạy thử nghiệm. (FYI tài liệu cho process.env của NodeJS có ở đây: https : //nodejs.org/api/ process.html # process_ process_env )

Tôi sẽ không hoàn toàn tin tưởng vào phần đầu tiên của giải pháp này, tôi đã tìm và kiểm tra câu trả lời và nó đã hoạt động hoàn hảo để bỏ qua các bài kiểm tra dựa trên một điều kiện đơn giản thông qua tài nguyên này: https://github.com/mochajs/mocha/issues / 591

Hi vọng điêu nay co ich! :)


0

Đây không thực sự sử dụng các tính năng của mocha, thay vào đó điều chỉnh nó để có được hành vi tôi muốn.

Tôi muốn bỏ qua bất kỳ 'nó' nào trong các thử nghiệm mocha thước đo góc của tôi và một 'nó' đã thất bại. Điều này là do một lần thử nghiệm hành trình thất bại, gần như chắc chắn phần còn lại sẽ thất bại và có thể mất nhiều thời gian và hog máy chủ xây dựng nếu họ đang sử dụng trình duyệt chờ các phần tử xuất hiện trên trang, v.v.

Khi chỉ chạy các thử nghiệm mocha tiêu chuẩn (không phải thước đo góc), điều này có thể đạt được với các móc nối trước và sau toàn cầu bằng cách gắn cờ 'SkipSub resultent' cho phụ huynh của thử nghiệm (mô tả) như thế này:

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


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

Khi thử điều này với thước đo góc và mocha, phạm vi của 'cái này' đã thay đổi và mã ở trên không hoạt động. Bạn kết thúc với một thông báo lỗi như 'lỗi gọi xong ()' và thước đo góc dừng.

Thay vào đó tôi đã kết thúc với mã dưới đây. Không phải là đẹp nhất, nhưng cuối cùng nó thay thế việc thực hiện các hàm kiểm tra còn lại bằng this.skip (). Điều này có thể sẽ ngừng hoạt động nếu / khi phần bên trong của mocha thay đổi với các phiên bản sau.

Nó đã được tìm ra thông qua một số thử nghiệm và lỗi bằng cách gỡ lỗi và kiểm tra các phần bên trong của mocha ... giúp làm cho các bộ kiểm tra trình duyệt hoàn thành sớm hơn khi các thử nghiệm thất bại.

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

Như @danielstjules đã trả lời ở đây, có một cách để bỏ qua bài kiểm tra. @ Tác giả của chủ đề này đã sao chép câu trả lời từ cuộc thảo luận của github.com mochajs, nhưng không có thông tin về phiên bản mocha nào có sẵn.

Tôi đang sử dụng mô-đun thử nghiệm grunt-mocha để tích hợp chức năng kiểm tra mocha trong dự án của mình. Nhảy đến phiên bản cuối cùng (hiện tại) - 0.12.7 mang đến cho tôi phiên bản mocha 2.4.5 với việc thực hiện this.skip ().

Vì vậy, trong gói.json của tôi

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

Và sau đó

npm install

Và nó làm tôi hạnh phúc với cái móc này:

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

Xin đừng. Một bài kiểm tra không hoạt động nhất quán trên các môi trường nên được cơ sở hạ tầng xây dựng của bạn thừa nhận. Và nó có thể rất mất phương hướng khi các bản dựng CI có số lần thử nghiệm khác với địa phương.

Ngoài ra nó vít lên độ lặp lại. Nếu các thử nghiệm khác nhau chạy trên máy chủ và cục bộ, tôi có thể có các thử nghiệm thất bại trong dev và chuyển qua CI hoặc ngược lại. Không có chức năng buộc và tôi không có cách nào để sửa một cách nhanh chóng và chính xác một bản dựng bị lỗi.

Nếu bạn phải tắt kiểm tra giữa các môi trường, thay vì kiểm tra chạy có điều kiện, hãy gắn thẻ kiểm tra của bạn và sử dụng bộ lọc để loại bỏ các kiểm tra không hoạt động trong các mục tiêu xây dựng nhất định. Bằng cách đó, mọi người đều biết những gì đang xảy ra và nó cản trở sự mong đợi của họ. Nó cũng cho mọi người biết rằng có sự không nhất quán trong khung kiểm tra và ai đó có thể có một giải pháp giúp họ chạy lại đúng cách. Nếu bạn chỉ tắt tiếng kiểm tra, họ thậm chí có thể không biết có vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.