`

【转】单元测试——基础概念

 
阅读更多

单元测试——基础概念

 

前言

我们都写过的某种测试

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

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

为什么不写单元测试

不想做

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

多余

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

  • 我们不能确保我们的代码是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. 重构代码。如果测试通过了,你就可以编写下一个单元测试,或者进行重构,使代码可读性更强,或者去除重复代码等。

红-->绿-->重构


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

分享到:
评论

相关推荐

    前后端分离开发模式下后端质量的保证——单元测试

    本文主要围绕单元测试展开,从单元测试的基础概念说起,对比单元测试和集成测试,同时我们还会聊一聊单元测试与测试驱动开发的区别。在我们了解完单元测试的概念之后,我们会探讨一下什么样的单元测试算得上是好的...

    Web接口开发与自动化测试

    《Web接口开发与自动化测试——基于Python语言》分为15章,第1章介绍了Python的基础知识,解答初学Python的同学都会遇到的一些问题;第2章到第5章以开发发布会签到系统为需求,介绍了Django Web开发技术;第6章介绍...

    Python接口开发测web

    《Web接口开发与自动化测试——基于Python语言》分为15章,第1章介绍了Python的基础知识,解答初学Python的同学都会遇到的一些问题;第2章到第5章以开发发布会签到系统为需求,介绍了Django Web开发技术;第6章介绍...

    计算机二级公共基础知识

    顺序存储方式主要用于线性的数据结构,它把逻辑上相邻的数据元素存储在物理上相邻的存储单元里,结点之间的关系由存储单元的邻接关系来体现。 链式存储结构就是在每个结点中至少包含一个指针域,用指针来体现数据...

    Java SE实践教程 源代码 下载

    5.4.1 创建JUnit单元测试 97 5.4.2 setUp和tearDown 102 5.4.3 使用TestSuite 103 5.5 补充:JUNIT 4的新增特性 104 5.5.1 测试方法 104 5.5.2 初始化方法 105 5.5.3 TestSuite初始化 106 5.5.4 兼容性 106 ...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    5.3 编写单元测试的步骤 95 5.3.1 常用断言 95 5.3.2 TestSuite 96 5.3.3 JUnit框架组成 96 5.4 练习 97 5.4.1 创建JUnit单元测试 97 5.4.2 setUp和tearDown 102 5.4.3 使用TestSuite 103 5.5 补充:JUNIT 4...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    5.3 编写单元测试的步骤 95 5.3.1 常用断言 95 5.3.2 TestSuite 96 5.3.3 JUnit框架组成 96 5.4 练习 97 5.4.1 创建JUnit单元测试 97 5.4.2 setUp和tearDown 102 5.4.3 使用TestSuite 103 5.5 补充:JUNIT 4...

    从Java走向Java+EE+.rar

    第1章 Java EE的基本知识 1 1.1 Java EE的出现及其...23.3 利用JUnit进行单元测试 324 23.4 利用StrutsTestCase对Struts进行测试 328 23.5 压力测试和JMeter 334 23.6 其他开源测试工具 339 23.7 小结 343

    Android 编程权威指南

    编辑推荐 威望——源自大名鼎鼎的Big Nerd Ranch训练营培训讲义,该训练营已经为微软、Google、Facebook...第3版较之前版本增加了对数据绑定等新工具的介绍,同时新增了针对单元测试、辅助功能和MVVM架构等主题的章节。

    零点起航Delphi7基础教程源码

    2.7 实例——随机加减法测试 2.8 小结 第3章 面向对象编程 3.1 OOP基本概念 3.2 类的基本概念 3.3 类的封装 3.4 类的继承性 3.5 类的多态性 3.6 异常处理 3.7 小结 第4章 应用程序开发框架 4.1 Delphi的...

    网上书店销售管理系统毕业论文+源码

    目 录 第一章 绪论 1 第二章 网络书店销售管理系统概述 2 ...§6.2单元测试实例 31 §6.3综合测试 32 §6.4系统的维护主要包括四个方面 32 结 论 33 系统结论 33 个人体会 33 参考文献 35 致 谢 36

    深度学习基础3——过拟合欠拟合、梯度消失与梯度爆炸、常见循环神经网络

    门控循环神经网络/门控循环单元(GRU)2.LSTM:长短期记忆3.深度循环神经网络(Deep RNN)4.双向循环神经网络(BRNN)   一、过拟合欠拟合 1.概念 欠拟合:训练误差(训练集的损失函数的值)较大。 过拟合:训练误差远远...

    ASP.NET MVC 3高级编程

    12.3 单元测试用于asp.net mvc应用程序的技巧和窍门 291 12.3.1 控制器测试 291 12.3.2 路由测试 296 12.3.3 验证测试 298 12.4 小结 302 第13章 扩展asp.net mvc 303 13.1 模型扩展 304 13.1.1 把请求数据...

    Spring.3.x企业应用开发实战(完整版).part2

    16.1.4 单元测试基本概念 16.2 JUnit 4快速进阶 16.2.1 JUnit 4概述 16.2.2 JUnit 4生命周期 16.2.3 使用JUnit 16.3 模拟利器Mockito 16.3.1 模拟测试概述 16.3.2 创建Mock对象 16.3.3 设定Mock对象的期望行为及...

    Spring3.x企业应用开发实战(完整版) part1

    16.1.4 单元测试基本概念 16.2 JUnit 4快速进阶 16.2.1 JUnit 4概述 16.2.2 JUnit 4生命周期 16.2.3 使用JUnit 16.3 模拟利器Mockito 16.3.1 模拟测试概述 16.3.2 创建Mock对象 16.3.3 设定Mock对象的期望行为及...

    新概念C语言.李一波(带详细书签).pdf

    “新概念C语言”突破了以往任何一种语言教材的旧的模式,将教学内容分为入门篇和提高篇两个篇章。在入门篇中只引进程序设计必要的语法现象,达到快速入门。激发兴趣的目的。在入门篇和提高篇之间插一个强化上机实验...

    计算机要学哪些东西----(还有附赠哦)

    每个单元都用一个领域名加一个数字后缀表示,比如OS3是关于并发的单元。各个单元由被细分成主题(topics),这是CS知识体层次结构的最底层。 离散结构(DS) DS1. 函数,关系,集合[核心] DS2. 基本逻辑[核心] DS3. ...

    asp.net知识库

    技术基础 New Folder 多样式星期名字转换 [Design, C#] .NET关于string转换的一个小Bug Regular Expressions 完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则...

    高级软件架构师复习提纲

    它有以下类型:单元测试;功能测试;签入测试;构造验证测试;回归测试 7、使用内部发布的好处:将复杂项目分解为多个可管理的任务;易于实现对计划的变更;提高了解决方案的整体质量;提供了一个相对容易实现的...

    jQuery基础教程(第四版)

    附录B向读者介绍使用jQUnit库对JavaScript程序进行单元测试。这个库是开发和维护高度完 善的Web应用所必须的工具。 附录C提供了jQuery的简明参考,包括所有方法和选择符表达式。在实际开发中,明确自己

Global site tag (gtag.js) - Google Analytics