软件工程软件工程软件工程 (11).pdf
单元测试概述 单元测试概述 现实的开发问题 现实的开发问题 经常把单元测试任务堆积到系统测试阶段 w 大量故障堆积在项目中后期,项目后10%的工作占用了项目90%的时间。w 故障难以定位,而且飘忽不定,开发和测试人员疲于奔命。现实的开发问题 现实的开发问题 当前阶段引入的缺陷率 当前阶段发现的缺陷率 当前阶段修复缺陷成本 85%编码 单元测试 功能测试 验收测试 发布上线$25$100$250$1,000$16,000 单元测试 单元测试 要使城墙保持坚固,至少应该保证每一块砖都是好的 单元是构造软件系统的基础,只有使每个单元得到足够的测试,系统的质量才能有可靠的保证,即单元测试是构筑产品质量的基石。单元测试 单元测试 设计更好文档化行为 验证代码 具有回归性 单元测试(Unit Testing)是对软件中的最小可测试单元进行检查和验证。单元测试 单元测试 程序UTCODE 测试人员有权利对没有做过UT的代码说No 程序员必须对自己的代码质量负责,单元测试是对自己代码质量的基本承诺。在现实中,代码质量最好、开发速度最快的程序员是单元测试做得最好的。单元测试内容 单元测试内容 单元测试 模块 接口 局部 数据 结构 边界 条件 独立 路径 出错 处理 检查模块中的数据结构是否正确的定义和使用 检查由于计算错误、判定错误、控制流错误导致的程序错误。对通过所有被测模块的数据流进行测试 检查可能引发错误处理的路径以及进行错误处理的路径 检查数据流或控制流中条件或数据处于边界时的出错可能性 单元测试内容 单元测试内容 单元测试 模块 接口 局部 数据 结构 边界 条件 独立 路径 出错 处理 单元模块被 正确编写 单元测试原则 单元测试原则 快速的 独立的 可重复的 自我验证的 及时的 单元测试应能快速运行,如果运行缓慢,就不会愿意频繁运行它。单元测试应相互独立,某个测试不应为下一个测试设定条件。当测试相互依赖时,一个没通过就会导致一连串的失败,难以定位问题。单元测试应该是可以重复执行的,并且结果是可以重现的。单元测试应该有布尔输出,无论是通过或失败,不应该查看日志文件或手工对比不同的文本文件来确认测试是否通过。及时编写单元测试代码,应恰好在开发实际的单元代码之前。单元测试过程 单元测试过程 确定要做的单元测试 编写或修改单元测试用例 执行单元测试 根据结果修改或增加单元测试 找出潜在的最大问题区 测试用例 单元测试代码 测试结果 满足测试质量 单元测试质量 单元测试质量 测试通过率是指在测试过程中执行通过的测试用例所占比例,单元测试通常要求测试用例通过率达到100%。测试 通过率 测试 覆盖率 测试覆盖率是用来度量测试完整性的一个手段,通过覆盖率数据,可以了解测试是否充分以及弱点在哪里。代码覆盖率是单元测试的一个衡量标准,但也不能一味地去追求覆盖率。单元测试质量 单元测试质量 判定覆盖 语句覆盖 条件组合覆盖 判定条件覆盖 条件覆盖 路径覆盖 代码覆盖率 单元测试方法 单元测试方法 静态测试:通过人工分析或程序正确性证明的方式来确认程序正确性。动态测试:通过动态分析和程序测试等方法来检查和确认程序是否有问题。事件驱动 输出 单元测试方法 单元测试方法 黑盒测试(Black Box Testing):又称功能测试,它将测试对象看做一个黑盒子,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。客户需求 输入 单元测试方法单元测试方法 白盒测试(White Box Testing):又称结构测试,它把测试对象看做一个透明的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。单元测试方法单元测试方法 被测模块 上层模块 下层模块1 下层模块2 下层模块N 单元测试方法单元测试方法 被测模块 驱动模块 桩模块1 桩模块2 桩模块N 测试用例 测试 结果 单元测试之单元测试之xUnit xUnit JUnit(Java)CppUnit(C+)DUnit(Delphi)NUnit(.Net)PhpUnit(Php)PyUnit(Python)单元测试之单元测试之xUnit xUnit 通常适用于以下场景的测试 单个函数、一个类或者几个功能相关类的测试 尤其适用于纯函数测试或者接口级别的测试 xUnit 无法适用于复杂场景的测试 被测对象依赖关系复杂,甚至无法简单创建出这个对象 对于一些失败场景的测试 被测对象中涉及多线程合作 被测对象通过消息与外界交互的场景 单元测试之单元测试之Mock Mock测试是在测试过程中对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象(即Mock对象)来创建以便测试的方法。真实对象具有不可确定的行为(产生不可预测的结果)真实对象很难被创建(如具体的Web容器)真实对象的某些行为很难触发(如网络错误)真实情况令程序的运行速度很慢真实对象有用户界面测试需要询问真实对象它是如何被调用的真实对象实际上并不存在单元测试之单元测试之Mock 举例:支付宝接龙红包通过猜金额的小游戏方式,实现朋友之间的互动并领取春节红包。这种情况应如何测试?GiftMoney GiftMoney(int min,int max,int money)GuessMoney(int guess).int min,max,money;int winnerID;GiftMoneyDAO 单元测试之单元测试之Mock 关键:需要应用针对接口的编程技术,即被测试的代码通过接口来引用对象,再使用Mock对象模拟所引用的对象及其行为,因此被测试模块并不知道它所引用的究竟是真实对象还是Mock对象。ClassA ClassB doMethod()InterfaceB doMethod()ClassA ClassB doMethod()Mock doMethod()单元测试之单元测试之Mock 思考:在微信抢票应用中,程序通过直接调用系统函数来获得当前的系统时间。如果使用Mock方法进行测试,应该如何重构程序?谢谢大家谢谢大家!THANKS