Saya memiliki kode di mana tes tertentu akan selalu gagal di lingkungan CI. Saya ingin menonaktifkannya berdasarkan kondisi lingkungan.
Bagaimana cara melewatkan tes di moka secara terprogram selama eksekusi runtime?
Saya memiliki kode di mana tes tertentu akan selalu gagal di lingkungan CI. Saya ingin menonaktifkannya berdasarkan kondisi lingkungan.
Bagaimana cara melewatkan tes di moka secara terprogram selama eksekusi runtime?
Jawaban:
Anda dapat melewati tes dengan menempatkan x di depan deskripsikan atau memblokirnya, atau menempatkan .skip
setelahnya.
xit('should work', function (done) {});
describe.skip('features', function() {});
Anda juga dapat menjalankan tes tunggal dengan menempatkan .only
tes. misalnya
describe('feature 1', function() {});
describe.only('feature 2', function() {});
describe('feature 3', function() {});
Hanya blok fitur 2 yang akan berjalan dalam kasus ini.
Tampaknya tidak ada cara untuk melewatkan tes secara terprogram, tetapi Anda bisa melakukan semacam pemeriksaan dalam sebuah beforeEach
pernyataan dan hanya menjalankan tes jika flag ditetapkan.
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,
}
}
}
beforeEach
panggilan dijalankan, Mocha mencatat fungsi anonim ("kait") untuk digunakan di masa depan , ketika describe
panggilan dieksekusi, Mocha segera mengeksekusi fungsi anonim yang diteruskan ke sana. Jadi pada saat if (runTest)
dieksekusi, beforeEach
kait tidak akan berjalan.
Ada cara yang tidak berdokumen untuk melewatkan tes secara terprogram:
// test.js
describe('foo', function() {
before(function() {
this.skip();
});
it('foo', function() {
// will not run
console.log('This will not be printed');
});
});
berlari:
$ mocha test.js
foo
- foo
0 passing (9ms)
1 pending
Ini dibahas di https://github.com/mochajs/mocha/issues/1901 .
describe
sebagai dilewati (yaitu semua tes di describe
dilewati).
Jawaban ini berfungsi untuk ES6 .
Dari pada:
describe('your describe block', () => {
Kamu ingin:
(condition ? describe : describe.skip)('your describe block', () => {
Kondisi ini melewatkan semua tes dalam blok uraian JIKA kondisinya salah.
Atau, bukannya:
it('your it block', () => {
Kamu ingin:
(condition ? it : it.skip)('your it block', () => {
Persyaratan ini melewatkan satu pengujian JIKA kondisinya salah.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
kemudian Anda dapat menggunakannya: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
Saya menggunakan runtime skipping dari Mocha untuk skenario yang sama seperti yang Anda gambarkan. Ini adalah salinan dari dokumen :
it('should only test in the correct environment', function() {
if (/* check test environment */) return this.skip();
// make assertions
});
Seperti yang Anda lihat, tes ini dilewati berdasarkan lingkungan. Kondisiku sendiri if(process.env.NODE_ENV === 'continuous-integration')
.
if (/* skipTestCondition */) return this.skip();
- sunting: karya: D
describe.skip
atauit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
atauit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Info lebih lanjut di https://mochajs.org/#inclusive-tests
Tergantung bagaimana Anda ingin melewatkan tes secara terprogram. Jika kondisi untuk dilewati dapat ditentukan sebelum kode pengujian dijalankan, maka Anda dapat menelepon it
atau it.skip
sesuai kebutuhan, berdasarkan kondisi. Misalnya, ini akan melewati beberapa tes jika variabel lingkungan ONE
disetel ke nilai apa pun:
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!");
});
});
Jika kondisi yang ingin Anda periksa hanya dapat ditentukan pada waktu tes, itu sedikit lebih rumit. Jika Anda tidak ingin mengakses apa pun yang tidak sepenuhnya merupakan bagian dari API pengujian, maka Anda dapat melakukan ini:
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!");
});
});
Sedangkan contoh pertama saya adalah menandai tes yang dilewati secara formal (alias "tertunda"), metode yang baru saja saya tunjukkan hanya akan menghindari melakukan tes yang sebenarnya tetapi tes tidak akan ditandai sebagai dilewati secara resmi. Mereka akan ditandai sebagai lulus. Jika Anda benar-benar ingin agar mereka dilewati, saya tidak tahu cara apa pun untuk mengakses bagian yang tidak berbicara dengan benar sebagai bagian dari API pengujian:
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!");
});
});
Saya tidak yakin apakah ini memenuhi syarat sebagai "lompatan terprogram", tetapi untuk melewati beberapa tes khusus untuk lingkungan CI kami, saya menggunakan fitur penandaan Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ). Dalam describe()
atau it()
pesan, Anda dapat menambahkan tag seperti @ no-ci. Untuk mengecualikan tes tersebut, Anda dapat menentukan "target ci" spesifik di package.json Anda dan menggunakan --grep
dan --invert
parameter seperti:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
Anda dapat menggunakan paket saya mocha-berasumsi untuk melewati tes pemrograman, tetapi hanya dari luar tes. Anda menggunakannya seperti ini:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-menganggap hanya akan menjalankan tes Anda saat myAssumption
ini true
, jika tidak maka akan melewatkannya (menggunakan it.skip
) dengan pesan yang bagus.
Inilah contoh yang lebih rinci:
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... */
});
});
});
Dengan menggunakan cara ini, Anda dapat menghindari kegagalan cascading. Katakanlah tes "Does something cool"
akan selalu gagal ketika beberapa Asumsi tidak berlaku - Tapi asumsi ini sudah diuji di atas (dalam Tests that verify someAssuption is always true"
).
Jadi kegagalan tes tidak memberi Anda informasi baru. Bahkan, itu bahkan salah-positif: Tes tidak gagal karena "sesuatu yang keren" tidak berfungsi, tetapi karena prasyarat untuk tes tidak memuaskan. dengan mocha-assume
Anda sering dapat menghindari positif palsu seperti itu.
beforeAll
kail tidak dijamin untuk menjalankan sebelum semua tes dikumpulkan. Sebenarnya, itu sangat mungkin hanya berjalan setelahnya, tetapi dalam kasus assuming(someAssumption)
ini sudah akan menerima nilai awal (tidak ditentukan). Dibutuhkan untuk membungkus bagian itu dalam suatu fungsi juga untuk mencapai efek yang diinginkan.
Kita dapat menulis fungsi pembungkus bersih yang bagus untuk menjalankan tes bersyarat sebagai berikut:
function ifConditionIt(title, test) {
// Define your condition here
return condition ? it(title, test) : it.skip(title, test);
}
Ini kemudian dapat diminta dan digunakan dalam pengujian Anda sebagai berikut:
ifConditionIt('Should be an awesome test', (done) => {
// Test things
done();
});
Katakanlah saya ingin melewati tes parametrized saya jika deskripsi tes saya berisi string "foo", saya akan melakukan ini:
// 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
});
});
Dalam kasus Anda, saya percaya bahwa jika Anda ingin memeriksa variabel lingkungan, Anda bisa menggunakan NodeJS:
process.env.ENV_VARIABLE
Misalnya (Peringatan: Saya belum menguji sedikit kode ini!), Mungkin kira-kira seperti ini:
(process.env.NODE_ENV.indexOf("prod") === -1 ? it : it.skip)("should...", function(done) {
// Code here
});
Di mana Anda dapat menetapkan ENV_VARIABLE menjadi apa pun yang Anda pilih, dan menggunakan nilai itu, lewati atau jalankan pengujian. (FYI dokumentasi untuk proses.env NodeJS ada di sini: https://nodejs.org/api/process.html#process_process_env )
Saya tidak akan mengambil kredit lengkap untuk bagian pertama dari solusi ini, saya menemukan dan menguji jawabannya dan bekerja sempurna untuk melewati tes berdasarkan kondisi sederhana melalui sumber daya ini: https://github.com/mochajs/mocha/issues / 591
Semoga ini membantu! :)
Ini tidak benar-benar menggunakan fitur mocha, melainkan men-tweak untuk mendapatkan perilaku yang saya inginkan.
Saya ingin melewati setiap 'itu' berikutnya dalam tes mocha busur derajat saya dan satu 'itu' gagal. Ini karena begitu satu langkah tes perjalanan gagal, hampir pasti sisanya akan gagal, dan mungkin memakan waktu lama dan memakan server build jika mereka menggunakan browser menunggu elemen muncul di halaman, dll.
Ketika hanya menjalankan tes moka standar (bukan busur derajat) ini dapat dicapai dengan kait global sebelum dan setiap kait dengan melampirkan bendera 'lewati' ke induk tes (jelaskan) seperti ini:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
Ketika mencoba ini dengan busur derajat dan moka itu ruang lingkup 'ini' telah berubah dan kode di atas tidak berfungsi. Anda berakhir dengan pesan kesalahan seperti 'panggilan kesalahan dilakukan ()' dan berhenti busur derajat.
Sebaliknya saya berakhir dengan kode di bawah ini. Bukan yang tercantik, tetapi akhirnya menggantikan penerapan fungsi tes yang tersisa dengan this.skip (). Ini mungkin akan berhenti berfungsi jika / ketika internal mocha berubah dengan versi yang lebih baru.
Itu ditemukan melalui beberapa percobaan dan kesalahan dengan men-debug dan memeriksa internal mocha ... membantu membuat suite tes browser selesai lebih cepat ketika tes gagal.
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'
}
});
mocha test/ --grep <pattern>
Sebagai @danielstjules menjawab di sini ada cara untuk melewati tes. @author dari topik ini telah menyalin jawaban dari diskusi mochajs github.com, tetapi tidak ada info dalam versi mocha apa yang tersedia.
Saya menggunakan modul grunt-mocha-test untuk mengintegrasikan fungsionalitas tes mocha dalam proyek saya. Melompat ke versi terakhir (untuk sekarang) - 0.12.7 bawakan saya mocha versi 2.4.5 dengan implementasi this.skip ().
Jadi, di package.json saya
"devDependencies": {
"grunt-mocha-test": "^0.12.7",
...
Lalu
npm install
Dan itu membuat saya senang dengan kait ini:
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();
}
...
Tolong jangan. Tes yang tidak bekerja secara konsisten di seluruh lingkungan harus diakui seperti itu oleh infrastruktur bangunan Anda. Dan itu bisa sangat membingungkan ketika CI membangun memiliki jumlah tes yang berbeda dari lokal.
Itu juga mengacaukan pengulangan. Jika tes yang berbeda berjalan di server dan lokal saya dapat memiliki tes gagal di dev dan lulus di CI atau sebaliknya. Tidak ada fungsi pemaksaan dan saya tidak memiliki cara untuk dengan cepat dan akurat memperbaiki bangunan yang gagal.
Jika Anda harus mematikan tes di antara lingkungan, alih-alih menjalankan pengujian secara kondisional, beri tag pada pengujian Anda dan gunakan filter untuk menghilangkan tes yang tidak berfungsi pada target build tertentu. Dengan begitu semua orang tahu apa yang terjadi dan itu sesuai dengan harapan mereka. Ini juga membuat semua orang tahu bahwa ada ketidakkonsistenan dalam kerangka pengujian, dan seseorang mungkin memiliki solusi yang membuat mereka berjalan dengan baik lagi. Jika Anda hanya menonaktifkan tes, mereka mungkin tidak tahu ada masalah.
this.skip()
dalam mochajs.org/#inclusive-tests dan jawaban @ zatziky di bawah ini. Sisa jawaban sudah usang untuk Mocha v3 +