只有在Jasmine测试失败时才可以做某事吗?与afterEach()
并列,无论结果如何都在it()
之后执行,我只是在it()
期望失败后才寻找执行代码的方法。
这个问题不是Angular特有的,但在我的场景中,我正在测试Angular服务,它使用$log
输出调试消息。我不想让我的控制台混乱以获得成功的测试,但只显示失败测试的附加信息。
describe("MyService", function() {
var MyService, $log;
beforeEach(function() {
inject(function (_MyService_, _$log_) {
MyService = _MyService_;
$log = _$log_;
});
});
afterEach(function () {
if (/* test failed */) {
//console.log($log.debug.logs);
}
});
it("should output debug logs when this fails", function() {
//do something with MyService that would put a message in $log
expect(false).toBe(true);
});
});
我正在运行Jasmine 2.2.0。
编辑:here是一个非常简单的小提琴,显示Jasmine 1.3 jasmine.getEnv().currentSpec
解决方案不再有效。
答案 0 :(得分:8)
这是在Jasmine 2中重新启用jasmine.getEnv().currentSpec
的黑客攻击(result
不是完整的spec
对象,而是包含id
,{{1 }},description
,fullName
和failedExpectations
):
passedExpectations
答案 1 :(得分:4)
我终于弄清楚如何使用Jasmine 2.3.4获取对失败规范结果的引用,但我不确定它是否正是您正在寻找的内容
我使用随Jasmine设置一起安装的vanilla PlayerSpec.js文件。我运行了SpecRunner.html文件来执行测试。
以下是我在PlayerSpec文件中更改的内容:
describe("Player", function() {
var player;
var song;
var index = 0;
beforeEach(function() {
player = new Player();
song = new Song();
this.index = index++;
});
afterEach(function() {
if (this.index > 0)
{ var failed = jsApiReporter.specResults(this.index -1, 1)[0].failedExpectations;
console.log('failed: ', failed);
if (failed.length > 0)
{
console.log('After: ', this, failed[0].message);
alert('ha');
}
}
});
it("should not fail", function()
{ expect(1).toEqual(2);
});
...
文件的其余部分与原来的相同。
以下是我改变的内容:
添加了一个索引变量来跟踪当前的规格编号。
在beforeEach函数中,我将索引值添加到" this"在it,beforeEach和afterEach函数之间传递的对象。这允许我根据需要在它们之间进行通信。我只使用这种机制来传递索引。谨防!如果您只是尝试使用索引值,它就不会起作用!这些函数是异步处理的,所以索引值很可能不是你在afterEach函数中所期望的那样。
在afterEach函数中,我检查以确保索引大于0.在我的本地测试中,第一个规范失败,但直到第二次调用afterEach时才能识别。这是我不确定这会使你想要的原因之一。然后,我获取对failedExpectations的引用,并在识别出错误时进行一些条件处理。
最后一次更改是添加了一个会导致失败的新规范。
这是我的FireBug控制台结果的糟糕副本:
failed: [Object { matcherName="toEqual", message="Expected 1 to equal 2.", stack="stack@http://localhost:4...ne-2.3.4/boot.js:110:5\n", more...}]
PlayerSpec.js (line 15)
After: Object { index=1} Expected 1 to equal 2.
PlayerSpec.js (line 18)
failed: []
PlayerSpec.js (line 15)
failed: []
PlayerSpec.js (line 15)
failed: []
PlayerSpec.js (line 15)
failed: []
PlayerSpec.js (line 15)
这个问题一直是我的旅程。可悲的是,我必须转向其他事情。
我真诚地希望这可以解决您的问题,或者至少指出您正确的方向。希望它也会帮助其他人。
祝你好运!
答案 2 :(得分:1)
我还在使用Jasmine 1.2,所以在Jasmine 2.0中可能会有所不同。
在afterEach函数中,您应该能够使用以下命令访问刚刚完成的当前规范:
var currentSpec = jasmine.getEnv().currentSpec;
这将返回一个具有许多属性的对象。其中之一是传递了多少嵌入式测试(results_.passedCount)。
您可以针对该值进行测试并适当地执行日志记录。
祝你好运!答案 3 :(得分:0)
我想在jasmine 2.5.2上做类似的事情(拥有自定义记录器对象,只有在测试失败时才会打印出来,而不必手动执行)。
为了让它在每次/每次之后都能正常工作而挣扎了很多,最后我陷入了一个更丑陋的解决方案
// logger print on fail
function collectSpecs(suite: jasmine.Suite): jasmine.Spec[] {
const result: jasmine.Spec[] = [];
const process = [suite];
while (process.length) {
const suite = process.pop();
const children = <jasmine.SuiteOrSpec[]> <any> suite.children; // wrong jasmine typing
children.forEach(item => {
switch (item.constructor.name) {
case "Suite":
process.push(<jasmine.Suite>item);
break;
case "Spec":
result.push(<jasmine.Spec>item);
break;
}
});
}
return result;
}
function findSpec(specId: string): jasmine.Spec {
const rootSuite: jasmine.Suite = jasmine.getEnv()["topSuite"]();
return collectSpecs(rootSuite)
.filter(s => `${s.id}` === specId)[0]; // wrong jasmine typing on id
}
const loggerSpecProperty = "logger";
function createReporter(): jasmine.CustomReporter {
return {
specDone: (result: jasmine.CustomReporterResult) => {
const spec = findSpec(result.id);
if (result.failedExpectations.length) {
const logger: modLog.MemoryLogger = spec[loggerSpecProperty];
if (logger) {
console.log(`\nfailed spec logger:\n${logger.lines.join("\n")}`);
}
}
delete spec[loggerSpecProperty];
}
};
}
export function registerReporter(): void {
jasmine.getEnv().addReporter(createReporter());
}
function createLogger(): modLog.MemoryLogger {
return new modLog.MemoryLogger(modLog.LogLevel.debug);
}
interface IItCallback {
(done?: Function): void;
}
interface IItFunctionTyping {
(name: string, callback: IItCallback): void;
}
interface IItFunction {
(name: string, callback: IItCallback): jasmine.Spec;
}
// bad typings on it/xit/fit, actually returns Spec but is typed as void
export function lit(fnIt: IItFunctionTyping, name: string, callback: IItCallback): jasmine.Spec {
function inner(spec: jasmine.Spec, done?: Function) {
const log = createLogger();
this.log = log;
spec[loggerSpecProperty] = log;
callback.call(this, done);
}
const itFunc = <IItFunction> (fnIt || it);
if (callback.length) {
const spec = itFunc(name, function (done) {
inner.call(this, spec, done);
});
return spec;
} else {
const spec = itFunc(name, function () {
inner.call(this, spec);
});
return spec;
}
}
由于@ types / jasmine隐藏了实际实现的一些细节(我认为它是故意的,输入版本与jasmine包版本相匹配),但是我还想练习我的TypeScript ,因为某些不必要的类型mumbo jumbo
传递“it”函数以在需要时仍然允许xit / fit modLog是我的记录器模块,覆盖它以满足您的需求
用法:
而不是
it("should do something", function (done) {
done();
});
使用
lit(it, "should do something", function (done) {
this.log.debug("test");
fail("test output");
done();
});
(记录不是很好,但我认为你可以得到图片)
如果有一种方法可以让customReporter访问规范上下文
,那就更好了(然后这一切基本上只是为了调试目的,你也可以将console.log添加到特定的测试中,当它失败并且你正在努力解决细节时,但是对于了解一点茉莉花是有趣的练习更多)