什么是单元测试

单元测试用于测试一个独立的工作单元的执行结果是否符合预期。

一个工作单元就是一项任务,不直接依赖于其他任何任务的完成。在面向对象的编程语言例如Java中,一个工作单元通常是(但不总是)一个类中的一个非private的方法。因此,单元测试是最细粒度的测试。相比之下,集成测试验收测试检查的是各个组件如何交互,是更粗粒度的测试。

单元测试通常关注的是一个方法是否遵循了它的API契约中的条款。通常而言,在单元测试中,我们会依照下面的步骤进行测试:

  1. 创建被测对象;
  2. 将测对象的设置到一个初始状态,包括注入被测对象的所依赖的协作对象的实例;
  3. 使用指定的参数集调用被测对象的方法,执行测试;
  4. 断言方法执行的结果符合预期。

执行结果通常有以下三种形式:

  • 对于有返回值的方法,断言方法的返回值符合预期
  • 对于没有返回值的方法,断言它产生的副作用(例如:修改了对象的内部状态,调用了协作对象)符合预期。
  • 抛出了我们预期的异常。例如对于ATM机应用,当测试中的取款金额超出了账户的可用余额时,断言调用取款方法会抛出BalanceInsufficientException异常。或者当账户被冻结时,断言调用取款方法会抛出AccountLockedException异常。

单元测试用于检验被测类中的一个工作单元(通常是一个非private的方法)在各种正常和异常条件下被调用时的响应(返回值、副作用、抛出异常)都符合设计者的预期。

例如,当我们设计银行账户类Account的取款方法withdraw(double amount)时,我们的设计意图包括下面几个要点:

  • 如果账户被冻结,无论余额是否足够,调用withdraw()方法都应该失败并抛出AccountLockedException异常。Account的当前可用余额不变。
  • 如果Account的状态正常,当取款金额为0或负数时,调用withdraw()方法应该失败并抛出InvalidAmountException异常。Account的当前可用余额不变。
  • 如果Account的状态正常且当前可用余额不小于取款金额Amount,则方法应当正常返回。当前余额更新为原余额-取款金额(产生了副作用——修改了Account对象的内部状态)。
  • 如果Account的状态正常且取款金额大于账户的当前可用余额,方法应该调用失败并抛出BalanceInsufficientException异常。Account的当前可用余额不变。

以上就是要设计的Account类的withdraw()方法的API契约。我们应该针对上面几种情况编写一组单元测试,以保证在以上四种状况下调用withdraw()方法的响应都符合设计意图。如果上面的单元测试都通过了,我们的系统就可以保证取款时:

  • 取款金额必须是正数。
  • 账户被冻结时候取款不会成功。
  • 账户未被冻结且余额足够时可以正常取款。
  • 余额不足时取款失败。
  • 如果取款成功,账户的余额必须相应减少。
  • 如果取款失败,不管是由于余额不足还是账户被冻结,账户的当前余额都不变。

这样的系统就是足够安全的。客户不会由于不完善的代码导致金钱和名誉损失。

专业程序员必须保证他写的每一行代码都是正确的、可靠的。单元测试就是保证代码正确性和可靠性的最重要的一步。

results matching ""

    No results matching ""