我想在 jasmine 2.5.2 上做类似的事情(有自定义记录器对象,只有在测试失败时才会打印出来,而不必手动执行)。
通过 beforeEach/afterEach 进行了相当大的努力使其能够正常工作,最后我屈服于一个更丑陋的解决方案
// 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 包版本匹配),因此出现了一些不必要的类型 mumbo jumbo,但我也想练习我的 TypeScript
传递“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 添加到特定的测试中,当它失败并且你正在为细节而苦恼时,但是了解 jasmine 是很有趣的练习更多)