ฉันมีรหัสที่การทดสอบบางอย่างจะล้มเหลวในสภาพแวดล้อม CI เสมอ ฉันต้องการปิดการใช้งานพวกเขาตามสภาพแวดล้อม
วิธีการข้ามการทดสอบโดยทางโปรแกรมในมอคค่าในระหว่างการดำเนินการรันไทม์?
ฉันมีรหัสที่การทดสอบบางอย่างจะล้มเหลวในสภาพแวดล้อม CI เสมอ ฉันต้องการปิดการใช้งานพวกเขาตามสภาพแวดล้อม
วิธีการข้ามการทดสอบโดยทางโปรแกรมในมอคค่าในระหว่างการดำเนินการรันไทม์?
คำตอบ:
คุณสามารถข้ามการทดสอบโดยวาง 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,
}
}
}
beforeEach
รันโทร Mocha บันทึกฟังก์ชั่นที่ไม่ระบุชื่อ (ที่ "เบ็ด") สำหรับอนาคตการใช้งานเมื่อdescribe
รันโทร Mocha ทันทีรันฟังก์ชั่นที่ไม่ระบุชื่อผ่านไป ดังนั้นเมื่อถึงเวลาที่if (runTest)
กำหนดbeforeEach
เบ็ดจะไม่ทำงาน
มีวิธีที่ไม่มีเอกสารของการทดสอบข้ามโปรแกรม:
// 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
describe
เป็นการข้ามทั้งหมด(เช่นการทดสอบทั้งหมดในนั้นdescribe
ถูกข้ามไป)
คำตอบนี้ไม่ทำงานสำหรับ ES6
แทน:
describe('your describe block', () => {
คุณต้องการ:
(condition ? describe : describe.skip)('your describe block', () => {
นี่เป็นการข้ามการทดสอบทั้งหมดในบล็อกอธิบายหากเงื่อนไขเป็นเท็จ
หรือแทน:
it('your it block', () => {
คุณต้องการ:
(condition ? it : it.skip)('your it block', () => {
การทำแบบนี้จะข้ามการทดสอบหนึ่งเงื่อนไขหากเงื่อนไขเป็นเท็จ
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
จากนั้นคุณสามารถใช้มันได้: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
ฉันใช้การข้ามรันไทม์จาก 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')
สภาพของตัวเองของฉันคือ
if (/* skipTestCondition */) return this.skip();
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
ขึ้นอยู่กับวิธีที่คุณต้องการข้ามการทดสอบโดยทางโปรแกรม หากสามารถกำหนดเงื่อนไขสำหรับการข้ามได้ก่อนที่จะเรียกใช้รหัสทดสอบใด ๆ คุณสามารถโทร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!");
});
});
ในขณะที่ตัวอย่างแรกของฉันทำเครื่องหมายการทดสอบว่าข้ามอย่างเป็นทางการ (aka "รอดำเนินการ") วิธีที่ฉันเพิ่งแสดงจะหลีกเลี่ยงการทดสอบจริง แต่การทดสอบจะไม่ถูกทำเครื่องหมายว่าข้ามอย่างเป็นทางการ พวกเขาจะถูกทำเครื่องหมายว่าผ่าน หากคุณต้องการให้ข้ามไปจริง ๆ ฉันไม่ทราบวิธีการเข้าถึงส่วนที่ไม่ถูกต้องซึ่งเป็นส่วนหนึ่งของ 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!");
});
});
ฉันไม่แน่ใจว่าสิ่งนี้มีคุณสมบัติเป็น "การข้ามทางโปรแกรม" แต่เพื่อที่จะเลือกข้ามการทดสอบบางอย่างสำหรับสภาพแวดล้อม CI ของเราฉันใช้คุณลักษณะการติดแท็กของ Mocha ( https://github.com/mochajs/mocha/wiki/Tagging ) ในdescribe()
หรือit()
ข้อความคุณสามารถเพิ่มแท็กเช่น @ no-ci หากต้องการยกเว้นการทดสอบเหล่านั้นคุณสามารถกำหนด "ci เป้าหมาย" เฉพาะใน package.json ของคุณและใช้--grep
และ--invert
พารามิเตอร์เช่น:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
คุณสามารถใช้มอคค่าแพ็คเกจของฉันเพื่อข้ามการทดสอบโดยทางโปรแกรม แต่จากภายนอกการทดสอบเท่านั้น คุณใช้มันแบบนี้:
assuming(myAssumption).it("does someting nice", () => {});
มอคค่า - สมมติว่าจะเรียกใช้การทดสอบของคุณเมื่อmyAssumption
เป็น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"
จะล้มเหลวเสมอเมื่อบางคนไม่ได้มีการสรุป - แต่ข้อสันนิษฐานนี้ได้ผ่านการทดสอบด้านบนแล้ว (เป็นTests that verify someAssuption is always true"
)
ดังนั้นความล้มเหลวในการทดสอบจึงไม่ให้ข้อมูลใหม่แก่คุณ ในความเป็นจริงมันเป็นเท็จบวก: การทดสอบไม่ได้ล้มเหลวเพราะ "สิ่งที่เจ๋ง" ไม่ได้ผล แต่เป็นเพราะเงื่อนไขเบื้องต้นสำหรับการทดสอบไม่เป็นที่พอใจ กับmocha-assume
คุณมักจะสามารถหลีกเลี่ยงการบวกเท็จเช่น
beforeAll
เบ็ดไม่รับประกันว่าจะทำงานก่อนการทดสอบทั้งหมดจะถูกเก็บรวบรวม ที่จริงแล้วมีโอกาสมากที่จะเรียกใช้หลังจากนั้น แต่ในกรณีนี้assuming(someAssumption)
จะได้รับค่าเริ่มต้น (ไม่ได้กำหนด) ไว้แล้ว มันจำเป็นต้องห่อส่วนนั้นไว้ในฟังก์ชั่นด้วยเพื่อให้ได้เอฟเฟกต์ที่ต้องการ
เราสามารถเขียนฟังก์ชั่น wrapper ที่สะอาดเพื่อทำการทดสอบตามเงื่อนไขดังนี้
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();
});
สมมติว่าฉันต้องการข้ามการทดสอบแบบมีพารามิเตอร์ถ้าคำอธิบายการทดสอบของฉันมีสตริง "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 ให้เป็นทุกอย่างที่คุณปิดคีย์และใช้ค่านั้นข้ามหรือเรียกใช้การทดสอบ (FYI เอกสารสำหรับกระบวนการ NodeJS 'process.env อยู่ที่นี่: https://nodejs.org/api/process.html#process_process_env )
ฉันจะไม่ได้รับเครดิตที่สมบูรณ์สำหรับส่วนแรกของโซลูชันนี้ฉันพบและทดสอบคำตอบและทำงานได้อย่างสมบูรณ์ในการข้ามการทดสอบตามเงื่อนไขง่ายๆผ่านทรัพยากรนี้: https://github.com/mochajs/mocha/issues / 591
หวังว่านี่จะช่วยได้! :)
สิ่งนี้ไม่ได้ใช้คุณสมบัติของมอคค่าแทนการปรับแต่งเพื่อให้ได้พฤติกรรมที่ฉันต้องการ
ฉันต้องการข้ามสิ่งต่อไปนี้ 'ใน' ในการทดสอบมอคค่าไม้โปรแทรกเตอร์ของฉันและหนึ่ง 'มัน' ล้มเหลว นี่เป็นเพราะเมื่อขั้นตอนหนึ่งของการทดสอบการเดินทางล้มเหลวก็เกือบจะแน่ใจว่าส่วนที่เหลือจะล้มเหลวและอาจใช้เวลานานและหมูตัวเซิร์ฟเวอร์สร้างหากพวกเขากำลังใช้เบราว์เซอร์รอให้องค์ประกอบปรากฏบนหน้าเว็บ ฯลฯ
เมื่อเรียกใช้การทดสอบมอคค่ามาตรฐาน (ไม่ใช่ไม้โปรแทรกเตอร์) สิ่งนี้สามารถเกิดขึ้นได้กับโกลบอล beforeEach และ afterEach โดยการแนบแฟล็ก 'skipSubsequent' เข้ากับพาเรนต์ของการทดสอบ (อธิบาย) ดังนี้:
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
เมื่อพยายามทำเช่นนี้กับไม้โปรแทรกเตอร์และมอคค่าขอบเขตของ 'this' จะเปลี่ยนไปและโค้ดข้างต้นไม่ทำงาน คุณท้ายด้วยข้อความแสดงข้อผิดพลาดเช่น 'การโทรผิดพลาดเสร็จสิ้น ()' และไม้โปรแทรกเตอร์หยุดทำงาน
แต่ฉันลงเอยด้วยรหัสด้านล่าง ไม่ใช่ที่สวยที่สุด แต่มันกลับมาแทนที่การใช้งานฟังก์ชั่นการทดสอบที่เหลือด้วย this.skip () นี่อาจจะหยุดทำงานถ้า / เมื่อ internals ของ mocha เปลี่ยนเป็นรุ่นที่ใหม่กว่า
มันถูกค้นพบด้วยการลองผิดลองถูกโดยการดีบั๊กและตรวจสอบภายในของมอคค่า ... ช่วยให้ชุดทดสอบเบราว์เซอร์เสร็จสมบูรณ์เร็วขึ้นเมื่อการทดสอบล้มเหลว
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>
As @danielstjules ตอบที่นี่มีวิธีที่จะข้ามการทดสอบ @ อนุญาตของหัวข้อนี้ได้คัดลอกคำตอบจากการอภิปราย github.com mochajs แต่ไม่มีข้อมูลใดในมอคค่ารุ่นใด
ฉันใช้โมดูล grunt-mocha-test สำหรับการรวมฟังก์ชั่นการทดสอบ mocha ในโครงการของฉัน ข้ามไปยังรุ่นล่าสุด (สำหรับตอนนี้) - 0.12.7 นำมอคค่าเวอร์ชัน 2.4.5 มาให้ฉันด้วยการใช้ this.skip ()
ดังนั้นใน 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();
}
...
โปรดอย่า การทดสอบที่ไม่ทำงานอย่างสม่ำเสมอในสภาพแวดล้อมต่างๆควรได้รับการยอมรับเช่นนี้โดยโครงสร้างพื้นฐานของการสร้าง และมันอาจทำให้สับสนได้มากเมื่อ CI builds มีจำนวนการทดสอบที่แตกต่างจากในท้องถิ่น
อีกทั้งยังเพิ่มความสามารถในการทำซ้ำ หากการทดสอบที่แตกต่างกันทำงานบนเซิร์ฟเวอร์และท้องถิ่นฉันสามารถมีการทดสอบที่ล้มเหลวในการพัฒนาและผ่านใน CI หรือในทางกลับกัน ไม่มีฟังก์ชั่นบังคับและฉันไม่มีวิธีแก้ไขการสร้างที่ล้มเหลวได้อย่างรวดเร็วและแม่นยำ
หากคุณต้องปิดการทดสอบระหว่างสภาพแวดล้อมแทนที่จะใช้การทดสอบแบบมีเงื่อนไขติดแท็กการทดสอบของคุณและใช้ตัวกรองเพื่อกำจัดการทดสอบที่ไม่ทำงานในเป้าหมายการสร้างที่แน่นอน วิธีนี้ทำให้ทุกคนรู้ว่าเกิดอะไรขึ้นและทำให้ความคาดหวังของพวกเขาแย่ลง นอกจากนี้ยังช่วยให้ทุกคนรู้ว่ามีความไม่สอดคล้องกันในกรอบการทดสอบและบางคนอาจมีทางออกที่ทำให้พวกเขาทำงานได้อย่างถูกต้องอีกครั้ง หากคุณปิดเสียงการทดสอบพวกเขาอาจไม่รู้ด้วยซ้ำว่ามีปัญหา
this.skip()
อยู่ในmochajs.org/#inclusive-testsและคำตอบ @ zatziky ของด้านล่าง คำตอบที่เหลือนั้นล้าสมัยสำหรับ Mocha v3 +