我正在使用硒开发一个端到端的测试套件,其中的测试用例是使用笑话测试运行程序以JavaScript编写的。
我的问题是,当某事不起作用时,硒经常会毫不客气地失败,而对失败的原因几乎没有解释。不用说,调试这样的测试可能非常困难。
我正在寻找一种记录每个测试用例的方式,以便我知道测试失败的地方,但是仅在测试实际失败时才在测试输出中显示这些日志(以免污染测试的控制台输出有很多不必要的日志)。
所以我想做类似的事情:
var query = app.models.company.newQuery(); // Should this not be models.company.newQuery as there is no datasource named "carcompanies" ?
query.prefetch.autos._add();
var results = query.run();
var calculatedRecords = []; //contained a capitalization error here
results.forEach(function(company) {
var totals = {wholesale:0, retail:0, profit:0};
var records = company.autos;
records.forEach(function(item) {
totals.wholesale += item.wholesale;
totals.retail += item.retail;
totals.profit += (item.retail - item.wholesale);
});
var record = app.models.totals.newRecord();
record.Company = company.name;
record.wholesale = totals.wholesale;
record.retail = totals.retail;
record.profit = totals.profit;
calculatedRecords.push(record);
});
return calculatedRecords;
因此,如果#change order of columns for change ordering of final value column
df = df[df.columns[::-1]]
#reshape by stack
df = (df.set_index('Node')
.stack()
.rename_axis(('Node','num1'))
.astype(int)
.reset_index(name='num2'))
#get last non NaN value to num1 column
df['num1'] = df.groupby('Node')['num2'].transform('first')
#remove last row per groups
df = df[df.duplicated(subset=['Node'])].copy()
print (df)
Node num1 num2
1 YYZ 3 2
2 YYZ 3 1
4 DFW 7 6
5 DFW 7 5
6 DFW 7 4
8 DEN 21 20
10 BOS 106 105
11 BOS 106 104
12 BOS 106 103
13 BOS 106 102
14 BOS 106 101
15 BOS 106 100
中的测试失败并且describe(() => {
it('case 1', async () => {
// this log should only be printed on the console if this test fails
logger.info('message from case 1');
// ...
});
it('case 2', () => {
logger.info('message from case 2');
// ...
});
});
没有失败,那么我会在控制台输出中看到case 1
(最好是在该测试用例的错误之前),并且< em> not case 2
。
开玩笑有可能吗?我可以随意使用任何日志记录库。
答案 0 :(得分:6)
我遇到了同样的问题,无法找到确定的解决方案。看来it's low on Facebook's to do list是个解决方法。 它使用的是我发现的here和here代码段。 这个想法是,在每次玩笑之前,您都要设置一个消息存储区并全局覆盖控制台,以将所有日志记录转移到该消息存储区。 每次测试之后,您都要检查该测试是否失败,如果失败,请打印出隐藏的消息。
package.json :
start-btn
setup.js :
"jest": {
...
"verbose": true,
"setupFilesAfterEnv": ["<rootDir>/test/setup.js"],
...
}
如果需要执行其他任何清理操作,则可以像这样在测试文件中的“每次”之后“扩展”:
some.test.js
const util = require('util')
global.consoleMessages = []
// get information about the current test
jasmine.getEnv().addReporter({
specStarted: result => jasmine.currentTest = result,
specDone: result => jasmine.currentTest = result,
})
function squirrelAway(text, logger) {
// use error to get stack trace
try {
throw new Error('stacktrace')
} catch (err) {
let trace = err.stack.split('\n')
trace.shift() // removes Error: stacktrace
trace.shift() // removes squirrelAway() call from the "throw" command
trace.shift() // removes console logger call in the console override
consoleMessages.push({logger: logger, payload: text, stacktrace: trace.join('\n')})
}
}
const orig = console
global.console = {...console,
// use jest.fn() to silence, comment out to leave as it is
log: (text => squirrelAway(text, orig.log)),
error: (text => squirrelAway(text, orig.error)),
warn: (text => squirrelAway(text, orig.warn)),
info: (text => squirrelAway(text, orig.info)),
debug: (text => squirrelAway(text, orig.debug))
}
global.afterEach(() => {
// this includes tests that got aborted, ran into errors etc.
let failed = (jasmine && jasmine.currentTest
&& Array.isArray(jasmine.currentTest.failedExpectations)) ?
jasmine.currentTest.failedExpectations.length>0 : true
//orig.log(`test "${jasmine.currentTest.fullName}" finished. failed? ${failed}`)
if (failed) {
//orig.log(`Logging for "${jasmine.currentTest.fullName}" start`)
consoleMessages.forEach(msg => {
if (typeof msg.payload === 'object' || typeof msg.payload === 'function') {
msg.payload = util.inspect(msg.payload, false, null, true)
}
msg.logger.call(msg.logger, msg.payload + '\n' + msg.stacktrace)
})
//orig.log(`Logging for "${jasmine.currentTest.fullName}" end`)
}
consoleMessages = []
})
缺点:
答案 1 :(得分:1)
有多种方法可以让您的expect
调用变得棘手,让您知道发生故障的位置。这样的东西有用吗?
const location = "case 1 failed";
const result = someFunction();
expect({result: result, location}).toEqual({result: "hello", location});
现在,如果someFunction()
返回的值不是“ hello”,它会告诉您位置值,因为它抱怨期望的值。
仅当您遇到Jest错误,但没有从正常的expect
故障消息中获取足够的信息并且您需要更多详细信息时,这才真正有用。
答案 2 :(得分:0)
测试环境很好地处理了这个问题。它缓冲所有控制台消息,按测试对它们进行分组,并且仅在测试失败时才显示它们。环境与设置文件或报告程序的好处在于,它可以有选择地应用于特定测试,而将全局控制台留给所有其他人。
./tests/testEnvironment.js
const NodeEnvironment = require('jest-environment-node');
const colors = require('colors');
class TestEnvironment extends NodeEnvironment {
constructor(config, context) {
super(config, context);
}
async setup() {
await super.setup();
this.global.consoleItems = [];
this.global.console = { ...console,
original: console,
log: ((message) => this.global.consoleItems.push({type: 'log', message })),
error: ((message) => this.global.consoleItems.push({type: 'error', message })),
warn: ((message) => this.global.consoleItems.push({type: 'warn', message })),
info: ((message) => this.global.consoleItems.push({type: 'info', message })),
debug: ((message) => this.global.consoleItems.push({type: 'debug', message })),
};
}
async teardown() {
this.global.console = this.global.console.original;
await super.teardown();
}
async handleTestEvent(event, state) {
if (event.name === 'test_done' && event.test.errors.length > 0) {
let test = event.test;
let fullTestName = event.test.name;
while (test.parent != null && test.parent.name !== 'ROOT_DESCRIBE_BLOCK') {
fullTestName = test.parent.name + ' › ' + fullTestName;
test = test.parent;
}
this.global.console.original.log(colors.bold.red('Console messages for failed test ' + fullTestName));
this.global.consoleItems.forEach((item) => {
if (item.type === 'log') {
this.global.console.original.log(' - ' + item.message);
} else if (item.type === 'error') {
this.global.console.original.error(' - ' + item.message);
} else if (item.type === 'warn') {
this.global.console.original.warn(' - ' + item.message);
} else if (item.type === 'info') {
this.global.console.original.info(' - ' + item.message);
} else if (item.type === 'debug') {
this.global.console.original.debug(' - ' + item.message);
}
});
this.global.console.original.log('\n');
}
if (event.name === 'test_done') {
this.global.consoleItems = [];
}
}
}
module.exports = TestEnvironment;
对于每个测试套件,使用此环境需要以下注释:
/**
* @jest-environment ./tests/testEnvironment
*/
答案 3 :(得分:0)
这可能是不好的做法,但我注意到 expect().toBe()
或其他东西如果不相等会抛出错误,您可以先捕获它并记录它。
这是我尝试测试每条短信是否都有翻译语言时的示例代码。
test('All message has translate', () => {
allAvailableText.forEach((key) => {
const languagesOnTheKey = Object.keys(text[key]).sort()
try {
expect(languagesOnTheKey).toStrictEqual(languages)
} catch (error) {
console.log(key, languagesOnTheKey)
}
expect(languagesOnTheKey).toStrictEqual(languages)
})
})
这只是最快的方法,对我来说也最容易阅读,因为选择的答案让我很难理解。