Junit, CodeCover & CFG 刘子聪
内容 单元测试 Junit 静态控制流图模型 CFG Generator 覆盖率报告 CodeCover 作业说明
JUnit JUnit 测试是程序员测试,即所谓白盒测试 继承 TestCase 类即可利用 JUnit 测试
JUnit 需要知道程序结构以及逻辑 设计不同的测试输入以及输出预言 尽可能覆盖多的语句以及分支
Junit 安装及配置 要安装和使用 JUnit 是很容易的,只需三个 步骤: – ( 1 )下载 JUnit 软件; – ( 2 )将 JUnit 包解开,放到文件系统中; – ( 3 )运行 JUnit 测试时,将 JUnit 中的所有 *.jar 文 件放到类路径里。
Junit 安装及配置 =navbar =navbar (重定向到 Github )
Assert 断言 断言是单元测试最基本的组成部分。 Junit 程 序库提供了如下不同形式的多种断言。 1.assertEquals([String message],expected,actual);- 是否 相等 2.Excpected- 是你期望得到的值 ;actual- 是被测试代码实际 产生的值 ; 3.assertNull([String message],Object object);- 是否为空
Assert 断言 4.assertNotNull([String message],Object object);- 是否 不为空 5.assertTrue([String message],boolean condition);- 是 否为真 6.Fail(String message); 此断言会使测试立即失效,其中 message 参数是可选的。 这种断言通常用于标记某个不应该到达的分支。(例如: 在一个预期异常发生的时侯)
Assert 断言 当一个断言失败了,加上一个简短的消息 来通知这个失败的一些属性甚至是失败的 原因,可能会带来比较好的效果。 JUnit 框架里,一个断言的方法的第一个参 数作为可选项,接受一个 “String” 类型的参 数,包含一些消息,在断言失败的时候显 示出来。对于 assertTrue( ) 有 2 种形式:
对于异常的处理 对于测试而言,下面两种异常是我们可能会感兴趣的: – 从测试代码抛出的可预测异常 – 由于某个模块发生严重错误,而抛出的不可预测异常 对于 Junit 而言异常彻头彻尾是一个好东西 - 它能明确告诉 我们什么地方出错了。例如:有一个名为 sortMyList() 的方 法,如果传入的参数是一个 null list ,那么我们希望方法能 抛出一个异常。在 Junit 中我们可以显式地针对这一点进行 测试。
对于异常的处理 Public class TestException extends TestCase{ Public void testForException(){ try{ sortMyList(null); // 特意传入 null ,看测试结果 Fail(“ 需要抛出一个异常 !”); }catch(RuntimeException e){ assertTrue(true) // 如果有异常抛出则应到执行此语句 }
测试的技巧 大量测试数据 典型错误类型 强制产生错误条件
大量测试数据 对于有大量的测试数据的测试,可以通 过数据文件来存储这些测试数据,然后让 单元测试读取该文件,从而提高测试的完 整性和效率。
典型错误类型 注:找边界条件是做单元测试最有价值的工作之一,因为 bug 一般 就 出现在边界上。 常见的边界条件有如下一些: 1. 完全伪造一个不一致的输入数据,例如: “ ! · # ¥ % ……— …… *% —” ; 2. 格式错误的数据,例如没有顶层域名的电子邮件地址,象 3. 空值或者不完整的值 ( 如 0,0.00, ”” 和 null); 4. 一些与意料中的合理值相去甚远的数值。例如一个人岁数 1000 岁 ; 5. 如果要求是一个不允许出现重复数值的 list ,但是传入的是一 个存在重复数值的 list; 6. 事情到达的次序是错误的,或者碰巧和期望的次序不一致。 例如:在未登录系统之前,就尝试打印文件 ;
强制产生错误 在真实世界,错误总是会发生:磁盘会满,网 络连接会断开,电子邮件会多得会塞满整个邮 箱,而程序是会崩溃的。所以我们应当能够通 过强制引发错误,来测试代码中是如何处理所 有这些真实世界中的问题的。 我们常用的手段可以通过提供一些无效的 参数来进行模拟错误,但是对于象网络连接断 开这类型错误,我们可能需要借鉴一些其它手 段或工具 ( 如 Mock 对象等 )
JUnit 简单例子 源程序:
JUnit 简单例子 测试程序:
JUnit 简单例子 启动 JUnit :
JUnit 简单例子 测试结果:
CFG Generator 观察结构 CFG —— Control Flow Graph 观察程序的控制流走向 我们的目的就是尽量走遍每一条路线
CFG Generator 安装地址 – – “Help”->”Install New Software…”-> 输入地址
CFG Generator
例子:
CFG Generator 控制流图
CodeCover 用来统计测试覆盖率,支持多种覆盖(包 括语句覆盖、分支覆盖、 MCDC 覆盖等)
使用 CodeCover 统计覆盖率 使用上面这个地址安装 eclipse 插件
使用 CodeCover 统计覆盖率
查看结果
作业要提交的内容 每个程序一个 Eclipse 项目包 – 其中包含可以使用 Junit 运行的测试用例 – 所有的测试用例写在一个.java 文件之中
作业要提交的内容 每个测试用例需要加上注释,说明其作用,比如 加上注释后,使用 Javadoc 产生接口文档,提交之。
Java Doc 生成 右击项目,选择 Export 选择 Javadoc
Java Doc 生成 Javadoc command : 选择 jdk 的 bin/javadoc.exe 生成的 doc 在工程 目录下 doc 文件夹 下
评分标准 覆盖率 – 语句覆盖、分支覆盖、条件覆盖。。。 测试用例说明
附: JUnit3 、 4 对照 在网上的教程好多是基于 JUnit3 的(比如继 承 TestCase 类), JUnit3 与 4 的区别都有哪些?
JUnit4 取消用反射机制来命名定位测试,而采用 JDK public void additionTest() { int z = x + y; assertEquals(2, z); }
JUnit4 不需要继承 TestCase 类,只需要使用 JDK 中的 static import 。 import static org.junit.Assert.assertEquals; public void addition() { int z = x + y; assertEquals(2, z); }
JUnit4 新的 setUp() 和 tearDown() 。 在 Junit4 中不再使用 setUp() 和 tearDown() 来完成测 试前后的准备和清除工作,而是采用: – :标识需要在每个测试方法前后需要进 行的操作。 – :标识需要在测试类前后进行 的操作。
JUnit4 异常测试 old Junit try { int n = 2 / 0; fail("Divided by zero!"); } catch (ArithmeticException success){ assertNotNull(success.getMessage()); } 异常测试 Exception.class) public void divideByZero() { int n = 2 / 0; } 如果该异常没有抛出(或 者抛出了一个不同的异 常),那么测试就将失败。
JUnit4 ,当使用文本界面时,会输出一个 “I” (代表 ignore )。 可以帮助解决单元测试的一些 性能问题。 Assert 判断方法精简,并添加了: public static void assertEquals(Object[] expected, Object[] actual) public static void assertEquals(String message, Object[] expected, Object[] actual) – 为数组的比较提供了方便。
Thanks !