错误处理
当您执行负载测试时,您的被测系统 (SUT) 常常会过载并开始返回错误。在这种情况下,您需要考虑迭代执行应该怎么做
- 接受系统错误并继续执行场景
- 或退出
性能测试人员忘记这些情况并非罕见。我们经常编写脆弱的测试代码,假设系统响应总是成功的并包含预期数据。
import { check, group } from 'k6';
import http from 'k6/http';
export default function () {
group('Fetch a list of pizza names', () => {
const res = http.get('https://quickpizza.grafana.com/api/names');
check(res, {
'is status 200': (r) => r.status === 200,
'got more than 5 crocs': (r) => r.json().length > 5,
});
// ... continue test within the group...
});
group('other group', () => {
//...
});
}
当 SUT 返回正确响应时,此代码将正常工作。但是,当 SUT 开始失败时,r.json().length
将抛出异常
ERRO[0001] cannot parse json due to an error at line 1, character 2 , error: invalid character '<' looking for beginning of value
running at reflect.methodValueCall (native)
在这种情况下,k6 会抛出一个 JavaScript 异常并退出当前迭代的执行,但会继续启动新的迭代。
这可能不是理想情况,因为
- 系统错误作为异常传播,不会在测试结果中报告
- 您可能希望将这些错误视为正常情况并继续执行
重写此测试以减少脆弱性是可能的,但这会使我们的测试代码更长且可读性更差。
异常处理
有时很难预测 SUT 可能会如何失败。对于这些情况,describe 会捕获任何内部异常并
- 将它们记录为失败的断言
- 继续执行(在其
describe()
函数之外)
import { describe, expect } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';
export default function testSuite() {
describe('Test case against a Shaky SUT', (t) => {
throw 'Something entirely unexpected happened';
});
// this test case will be executed because
// the previous `describe` catched the exception
describe('Another test case', (t) => {
expect(2).to.equal(2);
});
}
█ Test case against a Shaky SUT
✗ Exception raised "Something entirely unexpected happened"
↳ 0% — ✓ 0 / ✗ 1
█ Another test case
✓ expected ${this} to equal 2