Mocha'da bir testi programlı olarak nasıl atlayabilirim?


142

Belirli testlerin her zaman CI ortamında başarısız olacağı bir kod var. Onları bir ortam durumuna göre devre dışı bırakmak istiyorum.

Çalışma zamanında yürütme sırasında mocha'da bir testi programlı olarak nasıl atlayabilirim?


3
Programlı bir test atlayarak kaplıdır this.skip()içinde mochajs.org/#inclusive-tests ve aşağıdaki zatziky cevabı @. Cevapların geri kalanı Mocha v3 + için kullanılmıyor
Patrick

1
expla.skip ('açıklama', () => {}) / define.only ('açıklama', () => {}) / it.skip ('açıklama', () => {}) / it. yalnızca ('description', () => {})
711 Haziran

kabul edilmiş bir cevap var mı?
Paul Rooney

Yanıtlar:


168

Açıklamanın veya bloğun önüne bir x koyarak veya bir .skipsonrasını yerleştirerek testleri atlayabilirsiniz .

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

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

Teste bir yerleştirerek tek bir test de yapabilirsiniz .only. Örneğin

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

Bu durumda yalnızca özellik 2 bloğu çalışır.

Testleri programlı olarak atlamanın bir yolu yoktur, ancak bir beforeEachdeyimde bir çeşit check-in yapabilir ve sadece bayrak ayarlanmışsa testi çalıştırabilirsiniz.

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
Bir çözüm için 2. denemeniz işe yaramaz, çünkü yürütme sırası düşündüğünüz değildir. Ne zaman beforeEachçağrı yürütür, Mocha kaydeden anonim fonksiyonu için ( "kanca") gelecek kullanımı, zaman describeçağrı yürütür, Mocha hemen kendisine geçirilen anonim işlevini yürütür. Bu yüzden if (runTest), yürütüldüğünde, beforeEach kanca çalışmaz.
Louis

23
Bu cevabın nasıl 27 upvotes var? Soru programlı olarak testleri atlamayı sorar, bu nedenle ".skip" veya ".only" eklemek işe yaramaz. Daha sonra, diğer cevapların size nasıl yapılacağını söylese de, OP'nin yapmak istediklerini yapamayacağınızı açıkça söylüyor.
Graeme Perrow

3
Çalışmayacak, soruya bir cevap değil, bunun yerine
@Gajus'un

1
Bu cevabın burada sorulmamış başka bir soruya faydası var. Burada hiçbir şeyi değiştirecek gücüm yok. This.skip () yanıtına bakın.
Andrew Martinez

3
bu soruya cevap vermiyor
Ingo Renner

110

Testleri programlı olarak atlamanın belgelenmemiş bir yolu vardır:

// test.js

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

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

çalışan:

$ mocha test.js


  foo
    - foo


  0 passing (9ms)
  1 pending

Bu, https://github.com/mochajs/mocha/issues/1901 adresinde tartışılmaktadır .


14
Okuyucular bunun tümünün describeatlanmış olarak işaretlendiğini bilmek isteyebilir (örn. İçindeki tüm testler describeatlanır).
Louis


expla.skip ('açıklama', () => {}) / define.only ('açıklama', () => {}) / it.skip ('açıklama', () => {}) / it. yalnızca ('description', () => {})
711 Haziran

Bu tür bir cevabın neden iptal edildiğini anlamıyorum. bu bir hack - ve bir preety değil.
chenop

2
gerçek dokümantasyon mochajs.org/#inclusive-tests , herhangi bir şekilde bir kesmek btw değil, çalışma zamanı ayarlarına dayalı bazı testleri hariç tutmak için doğru yöntemdir. yani asıl sorunun sorduğu soruya tam olarak cevap verir. Teşekkürler @xavdid
WowPress.host

41

Bu cevap ES6 için işe yarar .

Onun yerine:

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

İstediğiniz:

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

Bu, koşul yanlışsa, açıklama bloğundaki tüm testleri atlar.

Veya:

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

İstediğiniz:

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

Koşul yanlışsa bu şartlı olarak bir test atlar.


