我应该在测试用例中使用 try-catch 吗?
Should I use try-catch in test case?
我在想一个问题。这是一个示例:
index.ts
async function getUserById(id?: number) {
return new Promise((resolve, reject) => {
if (id) {
const user = { id };
resolve(user);
} else {
reject(new Error('user id is required'));
}
});
}
export { getUserById };
index.spec.ts
:
import { getUserById } from './';
const coin = () => Math.random() > 0.5;
describe('should throw an error test suites', () => {
const testCount = 1000;
for (let i = 0; i < testCount; i++) {
it(`t-${i}`, async () => {
const id = coin() ? 1 : 0;
try {
const user = await getUserById(id);
expect(user).toEqual({ id });
} catch (error) {
expect(error.message).toBe('user id is required');
}
});
}
});
测试结果:
Test Suites: 1 passed, 1 total
Tests: 1000 passed, 1000 total
Snapshots: 0 total
Time: 2.637s
如您所见,我动态生成了很多测试用例。问题是在这种情况下测试用例总是会通过。我认为将 correct
部分和 exception
部分一起测试是不正确的。我说得对吗?
什么时候应该在测试用例中使用 try-catch
?
谢谢。
如果您正在测试您的应用程序是否在给定时间抛出预期的异常,您应该使用 try-catch 块来触发异常并对其进行评估。
我认为您不能说除此之外还有何时使用它们的任何规则集。当然,这取决于您的目标和您的编码风格,但是我们正在接近一个基于意见的答案,这对于这个网站来说有点偏离主题;-)
在测试代码中使用 try-catch
本身不是问题。事实上,如果在您的测试代码中您想要验证被测系统 (SUT) 是否按预期抛出预期,您甚至需要这样做。
但是,您的特定示例在测试代码中做了一些具有不利后果的事情。一件事是您的测试代码将两个不同方面(成功场景和失败场景)的测试合并到一个测试函数中。缺点之一是,这会使测试代码复杂化,并且有时很难理解哪个设置部分对于哪个测试是必需的。您使用 try-catch
来合并测试,但问题不是 try-catch
,而是合并。
而且,事实上,这种合并实际上将您引入了一个陷阱:您的合并测试无法正常工作。例如,您随机 select 一个 id
。 id
为 1 应该会导致传送正确的 user
。但是,您并没有真正测试:如果您的 SUT 错误地 总是 抛出异常,您将认为这是一个成功的测试。
其次,您 运行 进行了 1000 次测试,但实际上只测试了两个场景(方面)。因此,1000 次测试不会给您带来任何好处。恰恰相反:额外的复杂性甚至可能意味着您错误地(因为场景 selection 中的错误)没有测试这两种场景。或者,巧合的是总是选择一个场景(不太可能,承认)。无论如何,您浪费时间执行 1000 次测试,而仅测试了 2 个方面的有效值。
我在想一个问题。这是一个示例:
index.ts
async function getUserById(id?: number) {
return new Promise((resolve, reject) => {
if (id) {
const user = { id };
resolve(user);
} else {
reject(new Error('user id is required'));
}
});
}
export { getUserById };
index.spec.ts
:
import { getUserById } from './';
const coin = () => Math.random() > 0.5;
describe('should throw an error test suites', () => {
const testCount = 1000;
for (let i = 0; i < testCount; i++) {
it(`t-${i}`, async () => {
const id = coin() ? 1 : 0;
try {
const user = await getUserById(id);
expect(user).toEqual({ id });
} catch (error) {
expect(error.message).toBe('user id is required');
}
});
}
});
测试结果:
Test Suites: 1 passed, 1 total
Tests: 1000 passed, 1000 total
Snapshots: 0 total
Time: 2.637s
如您所见,我动态生成了很多测试用例。问题是在这种情况下测试用例总是会通过。我认为将 correct
部分和 exception
部分一起测试是不正确的。我说得对吗?
什么时候应该在测试用例中使用 try-catch
?
谢谢。
如果您正在测试您的应用程序是否在给定时间抛出预期的异常,您应该使用 try-catch 块来触发异常并对其进行评估。
我认为您不能说除此之外还有何时使用它们的任何规则集。当然,这取决于您的目标和您的编码风格,但是我们正在接近一个基于意见的答案,这对于这个网站来说有点偏离主题;-)
在测试代码中使用 try-catch
本身不是问题。事实上,如果在您的测试代码中您想要验证被测系统 (SUT) 是否按预期抛出预期,您甚至需要这样做。
但是,您的特定示例在测试代码中做了一些具有不利后果的事情。一件事是您的测试代码将两个不同方面(成功场景和失败场景)的测试合并到一个测试函数中。缺点之一是,这会使测试代码复杂化,并且有时很难理解哪个设置部分对于哪个测试是必需的。您使用 try-catch
来合并测试,但问题不是 try-catch
,而是合并。
而且,事实上,这种合并实际上将您引入了一个陷阱:您的合并测试无法正常工作。例如,您随机 select 一个 id
。 id
为 1 应该会导致传送正确的 user
。但是,您并没有真正测试:如果您的 SUT 错误地 总是 抛出异常,您将认为这是一个成功的测试。
其次,您 运行 进行了 1000 次测试,但实际上只测试了两个场景(方面)。因此,1000 次测试不会给您带来任何好处。恰恰相反:额外的复杂性甚至可能意味着您错误地(因为场景 selection 中的错误)没有测试这两种场景。或者,巧合的是总是选择一个场景(不太可能,承认)。无论如何,您浪费时间执行 1000 次测试,而仅测试了 2 个方面的有效值。