【问题标题】:Should I use try-catch in test case?我应该在测试用例中使用 try-catch 吗?
【发布时间】:2019-03-24 02:32:23
【问题描述】:

我在想一个问题。这是一个示例:

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

谢谢。

【问题讨论】:

    标签: unit-testing jasmine mocha.js jestjs


    【解决方案1】:

    在测试代码中使用try-catch 本身不是问题。事实上,如果您想在测试代码中验证被测系统 (SUT) 是否按预期抛出预期,您甚至需要这样做。

    但是,您的特定示例在测试代码中做了一些具有不利后果的事情。一件事是您的测试代码将两个不同方面(成功场景和失败场景)的测试合并到一个测试函数中。缺点之一是,这会使测试代码复杂化,并且有时很难理解设置的哪个部分对于哪个测试是必需的。您使用try-catch 来合并测试,但问题不是try-catch,而是合并。

    而且,事实上,这种合并实际上把你带入了一个陷阱:你的合并测试不能正常工作。例如,您随机选择一个idid 为 1 应该会导致正确的 user 被传递。但是,您并没有真正测试:如果您的 SUT 错误地总是抛出异常,您将认为这是一个成功的测试。

    其次,您运行了 1000 个测试,但实际上只测试了两个场景(方面)。因此,1000 次测试不会给您带来任何好处。恰恰相反:额外的复杂性甚至可能意味着您错误地(由于场景选择中的错误)没有测试两种场景。或者,碰巧总是选择一种情况(不太可能,承认)。在任何情况下,您都浪费时间执行 1000 次测试,以仅测试 2 个方面的有效值。

    【讨论】:

    • 这是否意味着我应该在一个测试用例中测试某个异常部分并在一个新的测试用例中测试正确的部分。不应该在一个测试用例中同时测试它们吗?
    • 是的,这是您的代码的两个不同方面。理想情况下,每个单元测试都应该专注于一个方面。
    • 谢谢。这意味着在测试代码之前,您应该已经知道它是正确的还是错误的?我说的对吗?
    • 在编写测试时,您不会知道测试是否成功,但您当然应该知道测试成功的标准是什么。在您的情况下,如果您使用 id=0 调用代码,则成功标准是抛出异常。如果您使用 id!=0 调用代码,则成功标准是返回具有该 id 的用户(简化 - id!=0 可能也存在失败案例,但从您的示例中这并不明显)。
    【解决方案2】:

    如果您正在测试您的应用程序是否在给定时间抛出预期的异常,您应该使用 try-catch 块来触发异常并对其进行评估。

    除此之外,我认为您不能说何时使用它们有任何规则集。当然这取决于你的目标和你的编码风格,但是我们正在接近一个基于意见的答案,这对于这个网站来说有点离题;-)

    【讨论】:

    • 我想我应该在一个测试用例中测试特定的exception 部分并在一个新的测试用例中测试correct 部分。不应该在一个测试用例中同时测试它们。
    • 同样,这取决于您的偏好。有些人喜欢很少的综合测试用例(我不喜欢,这使得很难准确地看到失败的原因),其他人更喜欢孤立的测试用例。如果你看一下测试驱动开发,这个想法是你首先定义你的测试用例,然后编码/重新编码以使你的测试用例通过。但是,如果您在一个测试用例中收集所有内容,您将在某个阶段失去概览。
    猜你喜欢
    • 2020-02-11
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 2010-10-05
    • 2018-09-14
    • 2012-11-25
    • 2014-08-07
    相关资源
    最近更新 更多