4
Ne önerdiğini anlıyorum ama önce şöyle bir bağlamsal tanım tanımlamanız gerekiyor : const contextualDescribe = shouldAvoidTests ? describe.skip : describe o zaman kullanabilirsiniz: contextualDescribe('your it block', () => {
Ser

3
@Ser Tek bir hatta girmek için şöyle bir şey kullandım:(condition ? describe : describe.skip)('your describe block', () => {
joshden

Bu zaman uyumsuzluk nasıl yapılır? Bir asenkron işlem (redis özellik bayrakları saklar) olan redis bayrağına göre atlama koşulu aramak gerekir.
Patrick Finnigan

Bir süre oldu ama ive daha önce bu tür bir ihtiyaç vardı, ben sadece async geri arama tamamlandıktan sonra çağrılan bir fonksiyonda tüm mocha şeyler sarılmış - kesin ayrıntıları hatırlayamıyorum
danday74 17:18

Bu tekniği kullanırdım ama şimdi benim için başarısız oluyor. sadece yazmaya çalışın(it)('my test', () => {})
cyrf

33

Açıkladığınız aynı senaryo için Mocha'dan çalışma zamanı atlama özelliğini kullanıyorum. Dokümanlardan kopyala yapıştır :

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

  // make assertions
});

Gördüğünüz gibi testi ortama göre atlıyor. Benim durumum if(process.env.NODE_ENV === 'continuous-integration').


2
Kabul! Belki erken bir dönüş yaparak tek astar olabilir mi? Beğen: if (/* skipTestCondition */) return this.skip();- düzenle: çalışır: D
SidOfc

12

testleri atlamak için describe.skipveyait.skip

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

kullanabileceğiniz testleri dahil etmek describe.onlyveyait.only


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

Https://mochajs.org/#inclusive-tests adresinde daha fazla bilgi


6

Testi programlı olarak nasıl atlamak istediğinize bağlıdır. Atlama koşulları herhangi bir test kodu çalıştırılmadan önce belirlenebilirse , bir koşula bağlı olarak sadece arayabilir itveya it.skipgerektiği gibi arayabilirsiniz . Örneğin, ortam değişkeni ONEherhangi bir değere ayarlanırsa bu bazı testleri atlar :

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

});

Kontrol etmek istediğiniz koşullar sadece test zamanında belirlenebilirse, biraz daha karmaşıktır. Test API'sının tam olarak konuşmadığı bir şeye erişmek istemiyorsanız, bunu yapabilirsiniz:

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

});

İlk örneğim testleri resmi olarak atlanmış olarak işaretlerken (aka "beklemede"), az önce gösterdiğim yöntem sadece gerçek testi yapmaktan kaçınacak, ancak testler resmi olarak atlanmış olarak işaretlenmeyecek. Geçti olarak işaretlenirler. Kesinlikle atlanmasını istiyorsanız, test API'sının bir parçası olarak düzgün bir şekilde konuşmayan parçalara erişmenin kısa bir yolunu bilmiyorum:

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

Bunun “programlı atlama” olarak nitelendirilip değerlendirilmediğinden emin değilim, ancak CI ortamımız için bazı spesifik testleri seçici olarak atlamak için Mocha'nın etiketleme özelliğini kullanıyorum ( https://github.com/mochajs/mocha/wiki/Tagging ). İçine describe()veya it()iletilere @ no-ci gibi bir etiket ekleyebilirsiniz. Bu testleri hariç tutmak için paketinizde belirli bir "ci hedefi" tanımlayabilir --grepve aşağıdaki --invertgibi kullanım ve parametreleri kullanabilirsiniz :

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

Testleri atlamanın yollarından biri budur. Küçük bir örnek gerçekten yararlı olacaktır. Ancak kesinlikle paylaştığınız bağlantının başlangıçta bir örneği olduğunu kabul ediyorum. @martin
Krishna Pravin

2

Paketimi programlı olarak atlamak için mocha-varsaymayı kullanabilirsiniz, ancak yalnızca testlerin dışından yapabilirsiniz. Bu şekilde kullanırsınız:

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

Mocha-varsayım testinizi sadece myAssumptionolduğu zaman gerçekleştirir true, aksi takdirde it.skipgüzel bir mesajla (kullanarak ) atlar .

İşte daha ayrıntılı bir örnek:

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

Bu şekilde kullanarak basamaklı hataları önleyebilirsiniz. Diyelim ki bazı "Does something cool"varsayımlar geçerli olmadığında test her zaman başarısız olur - Ama bu varsayım yukarıda (in Tests that verify someAssuption is always true") zaten test edilmiştir .

Bu nedenle test hatası size yeni bir bilgi vermez. Aslında, bu yanlış bir pozitiftir: "Başarısız bir şey" çalışmadığı için test başarısız olmadı, ancak test için bir önkoşul sağlanamadı. ile mocha-assumesize genellikle bu tür yanlış pozitif önleyebilirsiniz.


Bu gerçekten harika, projenin terk edilmiş gibi göründüğü üzücü ...
Victor Schröder

@ VictorSchröder Eh, kimsenin kullanmadığı izlenimine kapıldım. Eğer zamanım olsaydı, önümüzdeki birkaç hafta içinde geliştirmeye bakabiliriz. Github'da bir sorun açabilir ve bana ne görmek istediğinizi söyleyebilir misiniz?
David Tanzer

Henüz kullanmýyorum, @David Tanzer, fikrini çok iyi buldum . Kendimi test hazırlığı ve koşullu atlama yaptığını görüyorum ve bu tür bir arayüz çok daha okunabilir. Yine de denemeliyim, ancak birkaç varsayımı zincirleyebilmenin ve async işlevlerini varsayımlar olarak destekleyebilmenin harika olacağını hayal ediyorum. Belki de tüm bunlar zaten destekleniyor, kontrol etmedim.
Victor Schröder

1
Yine de bu cevabın ikinci örneğinde bir sorun var. beforeAllKanca Tüm testler toplanmadan önce çalıştırmak için garanti edilmez. Aslında, sadece daha sonra çalışması muhtemeldir, ancak bu durumda assuming(someAssumption)başlangıç ​​(tanımsız) değerini zaten almış olurdu. İstenilen efekti elde etmek için bu parçayı bir fonksiyona da sarmak gerekir.
Victor Schröder

2

Koşullu olarak testleri aşağıdaki gibi çalıştırmak için güzel bir temiz sarmalayıcı işlevi yazabiliriz:

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

Bu daha sonra aşağıdaki gibi testlerinizde gerekli ve kullanılabilir:

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

Bence bu, burada sunulan en şık çözüm. Daha karmaşık bir mantık yapmak için kolayca genişletilebilir ve bu şekilde atlanan testlerin test raporunda atlanmış olarak işaretlendiği ek bonusu vardır
Joshua Evans

0

Test açıklamam "foo" dizesini içeriyorsa parametreli testimi atlamak istedim, bunu yaparım:

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

Sizin durumunuzda, ortam değişkenlerini kontrol etmek isterseniz, NodeJS'leri kullanabileceğinize inanıyorum:

process.env.ENV_VARIABLE

Örneğin (Uyarı: Bu kod biraz test etmedim!), Belki böyle bir şey:

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

ENV_VARIABLE'ı, anahtarladığınız her şey olacak şekilde ayarlayabildiğinizde ve bu değeri kullanarak testi atlayın veya çalıştırın. (NodeJS'nin process.env belgelerine bakın: https://nodejs.org/api/process.html#process_process_env )

Bu çözümün ilk kısmı için tam kredi almayacağım, cevabı buldum ve test ettim ve bu kaynak aracılığıyla basit bir koşula dayanan testleri atlamak için mükemmel çalıştı: https://github.com/mochajs/mocha/issues / 591

Bu yardımcı olur umarım! :)


