一、单元测试
1.单元测试定义:
百度百科:单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
2.单元测试基本方法:
单元测试的基本方法就是:依数据的分类列出输入,执行被测试程序,然后,判断输出是否符合预期。单元测试的本质,是面向逻辑块,单元测试用例的本质,是逻辑块的输入输出,也就是设定逻辑块的各种可能输入,及对应的预期输出。
3.单元测试的意义何在?
1)单元测试集中注意力于程序的基本组成部分,首先保证每个单元测试通过,才能使下一步把单元组装成部件并测试其正确性具有基础。单元是整个软件的构成基础,像硬件系统中的零部件一样,只有保证零部件的质量,这个设备的质量才有基础,单元的质量也是整个软件质量的基础。因此,单元测试的效果会直接影响软件的后期测试,最终在很大程度上影响到产品的质量。
2)单元测试可以平行开展,这样可以使多人同时测试多个单元,提高了测试的效率。
3)单元规模较小,复杂性较低,因而发现错误后容易隔离和定位,有利于调试工作。
4)单元的规模和复杂性特点,使单元测试中可以使用包括白盒测试的覆盖分析在内的许多测试技术,能够进行比较充分细致的测试,是整个程序测试满足语句覆盖和分支覆盖要求的基础。
5)单元测试的测试效果是最显而易见的。做好单元测试,不仅后期的系统集成联调或集成测试和系统测试会很顺利,节约很多时间;而且在单元测试过程中能发现一些很深层次的问题,同时还会发现一些很容易发现而在集成测试和系统测试很难发现的问题;更重要的是单元测试不仅仅是证明这些代码做了什么,是如何做的,而且证明是否做了它该做的事情而没有做不该做的事情。
6)单元测试的好与坏不仅直接关系到测试成本(因为如果单元测试中易发现的问题拖到后期测试发现,那么其成本将成倍数上升),而且也会直接影响到产品质量,因为可能就是由于代码中的某一个小错误就导致了整个产品的质量降低一个指标,或者导致更严重的后果。
根据业界的统计,一个 BUG 在单元测试阶段发现花费是 1 的话,到集成测试就变为 10 ,到系统测试就高达 100 ,到实际推向市场量产后就高达 1000 。
4.单元测试内容:
一般来说,单元测试任务包括
- 接口功能测试:用来保证接口功能的正确性。
- 局部数据结构测试(不常用):用来保证接口中的数据结构是正确的
- 比如变量有无初始值
- 变量是否溢出
- 边界条件测试
- 变量没有赋值(即为NULL)
- 变量是数值(或字符)
- 主要边界:最小值,最大值,无穷大(对于DOUBLE等)
- 溢出边界(期望异常或拒绝服务):最小值-1,最大值+1
- 临近边界:最小值+1,最大值-1
- 变量是字符串
- 引用“字符变量”的边界
- 空字符串
- 对字符串长度应用“数值变量”的边界
- 变量是集合
- 空集合
- 对集合的大小应用“数值变量”的边界
- 调整次序:升序、降序
- 变量有规律
- 比如对于Math.sqrt,给出n^2-1,和n^2+1的边界
- 所有独立执行通路测试:保证每一条代码,每个分支都经过测试
- 代码覆盖率
- 语句覆盖:保证每一个语句都执行到了
- 判定覆盖(分支覆盖):保证每一个分支都执行到
- 条件覆盖:保证每一个条件都覆盖到true和false(即if、while中的条件语句)
- 路径覆盖:保证每一个路径都覆盖到
- 相关软件
- Cobertura:语句覆盖
- Emma: Eclipse插件Eclemma
- 代码覆盖率
- 各条错误处理通路测试:保证每一个异常都经过测试
5.单元测试基本原则
- 单元测试必须由最熟悉代码的人(程序的作者)来写(代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。)
- 单元测试应该在最低的功能/参数上验证程序的正确性。
- 单元测试过后,机器状态保持不变。
- 单元测试要快(一个测试运行时间是几秒钟,而不是几分钟)。
- 单元测试应该产生可重复、一致的结果。
- 独立性,单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性。
- 单元测试应该覆盖所有代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,
- 单元测试必须测试公开的和私有的函数/方法。
- 单元测试必须和产品代码一起保存和维护。
- 单元测试必须和代码一起进行版本维护。
5.不同单元测试工具(网络资料)
C/C++
CppUnit
C++Test
然后介绍C++Test,这是Parasoft公司的产品。C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%
Visual Unit
最后介绍Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术。[自动生成测试代码 快速建立功能测试用例程序行为一目了然 极高的测试完整性 高效完成白盒覆盖 快速排错 高效调试 详尽的测试报告前面所述测试要求:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖,用VU可以轻松实现,还有一点值得一提:使用VU还能提高编码的效率,总体来说,在完成单元测试的同时,编码调试的时间还能大幅度缩短。
gtest测试框架是在不同平台上(Linux,Mac OS X,Windows,Cygwin,Windows CE和Symbian)为编写C++测试而生成的。它是基于xUnit架构的测试框架,支持自动发现测试,丰富的断言集,用户定义的断言,death测试,致命与非致命的失败,类型参数化测试,各类运行测试的选项和XML的测试报告。
C#
Visual Build Professional
Java
JUnit 是 Java 社区中知名度最高的单元测试工具。它诞生于 1997 年,由 Erich Gamma 和 Kent Beck 共同开发完成。其中 Erich Gamma 是经典著作《设计模式:可复用面向对象软件的基础》一书的作者之一,并在 Eclipse 中有很大的贡献;Kent Beck 则是一位极限编程(XP)方面的专家和先驱。JUnit 设计的非常小巧,但是功能却非常强大。JUnit ——是一个开发源代码的Java测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例(用于java语言)。主要用于白盒测试,回归测试。
JUnit的好处和JUnit单元测试编写原则:
好处:可以使测试代码与产品代码分开;针对某一个类的测试代码通过较少的改动便可以应用于另一个类的测试;易于集成到测试人员的构建过程中,JUnit和Ant的结合可以实施增量开发;JUnit是公开源代码的,可以进行二次开发;可以方便地对JUnit进行扩展;
TestNG
TestNG,即Testing Next Generation,下一代测试技术。是根据JUnit和NUnit思想,采用 jdk 的 annotation 技术来强化测试功能并借助XML 文件强化测试组织结构而构建的测试框架。TestNG 的强大之处还在于不仅可以用来做单元测试,还可以用来做集成测试。
6.C#单元测试
前面提到工具因为个人没有使用过,所以介绍一下C#单元测试流程,自己学习一下。
软件:VS2013版本及以上
工具:Unit Test Generator 如果VS中为安装可以按照以下步骤下载安装该插件
选择“工具”-“扩展和更新”-联机搜索插件“Unit Test Generator”-下载
具体步骤:
1)新建项目C#类库
2)添加代码
3)右键刚刚创建的User类,选择Generate Unit Test,
点击OK,VS将自动创建一个“UserTest”的类库,其中有“TestClass”和“TestMethod”,这是单元测试专用的测试类和测试方法,写入测试代码。
4)点击上方工具栏的“测试”-“窗口”-“测试资源管理器”。
5)查看结果
以上就是C#中的单元测试流程。
二、测试矩阵
测试矩阵是测试计划中关键的组成都分。一方面,它列出了椭要被测试的内容:另一方面,它指出了将要执行哪一个测试,或“如何”测试软件。矩阵的两维之间就是适用于软件的测试;比如,一个测试:可能用于多个软件模块的测试。测试矩阵也是测试的“证明”。它证明了每个可测试的功能都至少有一个测试,并且每个测试都是设计用来测试特定的功能的。
测试矩阵的一个实例如下表所示。该表显示了工资表系统中4个功能,并有3个用于确认功能的测试。因为工资表是一个批处理系统,所以位用使用带有不同日期的批处理的测试数据,在处理总的分类账时,应进行并行测试,同时所有的修改都应该通过代码检视来验证。可以使用接下来的工作表来淮备这种测试矩阵。(注意:表中将标识出含有被测试功能的模块。)
推荐的测试过程首先确定在测试过程中将被评估的测试因素,然后选择将在测试执行个用到的技术。图8-5是一个因素/测试技术的矩阵,该矩阵显示了对于各种测试因素来说哪些技术是最有价值的。比如,如果测试人员想要评估系统结构的可靠性,那么推荐使用执行和恢复测试技术。另一方面,如果测试人员想要评估可靠性功能方面的问题,推荐使用需求测试、错误处理测试、手动支持测试以及控制测试等技术。