我有一个代码,其中某些测试将始终在CI环境中失败。我想根据环境条件禁用它们。
如何在运行时执行期间以编程方式跳过mocha中的测试?
答案 0 :(得分:136)
您可以通过在describe或it块前面放置一个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,
}
}
}
答案 1 :(得分:75)
有一种以无记录方式以编程方式跳过测试:
// 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
答案 2 :(得分:28)
此答案适用于ES6 。
而不是:
describe('your describe block', () => {
你想:
(condition ? describe : describe.skip)('your describe block', () => {
如果条件为假,这有条件地跳过描述块中的所有测试。
或者,而不是:
it('your it block', () => {
你想:
(condition ? it : it.skip)('your it block', () => {
如果条件为假,则有条件地跳过一次测试。
答案 3 :(得分:24)
我使用Mocha运行时跳过与您描述的相同的场景。它是docs:
的复制粘贴it('should only test in the correct environment', function() {
if (/* check test environment */) {
// make assertions
} else {
this.skip();
}
});
如您所见,它会根据环境跳过测试。我自己的条件是if(process.env.NODE_ENV === 'continuous-integration')
。
答案 4 :(得分:6)
这取决于您希望以编程方式跳过测试。如果在运行任何测试代码之前可以确定跳过的条件,那么您可以根据条件根据需要调用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!");
});
});
虽然我的第一个例子是将测试标记为正式跳过(又名"待定"),但我刚刚展示的方法将避免执行实际测试,但测试不会被测试被标记为正式跳过。它们将被标记为已通过。如果你绝对想要跳过它们,我不知道如何访问那些没有正确说出测试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!");
});
});
答案 5 :(得分:2)
我们可以编写一个很好的干净包装函数来有条件地运行测试,如下所示:
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();
});
答案 6 :(得分:1)
您可以使用我的包mocha-assume以编程方式跳过测试,但仅限于测试之外。你这样使用它:
assuming(myAssumption).it("does someting nice", () => {});
Mocha-assume只会在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
,您通常可以避免这种误报。
答案 7 :(得分:1)
我不确定这是否属于“程序化跳过”,但为了有选择地跳过我们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"
}
答案 8 :(得分:1)
describe.skip
或it.skip
describe('Array', function() {
describe.skip('#indexOf()', function() {
// ...
});
});
describe.only
describe('Array', function() {
describe.only('#indexOf()', function() {
// ...
});
});
答案 9 :(得分:0)
如果我的测试描述包含字符串“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设置为您正在键入的任何内容,并使用该值跳过或运行测试。 (仅供参考,NodeJS'process.env的文档在这里:https://nodejs.org/api/process.html#process_process_env)
我不会完全赞同这个解决方案的第一部分,我找到并测试了答案,它完美地通过这个资源跳过基于简单条件的测试:https://github.com/mochajs/mocha/issues/591
希望这有帮助! :)
答案 10 :(得分:0)
for j in range(15):
fancycode
k = j % 3
print(k)
答案 11 :(得分:0)
这并不是真的使用摩卡的功能,而是调整它以获得我想要的行为。
我想跳过任何后续的'''在我的量角器摩卡测试和一个'它'失败。这是因为一旦旅程测试的一步失败,几乎可以肯定其余部分会失败,并且如果他们使用浏览器等待元素出现在页面等上,则可能需要很长时间并且占用构建服务器。
当只运行标准的mocha测试(不是量角器)时,可以使用全局的beforeEach和afterEach挂钩来实现,这可以通过附加一个' skipSubsequent'标记为测试的父级(描述),如下所示:
handleClick(event) {
const value = event.currentTarget.value;
this.setState({ touched: value });
}
render() {
return(
<ChildComponent {...this.state} />
)
}
当使用量角器尝试这个时,mocha它的范围是&#39;这个&#39;已更改,上面的代码不起作用。您最终会收到一条错误消息,例如错误调用done()&#39;和量角器停止。
相反,我最终得到了以下代码。不是最漂亮的,但它最终用this.skip()替换剩余测试函数的实现。如果/当mocha的内部与更高版本一起改变时,这可能会停止工作。
通过调试和检查mocha的内部结构,通过一些反复试验得出结论......有助于在测试失败时尽快完成浏览器测试套件。
beforeEach(function() {
if(this.currentTest.parent.skipSubsequent) {
this.skip();
}
});
afterEach(function() {
if (this.currentTest.state === 'failed') {
this.currentTest.parent.skipSubsequent = 'true'
}
})
答案 12 :(得分:0)
可以根据条件使用, 例如,声明一个var,当条件失败时,使用this.skip();
<块引用>注意skip()在箭头函数中不起作用
let shouldRun: boolean;
before(function(){
if ($('#nsErrorIframe').isDisplayed()) {
driver.switchToFrame($('#nsErrorIframe'));
if ($('.ns-error-wrapper').isDisplayed()) {
console.log('PAGE IS NOT AVAILABLE');
shouldRun = false;
if ( shouldRun === false) {
this.skip();
}
}
}
});
答案 13 :(得分:0)
我们在测试环境中有一些不稳定的测试,有时会使用这种方法关闭测试:
mocha --config ./config/parallelrc.cjs --parallel --jobs 3 -- tests/spec/**/index.js -g @flaky -i
我们在tests describe中标记了flaky测试@flaky并设置了特殊的-g
规则,这意味着mocha只运行带有@flaky
标签的测试,接下来使用-i
- 这意味着反转,所以 mocha 只运行测试而不是 @flaky
。
所以,认为它对你有用)
答案 14 :(得分:-2)
由于@danielstjules回答here,有一种方法可以跳过测试。本主题的@author复制了来自github.com mochajs讨论的答案,但没有关于它可用的mocha版本的信息。
我使用grunt-mocha-test模块在我的项目中集成了mocha测试功能。跳到最后(现在)版本 - 0.12.7带来mocha版本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();
}
...
答案 15 :(得分:-3)
请不要。对于环境不一致的测试,您的构建基础架构应该承认这一点。当CI构建具有与本地不同的测试数量时,它可能非常迷惑。
它还会破坏重复性。如果在服务器和本地运行不同的测试,我可以让测试在dev中失败并传入CI,反之亦然。没有强制功能,我无法快速准确地纠正失败的构建。
如果必须在环境之间关闭测试,而不是有条件地运行测试,请标记测试并使用过滤器来消除在某些构建目标中不起作用的测试。这样每个人都知道发生了什么,这会缓和他们的期望。它还让每个人都知道测试框架中存在不一致,并且有人可能有一个解决方案可以让它们再次正常运行。如果你只是将测试静音,他们可能甚至不知道有问题。