【发布时间】:2014-04-23 18:00:31
【问题描述】:
有没有办法在 Jasmine expect() 失败时打印自定义错误消息?
例如,对于端到端测试,我有一组网页,我使用一个测试转到每个 URL 并断言每个页面上都存在一个元素。我知道我可以将每个 expect() 放入单独的测试中,但我宁愿遍历数组并在失败时记录页面 URL。
【问题讨论】:
标签: javascript testing jasmine protractor
有没有办法在 Jasmine expect() 失败时打印自定义错误消息?
例如,对于端到端测试,我有一组网页,我使用一个测试转到每个 URL 并断言每个页面上都存在一个元素。我知道我可以将每个 expect() 放入单独的测试中,但我宁愿遍历数组并在失败时记录页面 URL。
【问题讨论】:
标签: javascript testing jasmine protractor
更新
我看到人们仍在寻找这个。 Jasmine 团队后来提供的信息是,expect 中有一个未记录的功能 - 您可以包含自定义失败消息,它就可以正常工作:
expect( fields[i].element.exists() ).toEqual(true, field[i].name + ' is expected to exist');
这正是我最初想要的。
原答案如下:
我今天一直在寻找这个,并在这里发表评论:https://github.com/adobe/brackets/issues/2752
已经讨论过的语法是对 Jasmine 的扩展,允许添加因为 - 所以你可以这样写:
expect( fields[i].element.exists() ).toEqual(true).because( field[i].name + 'is expected to exist');
几年后仍在讨论中,可能不会实现。我发现的另一种方法是创建自定义匹配器。一般来说,我认为我会劝阻自定义匹配器,但不能确保您使用它覆盖所有基础,但在这种情况下,我们实际上是在检查真/假值,所以匹配器并不太可怕。
我们可以使用 beforeEach 创建自定义匹配器:
beforeEach(function() {
var matchers = {
toEqualBecause: function( value, message ) {
this.message = function() {
return "Expected '" + this.actual + "' to equal '" + value + "' because " + message;
};
return this.actual == value;
}
};
this.addMatchers(matchers);
});
然后我们可以使用这个匹配器来发送一条带有我们失败的消息:
expect( field[i].element.exists() ).toEqualBecause( true, field[i].name );
这将给出包括字段名称在内的失败输出:
Expected 'false' to equal 'true' because account_name
【讨论】:
toBe,但不适用于 toEqual
toEqual,尽管它已记录在案。使用toBe,您可以测试在对象上失败的完全相同的值(可能是因为原型部分)所以仍然不适用:(
是的,我们可以在 Jasmine 中的 expect() 失败时打印自定义错误消息。
Code Snippet:
it('print a custom error message when an expect failed', function() {
var elemenToBeDisplayed=element(by.css("userName"));
/*custom error message will be displayed if expected condition
failed*/
expect(elemenToBeDisplayed.isPresent).toBe(true,'Write your custom
error message here');
});
【讨论】:
toEqual。有什么解决办法吗?
Jasmine 3.3 包含 withContext 作为官方支持的方式来指定有关期望的附加信息,而无需担心您使用的是哪个匹配器。
【讨论】:
expect(true).withContext("reason").toBe(false);,我得到了Failed: expect(...).withContext is not a function。任何想法为什么会发生?
reason: Expected true to be false.
从 Jasmine 3.3 开始,有一种方法可以通过 withContext 来实现
例子:
expect(someValue).withContext('expected someValue to be true...').toBe(true)
另见https://github.com/jasmine/jasmine/issues/641#issuecomment-457037665
【讨论】:
expect(true).withContext("reason").toBe(false);,我得到了Failed: expect(...).withContext is not a function。任何想法为什么会发生?
您可以使用fail() 方法来做到这一点。
it('should fail with a message', function() {
if (!foo) fail(`your message here`);
});
【讨论】:
其他答案解释了如何破解“期望”,但还有另一种方法可以解决您的问题,尽管它需要您稍微改变一下思路。与其将“期望”视为您的测试行为,不如将单个“it”调用下的所有期望视为您的测试行为。
我遇到此问题最多的情况是,当我有一个正在执行某种密集解析的函数并且我想编写 20 个几乎相同的测试时。
像这样安排你的输入和输出:
var testDatas = [
{
input: 'stringtoparse1',
output: 'String To Parse 1'
},
{
input: 'stringtoparse2',
output: 'String To Parse 2'
},
{
input: 'stringtoparse3',
output: 'String To Parse 3'
},
];
现在遍历您的测试数据列表,并从 inside 循环中调用“它”,如下所示:
testDatas.forEach(function(test) {
it('should parse for input ' + test.input, function() {
expect(myParser(test.input).toEqual(test.output);
});
});
您可以减少在测试中飞来飞去的无关代码的数量,并且可以为每个期望或一组期望格式化一条消息。
【讨论】:
我需要为 Jasmine 记录自定义消息,我使用了以下方法。
beforeEach(function(){
this.addMatchers({
customError: function(mesg){
this.message= function () {
return mesg;
};
return this.actual == true;
}
});
});
if(<fail condidtion>){
expect(false).customError(<Fail message>)
}
请注意,我上面提到的是 jasmine 1 格式。如果你使用 jasmine 2,会有轻微的变化。 希望对你有帮助
【讨论】:
示例: 我需要在第一次加载时验证页面的颜色。
expect(obj.color).toBe(true, 10000, 'Custom Message');
未来:
【讨论】:
这是我在 Jasmine 2.6.4 中使用的 TypeScript(Visual Studio 中的 Jasmine+Chutzpah)。
通过 NuGet 的最新 Jasmine 版本似乎是 2.6.4,所以我没有“withContext”的东西(它也似乎有点笨拙,我更喜欢在最后标记一条消息像许多其他框架一样的匹配器)。
即使“expectationFailOutput”参数(要显示的消息)出现在 jasmine.d.ts 分型中,它似乎也没有得到 jasmine 的官方支持:
然而,非正式地,它似乎对除 toEqual 匹配器之外的所有对象都有效。
我使用以下内容在全局范围内添加了一个新的 toBeEqualTo 匹配器,我从原始 toEqual 匹配器复制了该匹配器,并将expectationFailOutput 消息添加到末尾。接口声明位允许我们使用 expect(...).toBeEqualTo(...) 而不用 TypeScript 抱怨。
示例用法:
expect(x).toBe(y, "Some Message"); // stock message works with .toBe
expect(x).toEqual(y, "This is ignored"); // stock message ignored with .toEqual
expect(x).toBeEqualTo(y, "My message is displayed"); // new matcher added below
TypeScript 实现:
/// <reference path="../../Scripts/typings/jasmine/jasmine.d.ts"/>
declare namespace jasmine
{
interface Matchers
{
toBeEqualTo(expected: any, expectationFailOutput?: any): boolean;
}
}
beforeEach(function ()
{
jasmine.addMatchers(<any>{
toBeEqualTo: function (util, customEqualityTesters)
{
customEqualityTesters = customEqualityTesters || [];
return {
compare: function (actual, expected, expectationFailOutput)
{
var diffBuilder = (<any>jasmine).DiffBuilder();
return {
pass: util.equals(actual, expected, customEqualityTesters, diffBuilder),
message: diffBuilder.getMessage() + ": " + expectationFailOutput
};
}
};
}
});
});
【讨论】: