• 单元测试


    单元测试——基础概念

     

    前言

    我们都写过的某种测试

    不要惊讶,你已经进行过某种程度的单元测试。你见过提交代码前不做测试的开发人员吗?
    在传统测试中,开发人员使用一个图形用户界面触发要测试的类的某个行为,然后检验结果。

    那什么是单元测试,什么不是单元测试呢?

    为什么不写单元测试

    不想做

    往往说不想的,其实是因为还不会。因为不会,所以想一想就很麻烦,还不如手工测试呢。

    多余

    我已经写好代码,然后还要去确认写好的逻辑,好多余

    • 我们不能确保我们的代码是100%正确的。有可能因为精神不好,原因需要抛异常的地方,忘了写一个throw呢?结果原来需要回滚的事业,没正常回滚。
    • 我们在写实现的有很多逻辑,甚至有一些异常处理。因为我们在假设某些场景。其实这些场景就是简单的单元测试。所以又写一遍会觉得很多余。
    • 代码都实现完了,写单元测试干什么。其实代码还没有实现完!有可能还要重构,有可能你还需要排错,有可能别人接手你的代码。但是你没有一个办法保证你的代码一直是正确的。

    因为我们没有遵循正确的TDD实践,所以觉得不舒服和多余。

    经常修改

    单元测试一旦通过,不会经常修改。一般有两大类经常修改情况:

    • 确实需要修改单元测试,因为接口需求变更了。所以有些单元测试没有某些业务的考虑,所以要删除或者修改这些单元测试,否则反而会报红。
    • 但是往往更多的是第二类。接口需求不变,重构的时候因为报红了,所以强行修改单元测试。因为依赖变了,甚至有些顺序变了,所以原来的单元测试报红了。那说明本来的被单元测试的代码本身就依赖性太强。一般需要修改的是重构代码本身。而且单元测试的每个case最好是隔离的。

    太浪费时间

    是的,单元测试确实会增加编码的时间。但是从整个软件的交付时间比来说,有好的单元测试的时间会交付更快。一般有健全的单元测试,在测试阶段和维护阶段会花费更少的时间。我们在做的是一个完整的软件,所以时间应该算总的周期
    另外一个原因,有可能是因为不熟练或者没有合适的工具,所以花了大量时间在重复的工作之上。

    不务正业

    其实咱们一直在做不务正业的事。调试代码,给代码加注释,画流程图,上网解决问题等等。这些其实都是开发者的日常工作。所以单元测试也是!!

    这里也有一篇文章,也比较有意思:为什么要进行烦人的单元测试?

    什么是单元测试

    那到底什么是单元测试呢?

    一个单元测试是一段自动化的代码,这段代码调用被测试的。这段代码调用被测试的工作单元,之后对这个单元的单个最终结果的某些假设进行检验。单元测试几乎都是用单元测试框架编写的。单元测试容易编写,能快速运行。单元测试可可靠、可读,并且可维护。只要产品代码不发生变化,单元测试的结果是稳定的。

    特性

    • 它应该是自动化的,可重复执行。
    • 它应该很容易实现
    • 它应该第二天还有意义
    • 任何人都应该能一键运行它
    • 它应该运行速度很快
    • 它的结果应该是稳定的(如果运行之间没有进行修改的话,多次运行一个测试应该总是返回同样的结果)
    • 它应该能完全控制被测试的单元
    • 它应该是完全隔离的(独立于其他测试的运行)
    • 如果它失败了,我们应该很容易发现什么是期待的结果,进而定位问题所在

    包含行为

    1. 准备(Arrange)对象,创建对象,进行必要的设置
    2. 操作(Act)对象
    3. 断言(Assert)某件事情是预期的。

    结果类型

    从调用系统的一个公共方法到产生一个测试可见的最终结果,其间这个系统发生的行为总称为一个工作单元。一个最终结果有三种形式

    1. 带有返回值的。即基于值的测试。
    2. 在方法调用前后,系统的状态或者行为有可见的变化 ,这种变化无需查询私有状态即可判断。即基于状态测试。
    3. 调用一个不受测试控制的第三方系统,这个第三方系统不返回任何值,或者返回值都被忽略。即交互测试。

    验证

    很多人把进行软件测试的行为和单元测试概念混为一谈。要澄清这个误解,你首先应该回顾自己以前写过的测试,问自己如下问题。

    1. 我两周前写的一单元测试,今天还能运行并得到结果吗?几个月前的呢?几年前的呢?
    2. 我两个月前写的单元测试,我团队里任何一个人都能运行它们并得到结果吗?
    3. 我能在几分钟内跑完我写过的所有单元测试吗?
    4. 我能一键运行我写过的所有单元测试吗?
    5. 我能在几分钟写出一个基本的测试吗?
      如果能的话,那就是单元测试。如果不能,那有可能就是集成测试。

    什么是集成测试

    那到底什么是集成测试呢?

    集成测试是对一个工作单元进行的测试,这个测试对被测试的工作单元没有完全的控制,并使用该单元的一个或者多个真实依赖物,何如时间、网络、数据库、线程或者随机数产生器等
    总的来说,集成测试会使用真实依赖物,而单元测试则把测试单元和基依赖物隔离开,以保证单元测试结果高度稳定

    并不是说集成测试不重要!单元测试和集成测试具有同等重要的地位,但是这两个测试应该彼此分开,以营造一种“绿色安全区”的感觉

    什么是TDD

    上面说的是什么是单元测试。那么什么时候编写测试呢?很多人觉得为软件编写单元测试的最佳时机是软件编码完成以后,但是越来越多的人选择在产品代码编写之前写单元测试。这种方法称为测试优先或测试驱动开发(Test-Driven Development, TDD)。
    执行步骤:

    1. 编写一个会失败的测试,以证明产品中代码或功能的缺失。编写测试的时候,要假设产品代码已经能工作了,这样测试的失败就说明产品代码中有缺陷。
    2. 编写符合测试预期的产品代码,使测试通过。产品代码应该尽量简单。
    3. 重构代码。如果测试通过了,你就可以编写下一个单元测试,或者进行重构,使代码可读性更强,或者去除重复代码等。

    红-->绿-->重构


    本文的概念大部分出自于《单元测试的艺术》,特此说明。因为书里的概念讲得是我想要的,比网上搜的其他资源要适合自己些。
    更具体的概念可以翻阅《单元测试的艺术》。

  • 相关阅读:
    全面分析 Spring 的编程式事务管理及声明式事务管理
    100句唤醒自己的励志名言
    100句自我激励的名言佳句
    java反射详解
    JAVA中的反射机制
    【BZOJ1015】【JSOI2008】星球大战Starwar(离线并差集)
    【HEOI2016/TJOI2016】排序(二份答案+线段树)
    【USACO06DEC】—牛奶模式Milk Patterns(后缀自动机)
    【HNOI2016】—找相同字符(后缀自动机)
    【AHOI2013】—差异(后缀自动机)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4916929.html
Copyright © 2020-2023  润新知