zoukankan      html  css  js  c++  java
  • 单元测试基础

    什么是单元测试

    单元测试,对软件在设计的最小单元中进行正确性检测的测试,将可能存在的错误在最小范围内发现并解决。

    对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。当然,在具体的测试实现中,也可能对应的是多个程序文件中的一组函数。

    单元具有一些基本属性,如明确的功能、规格定义、明确与其他部分的接口定义等,可以清晰的与同一程序的其它单元划分。

    单元测试的目的

    发现模块内部逻辑、语法、算法和功能错误。

    单元测试主要是基于白盒测试:

    • 验证代码与设计相符度。
    • 发现设计和需求中存在错误。
    • 发现在编码过程中引入的错误。

    单元测试关注的重点

    独立路径

    对于基本执行路径和循环进行测试,可能的错误有:

    • 不同数据类型的比较。
    • “差1错”,即可能多循环或少循环一次。
    • 错误或不可能的终止条件。
    • 不适当的修改了循环变量。

    局部数据结构

    单元的局部数据结构是最常见的错误来源,应设计测试用例以检查可能的错误:

    • 不一致的数据类型。
    • 检查不正确或不一致的数据类型。

    错误处理

    比较完善的单元设计要去能遇见出错的条件,并设置适当的错误处理,以便在程序出错时,能对错误重新做安排,保证期逻辑上的正确性:

    • 出错的描述难以理解。
    • 显示的错误与实际的错误不符。
    • 对错误条件的处理不正确。

    边界条件

    边界上出现错误是最常见的错误现象:

    • 取最大最小值发生错误。
    • 控制流中的大于、小于这些比较值常出现错误。

    单元接口

    接口实际上就是输入和输出对应关系的集合,要对单元进行动态测试无非就是给这个单元一个输入,然后检查输出是否和预期一致。

    如果数据不能正常输入和输出,单元测试就无从谈起,因此需要对单元接口进行如下的测试:

    • 被测单元的输入、输出在个数、属性、顺序是否和详细设计中的描述一致。
    • 是否修改了只做输入用的形式参数。
    • 约束条件是否通过形式参数来传送。

    单元测试环境

    单元本身不是一个独立的程序,一个完整的可运行的软件系统有若干个单元组成,所以必须为每个单元测试开发驱动单元和桩单元。

    • 驱动单元(Driver):所测函数的主程序,它接收测试数据,并把数据传递给所测试单元,最后再输出实际测试结果,当被测单元能完成相关单元时,也可以不需要驱动单元。
      • 接收测试数据,包含测试用例输入和预期输出。
      • 把测试用例输入传送给要测试的单元。
      • 将被测单元的实际输出和预期进行比较,得到测试结果。
      • 将测试结果输出到指定的位置。
    • 桩单元(Stub):用来代替所测单元调用的子单元。
      • 桩单元的功能是从测试角度模拟被调用的单元。
      • 桩单元需要针对不同的输入,返回不同的期望值,模拟不同的功能。

    驱动单元执行被测函数得到实际的测试结果,那被测函数可能有其他依赖的函数,我们就要使用桩函数替代被测函数依赖的函数,驱动单元的执行依赖桩函数的正确性。

    在展开测试的时候,有相应的测试策略可以使用。

    孤立的测试策略

    不考虑每个模块与其他模块之间的关系,为每个模块设计桩模块和驱动模块,每个模块进行独立的单元测试。

    优点是:

    • 该方法最简单,容易操作。
    • 可以达到很高的结构覆盖率。
    • 可以展开并行。
    • 该方法是纯粹的单元测试。

    缺点是装函数和驱动函数工作量很大,效率不高。

    自顶向下的单元测试策略

    方法是先对最顶层的单元进行测试,把顶层所调用的单元做成装模块,其次对于第二层进行测试,使用上面已经测试的单元做驱动模块,如此类推直到测试完所有的模块。

    优点是可以节省驱动函数的开发工作量,测试效率高。

    缺点是随着被测单元的增加,测试过程变得越来越复杂,并且开发和维护成本将增加。

    自底向上的单元测试策略

    方法是先对模块调用层次图上最底层的模块进行单元测试,模拟调用该模块的模块做驱动模块,然胡再对上面一层做单元测试,用下面已被测试过的模块做桩模块,一次类推, 直到测试完所有的模块。

    优点是可以节省桩函数的开发工作量,测试效率高。

    缺点是不是纯粹的单元测试,底层函数的测试质量对上层函数的测试将产生很大的影响。

    单元测试的四个阶段

    单元测试计划阶段:完成单元测试设计。

    单元测试设计阶段:完成单元测试方案。

    单元测试实现阶段:完成单元测试用例、规程、脚本及数据文件。

    单元测试执行阶段:执行单元测试用例,修改发现的问题并进行回归测试,提交单元测试报告。

    单元测试基本原则

    原则,1,对全新的代码或修改后的代码要进行单元测试:

    • 针对缺陷进行修改。
    • 代码优化。
    • 如果代码改动较小,需要进行回归测试,如果改动较大,则需要重新设计单元测试用例来进行测试。

    原则2,单元测试根据单元测试计划和方案进行,排除测试随意性。

    原则3,必须保证单元测试计划、方案、用例等经过评审。

    原则4,当测试用例的测试结果与预期不符时,单元测试的执行人员需要如实记录实际的测试结果。处理方式:

    • 确认到底是预期结果错误还是实测结果错误。
    • 如果是预期结果错误,修改预期结果,更新测试用例文档。
    • 如果是实测结果错误,那就意味着软件有bug,需要进一步测试,为开发人员提供更有用的信息,帮助他们尽快定位解决这个问题,同时还有可能发现更多的bug。

    原则5,只有当测试计划中的结束标准达到时,单元测试才能结束。

    原则6,对被测单元需要达到一定的代码覆盖率要求。

    单元测试方式

    • 代码级别测试,熟悉模块功能,内部逻辑与接口,编写测试用例。
      • 接口测试,确保接口实现正确,符合设计文档规范或者相关约定。
      • 数据结构测试,确保数据结构的设计正确合理。
      • 边界测试,对于边界值进行检测。
    • 模块功能测试,通过黑盒,对模块进行功能测试。
    • 其他测试,性能、规范等。

    示例:

    def div(x, y):
        """ 两数相除 """
        return x / y
    
    
    if __name__ == '__main__':
        print(div(10, 5))
        print(div(10, 0))

    例如,测试函数div的可用性,包括正常数据测试,还有在除法中,被除数能否为0进行测试。

    常见单元测试工具

    常见的应用于单元测试的工具有:

    • 代码静态分析工具:Logiscope、McCabeQA、CodeTest。
    • 代码检查工具:PC-LINT、CodeChk、Logiscope。
    • 测试脚本工具:TCL、Python、Perl。
    • 覆盖率测试工具:Logiscope、PureCoverage、TrueCoverage、McCabeTest、CodeTest。
    • 内存检测工具:Punify、BoundsCheck、CodeTest。
    • 转为单元测试设计的工具:RTRT、Cantata、AdaTest。
  • 相关阅读:
    第三题 bfw在睡觉
    第二题 bfw和zhk的故事
    第一题 奶牛散步
    AC加油站7月比赛总结
    暑期机房联赛
    题解 P5663 【加工零件【民间数据】】
    题解 P1052 【过河】
    并发编程之进程
    网络编程socketserver
    网络编程之黏包
  • 原文地址:https://www.cnblogs.com/sundawei7/p/11945447.html
Copyright © 2011-2022 走看看