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?
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?
Câu trả lời:
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 .skip
sau 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 .only
bà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 beforeEach
tuyê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,
}
}
}
beforeEach
cuộ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 describe
cuộ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.
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 .
describe
là bỏ qua (tức là tất cả các bài kiểm tra trong describe
được bỏ qua).
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.
const contextualDescribe = shouldAvoidTests ? describe.skip : describe
sau đó bạn có thể sử dụng nó: contextualDescribe('your it block', () => {
(condition ? describe : describe.skip)('your describe block', () => {
(it)('my test', () => {})
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')
.
if (/* skipTestCondition */) return this.skip();
- chỉnh sửa: hoạt động: D
describe.skip
hoặcit.skip
describe('Array', function() {
it.skip('#indexOf', function() {
// ...
});
});
describe.only
hoặcit.only
describe('Array', function() {
it.only('#indexOf', function() {
// ...
});
});
Thêm thông tin tại https://mochajs.org/#inclusive-tests
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 it
hoặc it.skip
khi 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!");
});
});
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
và --invert
các tham số như:
"scripts": {
"test": "mocha",
"test-ci" : "mocha --reporter mocha-junit-reporter --grep @no-ci --invert"
}
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 myAssumption
có true
, 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-assume
bạn thường có thể tránh những dương tính giả như vậy.
beforeAll
mó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.
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();
});
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! :)
Đâ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'
}
});
mocha test/ --grep <pattern>
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();
}
...
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 đề.
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 +