0

Bu gerçekten mocha'nın özelliklerini kullanmıyor, istediğim davranışı elde etmek için ayarlıyor.

İletki mocha testlerimde herhangi bir 'o' atlamak istedim ve bir 'o' başarısız oldu. Bunun nedeni, bir yolculuk testinin bir adımının başarısız olmasının, geri kalanının başarısız olacağından neredeyse emin olmasıdır ve tarayıcı kullanıyorlarsa, bir sayfada vb. Öğelerin görünmesini beklerlerse uzun sürebilir ve oluşturma sunucusunu bağlayabilirler.

Sadece standart mocha testleri (iletici değil) çalıştırırken, bu testin üst öğesine bir 'skipSubsequent' bayrağı ekleyerek (açıklayın) global beforeEach ve afterEach kancaları ile elde edilebilir:

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


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

Bunu iletki ve mocha ile denerken 'this' kapsamı değişti ve yukarıdaki kod çalışmaz. 'Hata arama bitti ()' ve iletki durdurma gibi bir hata mesajı ile sonuçlanırsınız.

Bunun yerine aşağıdaki kodu buldum. En güzel değil, ancak kalan test işlevlerinin uygulanmasını bir this.skip () ile değiştirir. Mocha'nın iç kısımları daha sonraki sürümlerle değişirse / olduğunda bu muhtemelen durur.

Mocha'nın iç kısımlarında hata ayıklama ve inceleme yaparak bazı deneme yanılma yoluyla çözüldü ... testler başarısız olduğunda tarayıcı test paketlerinin daha çabuk tamamlanmasına yardımcı oluyor.

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 burada yanıtladığı gibi testi atlamanın bir yolu var. Bu konunun @ yazarı cevap github.com mochajs tartışmadan kopyaladı, ancak mevcut mocha sürümünde bilgi yok.

Projemde mocha test işlevselliğini entegre etmek için grunt-mocha-test modülü kullanıyorum. (Şimdilik) son sürüme atlamak - 0.12.7 this.skip () uygulamasıyla bana mocha 2.4.5 sürümünü getiriyor.

Yani, paketimde. Json

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

Ve sonra

npm install

Ve bu kanca ile beni mutlu ediyor:

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

Lütfen yapma. Ortamlar arasında tutarlı bir şekilde çalışmayan bir test, yapı altyapınız tarafından olduğu gibi kabul edilmelidir. Ve CI yapılarının yerelden farklı sayıda test yürütmesi çok yön değiştirici olabilir.

Ayrıca tekrarlanabilirliği de arttırır. Sunucuda ve yerelde farklı testler çalışıyorsa, testlerde başarısız olan ve CI veya tersi geçen testleri test edebilirim. Zorlama işlevi yoktur ve başarısız bir yapıyı hızlı ve doğru bir şekilde düzeltmenin bir yolu yoktur.

Testleri ortamlar arasında kapatmanız gerekiyorsa, koşullu olarak test yapmak yerine, testlerinizi etiketleyin ve belirli oluşturma hedeflerinde çalışmayan testleri ortadan kaldırmak için bir filtre kullanın. Bu şekilde herkes neler olduğunu bilir ve beklentilerini cezbeder. Ayrıca, herkesin test çerçevesinde tutarsızlık olduğunu bilmesini sağlar ve birisinin tekrar düzgün çalışmasını sağlayan bir çözümü olabilir. Testi susturursanız, bir sorun olduğunu bile bilmeyebilirler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.