`
阿尔萨斯
  • 浏览: 4147789 次
社区版块
存档分类
最新评论

Java4Android之单元测试入门

 
阅读更多

本文主要介绍了如何使用 JUnit 4 提供的各种功能开展有效的单元测试,并通过一个实例演示了如何使用 Ant 执行自动化的单元测试。本文假设读者对 Eclipse 下进行 Java 开发有一定的经验,并了解 Java 5 中的注解(annotation)特性。<wbr></wbr>
引言<wbr></wbr>

<wbr><wbr><wbr>毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果。单元测试正是验证代码行为是否满足预期的有效手段之一。但不可否认,做测试是件很枯燥无趣的事情,而一遍又一遍的测试则更是让人生畏的工作。幸运的是,单元测试工具 JUnit 使这一切变得简单艺术起来。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>JUnit 是 Java 社区中知名度最高的单元测试工具。它诞生于 1997 年,由 Erich Gamma 和 Kent Beck 共同开发完成。其中 Erich Gamma 是经典著作《设计模式:可复用面向对象软件的基础》一书的作者之一,并在 Eclipse 中有很大的贡献;Kent Beck 则是一位极限编程(XP)方面的专家和先驱。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>麻雀虽小,五脏俱全。JUnit 设计的非常小巧,但是功能却非常强大。Martin Fowler 如此评价 JUnit:在软件开发领域,从来就没有如此少的代码起到了如此重要的作用。它大大简化了开发人员执行单元测试的难度,特别是 JUnit 4 使用 Java 5 中的注解(annotation)使测试变得更加简单。<wbr></wbr></wbr></wbr></wbr>

JUnit 4 初体验<wbr></wbr>

<wbr><wbr><wbr>在开始体验 JUnit 4 之前,我们需要以下软件的支持:<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>Eclipse:最为流行的 IDE,它全面集成了 JUnit,并从版本 3.2 开始支持 JUnit 4。当然 JUnit 并不依赖于任何 IDE。您可以从 http://www.eclipse.org/ 上下载最新的 Eclipse 版本。<wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>Ant:基于 Java 的开源构建工具,您可以在 http://ant.apache.org/ 上得到最新的版本和丰富的文档。Eclipse 中已经集成了 Ant,但是在撰写本文时,Eclipse 使用的 Ant 版本较低(必需 1.7 或者以上版本),不能很好的支持 JUnit 4。<wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>JUnit:它的官方网站是 http://www.junit.org/。您可以从上面获取关于 JUnit 的最新消息。如果您和本文一样在 Eclipse 中使用 JUnit,就不必再下载了。<wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr>首先为我们的体验新建一个 Java 工程 —— coolJUnit。现在需要做的是,打开项目 coolJUnit 的属性页 -&gt; 选择“Java Build Path”子选项 -&gt; 点选“Add Library…”按钮 -&gt; 在弹出的“Add Library”对话框中选择 JUnit(图1),并在下一页中选择版本 4.1 后点击“Finish”按钮。这样便把 JUnit 引入到当前项目库中了。<wbr></wbr></wbr></wbr></wbr>


图1 为项目添加 JUnit 库<wbr></wbr>
java<wbr>单元测试利器JUnit4<wbr></wbr>

请注意 JDK 的版本<wbr></wbr>

<wbr><wbr><wbr>JUnit 4.1 是基于 Java 5 的升级版本,它使用了 Tiger 中的很多新特性来简化原有的使用方式。正因为如此,它并不能直接运行在 JDK1.4.x 版本上。如果您需要在 JDK1.4.x 版本使用 JUnit 的话,请使用 3.8.1 版本。<wbr></wbr></wbr></wbr></wbr>


<wbr><wbr><wbr>可以开始编写单元测试了吗?等等……,您打算把单元测试代码放在什么地方呢?把它和被测试代码混在一起,这显然会照成混乱,因为单元测试代码是不会出现在最终产品中的。建议您分别为单元测试代码与被测试代码创建单独的目录,并保证测试代码和被测试代码使用相同的包名。这样既保证了代码的分离,同时还保证了查找的方便。遵照这条原则,我们在项目coolJUnit 根目录下添加一个新目录 testsrc,并把它加入到项目源代码目录中(加入方式见 图2)。<wbr></wbr></wbr></wbr></wbr>

图2 修改项目源代码目录<wbr></wbr>
java<wbr>单元测试利器JUnit4<wbr></wbr>

<wbr><wbr><wbr>现在我们得到了一条 JUnit 的最佳实践:单元测试代码和被测试代码使用一样的包,不同的目录。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>一切准备就绪,一起开始体验如何使用 JUnit 进行单元测试吧。下面的例子来自笔者的开发实践:工具类 WordDealUtil 中的静态方法 wordFormat4DB 是专用于处理 Java 对象名称向数据库表名转换的方法(您可以在代码注释中可以得到更多详细的内容)。下面是第一次编码完成后大致情形:<wbr></wbr></wbr></wbr></wbr>

Java代码<wbr><wbr><a target="_blank" href="http://wing929.iteye.com/blog/219065" title="收藏这段代码" style="text-decoration:none; color:rgb(9,67,130)"><img src="http://wing929.iteye.com/images/icon_star.png" alt="收藏代码" title="java&lt;wbr&gt;单元测试利器JUnit4" style="margin:0px; padding:0px; border:0px; list-style:none"></a></wbr></wbr>
  1. package<wbr>com.ai92.cooljunit;<wbr><wbr></wbr></wbr></wbr>
  2. <wbr><wbr></wbr></wbr>
  3. import<wbr>java.util.regex.Matcher;<wbr><wbr></wbr></wbr></wbr>
  4. import<wbr>java.util.regex.Pattern;<wbr><wbr></wbr></wbr></wbr>
  5. <wbr><wbr></wbr></wbr>
  6. <wbr><wbr></wbr></wbr>
  7. public<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>class</strong></span><wbr>WordDealUtil<wbr>{<wbr><wbr></wbr></wbr></wbr></wbr></wbr>
  8. <wbr><wbr></wbr></wbr>
  9. <wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  10. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>static</strong></span><wbr>String<wbr>wordFormat4DB(String<wbr>name){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  11. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>Pattern<wbr>p<wbr>=<wbr>Pattern.compile(<span style="word-wrap:normal; word-break:normal; color:blue">"[A-Z]"</span>);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  12. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>Matcher<wbr>m<wbr>=<wbr>p.matcher(name);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  13. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>StringBuffer<wbr>sb<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>new</strong></span><wbr>StringBuffer();<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  14. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  15. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>while</strong></span>(m.find()){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  16. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>m.appendReplacement(sb,<wbr><span style="word-wrap:normal; word-break:normal; color:blue">"_"</span>+m.group());<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  17. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  18. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>return</strong></span><wbr>m.appendTail(sb).toString().toLowerCase();<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  19. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  20. }<wbr><wbr></wbr></wbr>



<wbr><wbr><wbr>它是否能按照预期的效果执行呢?尝试为它编写JUnit 单元测试代码如下:<wbr></wbr></wbr></wbr></wbr>

Java代码<wbr><wbr><a target="_blank" href="http://wing929.iteye.com/blog/219065" title="收藏这段代码" style="text-decoration:none; color:rgb(9,67,130)"><img src="http://wing929.iteye.com/images/icon_star.png" alt="收藏代码" title="java&lt;wbr&gt;单元测试利器JUnit4" style="margin:0px; padding:0px; border:0px; list-style:none"></a></wbr></wbr>
  1. package<wbr>com.ai92.cooljunit;<wbr><wbr></wbr></wbr></wbr>
  2. <wbr><wbr></wbr></wbr>
  3. import<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>static</strong></span><wbr>org.junit.Assert.assertEquals;<wbr><wbr></wbr></wbr></wbr></wbr>
  4. import<wbr>org.junit.Test;<wbr><wbr></wbr></wbr></wbr>
  5. <wbr><wbr></wbr></wbr>
  6. public<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>class</strong></span><wbr>TestWordDealUtil<wbr>{<wbr><wbr></wbr></wbr></wbr></wbr></wbr>
  7. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试wordFormat4DB正常运行的情况</span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  8. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBNormal(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  9. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:blue">"employeeInfo"</span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  10. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  11. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  12. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertEquals(<span style="word-wrap:normal; word-break:normal; color:blue">"employee_info"</span>,<wbr>result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  13. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  14. }<wbr><wbr></wbr></wbr>


<wbr><wbr><wbr>很普通的一个类嘛!测试类TestWordDealUtil 之所以使用“Test”开头,完全是为了更好的区分测试类与被测试类。测试方法wordFormat4DBNormal 调用执行被测试方法 WordDealUtil.wordFormat4DB,以判断运行结果是否达到设计预期的效果。需要注意的是,测试方法 wordFormat4DBNormal 需要按照一定的规范书写:<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>测试方法必须使用注解 org.junit.Test 修饰。<wbr></wbr></wbr></wbr></wbr>
测试方法必须使用 public void 修饰,而且不能带有任何参数。<wbr></wbr>
<wbr><wbr><wbr>测试方法中要处理的字符串为“employeeInfo”,按照设计目的,处理后的结果应该为“employee_info”。assertEquals 是由 JUnit 提供的一系列判断测试结果是否正确的静态断言方法(位于类 org.junit.Assert 中)之一,我们使用它将执行结果 result 和预期值“employee_info”进行比较,来判断测试是否成功。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>看看运行结果如何。在测试类上点击右键,在弹出菜单中选择 Run As JUnit Test。运行结果如下图所示:<wbr></wbr></wbr></wbr></wbr>


图3 JUnit 运行成功界面<wbr></wbr>
java<wbr>单元测试利器JUnit4<wbr></wbr>

<wbr><wbr><wbr>绿色的进度条提示我们,测试运行通过了。但现在就宣布代码通过了单元测试还为时过早。记住:您的单元测试代码不是用来证明您是对的,而是为了证明您没有错。因此单元测试的范围要全面,比如对边界值、正常值、错误值得测试;对代码可能出现的问题要全面预测,而这也正是需求分析、详细设计环节中要考虑的。显然,我们的测试才刚刚开始,继续补充一些对特殊情况的测试:<wbr></wbr></wbr></wbr></wbr>

Java代码
  1. public<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>class</strong></span><wbr>TestWordDealUtil<wbr>{<wbr><wbr></wbr></wbr></wbr></wbr></wbr>
  2. <wbr><wbr><wbr><wbr>……<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  3. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试<wbr>null<wbr>时的处理情况</wbr></wbr></span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  4. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBNull(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  5. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>null</strong></span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  6. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  7. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  8. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertNull(result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  9. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  10. <wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  11. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试空字符串的处理情况</span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  12. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBEmpty(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  13. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:blue">""</span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  14. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  15. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  16. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertEquals(<span style="word-wrap:normal; word-break:normal; color:blue">""</span>,<wbr>result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  17. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  18. <wbr><wbr></wbr></wbr>
  19. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试当首字母大写时的情况</span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  20. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBegin(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  21. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:blue">"EmployeeInfo"</span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  22. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  23. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  24. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertEquals(<span style="word-wrap:normal; word-break:normal; color:blue">"employee_info"</span>,<wbr>result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  25. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  26. <wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  27. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试当尾字母为大写时的情况</span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  28. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBEnd(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  29. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:blue">"employeeInfoA"</span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  30. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  31. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  32. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertEquals(<span style="word-wrap:normal; word-break:normal; color:blue">"employee_info_a"</span>,<wbr>result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  33. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  34. <wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  35. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(0,130,0); padding:0px; margin:0px; width:auto; border:0px">//测试多个相连字母大写时的情况</span><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  36. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(100,100,100)">@Test</span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>void</strong></span><wbr>wordFormat4DBTogether(){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  37. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>target<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:blue">"employeeAInfo"</span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  38. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>String<wbr>result<wbr>=<wbr>WordDealUtil.wordFormat4DB(target);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  39. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  40. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>assertEquals(<span style="word-wrap:normal; word-break:normal; color:blue">"employee_a_info"</span>,<wbr>result);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  41. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  42. }<wbr><wbr></wbr></wbr>



<wbr><wbr><wbr>再次运行测试。很遗憾,JUnit 运行界面提示我们有两个测试情况未通过测试(图4)——当首字母大写时得到的处理结果与预期的有偏差,造成测试失败(failure);而当测试对 null 的处理结果时,则直接抛出了异常——测试错误(error)。显然,被测试代码中并没有对首字母大写和 null 这两种特殊情况进行处理,修改如下:<wbr></wbr></wbr></wbr></wbr>

Java代码<wbr><wbr><a target="_blank" href="http://wing929.iteye.com/blog/219065" title="收藏这段代码" style="text-decoration:none; color:rgb(9,67,130)"><img src="http://wing929.iteye.com/images/icon_star.png" alt="收藏代码" title="java&lt;wbr&gt;单元测试利器JUnit4" style="margin:0px; padding:0px; border:0px; list-style:none"></a></wbr></wbr>
  1. //修改后的方法wordFormat4DB<wbr><wbr></wbr></wbr>
  2. <wbr><wbr></wbr></wbr>
  3. <wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>public</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>static</strong></span><wbr>String<wbr>wordFormat4DB(String<wbr>name){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  4. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  5. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>if</strong></span>(name<wbr>==<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>null</strong></span>){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  6. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>return</strong></span><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>null</strong></span>;<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  7. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  8. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  9. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>Pattern<wbr>p<wbr>=<wbr>Pattern.compile(<span style="word-wrap:normal; word-break:normal; color:blue">"[A-Z]"</span>);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  10. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>Matcher<wbr>m<wbr>=<wbr>p.matcher(name);<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  11. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>StringBuffer<wbr>sb<wbr>=<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>new</strong></span><wbr>StringBuffer();<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  12. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  13. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>while</strong></span>(m.find()){<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  14. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>if</strong></span>(m.start()<wbr>!=<wbr><span style="word-wrap:normal; word-break:normal; color:rgb(192,0,0)">0</span>)<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  15. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>m.appendReplacement(sb,<wbr>(<span style="word-wrap:normal; word-break:normal; color:blue">"_"</span>+m.group()).toLowerCase());<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  16. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  17. <wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span style="word-wrap:normal; word-break:normal; color:rgb(127,0,85)"><strong>return</strong></span><wbr>m.appendTail(sb).toString().toLowerCase();<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  18. <wbr><wbr><wbr><wbr>}<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>



图4 JUnit 运行失败界面<wbr></wbr>
java<wbr>单元测试利器JUnit4<wbr></wbr>

<wbr><wbr><wbr>JUnit 将测试失败的情况分为两种:failure 和 error。Failure 一般由单元测试使用的断言方法判断失败引起,它表示在测试点发现了问题;而 error 则是由代码异常引起,这是测试目的之外的发现,它可能产生于测试代码本身的错误(测试代码也是代码,同样无法保证完全没有缺陷),也可能是被测试代码中的一个隐藏的bug。<wbr></wbr></wbr></wbr></wbr>

请牢记!<wbr></wbr>

<wbr><wbr><wbr>请牢记这一条 JUnit 最佳实践:测试任何可能的错误。单元测试不是用来证明您是对的,而是为了证明您没有错。<wbr></wbr></wbr></wbr></wbr>
<wbr><wbr></wbr></wbr>
<wbr><wbr><wbr>啊哈,再次运行测试,绿条又重现眼前。通过对 WordDealUtil.wordFormat4DB 比较全面的单元测试,现在的代码已经比较稳定,可以作为 API 的一部分提供给其它模块使用了。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>不知不觉中我们已经使用 JUnit 漂亮的完成了一次单元测试。可以体会到 JUnit是多么轻量级,多么简单,根本不需要花心思去研究,这就可以把更多的注意力放在更有意义的事情上——编写完整全面的单元测试</wbr></wbr></wbr>
分享到:
评论

相关推荐

    Android单元测试入门详解1

    Android 单元测试入门Start简单了解一下,如何依赖 Junit 进行 Java 代码的单元测试。依旧如何借助 Robolectric 进行 Andro

    android开发入门与实战(下)

    第4章 赚钱的市场——AndroidMarket及应用发布 4.1 GoogleMarket产生背景与目的 4.2 体验“选货”的乐趣——在G1上体验Market的使用 4.3 Android开发活动及特色应用 4.3.1 开发应用的领域 4.3.2 AndroidMarket特色...

    [14本经典Android开发教程]-7-Android编程入门教程

    [14本经典Android开发教程]-7-Android编程入门教程 -------------------------------------------------- 本文为以前已经使用Java编程并想开始为Android平台开发的开发者编写。我试着尽可能地多的"展开",在合适的每...

    calabash-android-java:用 Java 编写葫芦 android 测试

    下载下载最新版本的入门下载并在您的环境中设置 ANDROID_HOME 和 JAVA_HOME。 Calabash-android-java 依赖于几个 jars。 因此,在运行测试时将以下 jars 添加到类路径中。 ├── calabash-android-java-&lt;version&gt;....

    android开发入门与实战(上)

    第4章 赚钱的市场——AndroidMarket及应用发布 4.1 GoogleMarket产生背景与目的 4.2 体验“选货”的乐趣——在G1上体验Market的使用 4.3 Android开发活动及特色应用 4.3.1 开发应用的领域 4.3.2 AndroidMarket特色...

    《Google Android开发入门与实战》.pdf

    1.4 真实体验——android模拟器 4 1.4.1 模拟器概述 4 1.4.2 模拟器和真机的区别 4 1.4.3 模拟器使用注意事项 4 1.5 更上一层楼——加入android开发社区 5 1.6 本章小结 6 第2章 工欲善其事 必...

    java开源包4

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    android开发入门教程

    14.1.5 豆瓣网APIJava库介绍 14.2 豆瓣网(Web2.0)客户端设计 14.2.1 客户端功能规划设计 14.2.2 UI和交互流程设计 14.2.3 数据存储设计 14.3 豆瓣网(Web2.0)客户端实现 14.3.1 申请APIKey 14.3.2 Activity实现 14.4 ...

    Google.Android开发入门与实战

    内容简介  《Android开发入门与实战》内容上涵盖了用Android开发的大部分场景,从Android基础介绍、... 最后,祝广大开发者的技术日益精进,早日开始Android开发之旅,赶上移动互联网的第一班车,共赢中国3G未来!

    课程设计-Java基于Android的身心健康守护APP系统源码+项目说明.zip

    课程设计-Java基于Android的身心健康守护APP系统源码+项目说明.zip课程设计-Java基于Android的身心健康守护APP系统源码+项目说明.zip课程设计-Java基于Android的身心健康守护APP系统源码+项目说明.zip 1.健康 步数 ...

    Android 初学中阶高阶书籍_集合打包2

    Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...

    Android 初学中阶高阶书籍_集合打包3

    Google.Android开发入门与实战,Android 精通Android游戏开发,3G应用开发之Android,15个Android很有用的代码片 段,Android 图像处理篇,Android_CTS测试研,GoogleMaps基础开发教程,Android_GPS架构分析,android_JNI...

    Android基础教程

    以及本地数据存储等基础知识,而且通过“Hello, Android”项目深入探讨了外部通信、基于位置的服务、内置SQLite数据库、3D图形、多点触控、小部件、兼容性测试,以及如何向AndroidMarket发布应用程序等内容。...

    ARM Cortex-A8和Android 4.x联动报警系统

    第四部分,讲解了Linux设备驱动开发环境搭建、内核开发相关理论,然后将裸机下的接口驱动移植到Android环境下,并通过NDK和JAVA界面测试通过;第五部分,通过一个实战项目,综合应用各个模块的知识,为毕业设计 、...

    Google Android开发入门与实战的代码

    Google Android开发入门与实战的代码 1章 掀起你的盖头来——初识Android. 1 1.1 认识Android 1 1.2 Android的背景 2 1.2.1 Android的历史 2 1.2.2 Android的发展 2 1.3 我的Android我做主 2 ...

    [14本经典Android开发教程]-4-Android应用程序开发36技

    [14本经典Android开发教程]-4-Android应用程序开发36技 本书共分为4篇: ※ 第一篇:介绍应用框架概念、原理和特性。 ※ 第二篇:阐述应用框架之设计技巧。亦即,如何打造应用框架。 (注:如果你的职务是「使用」...

    【基于Selenium 2 (java+jUnit+testNg)的自动化测试-从入门到精通】白洛.著

    第4章 初始selenium webdriver 第5章 玩转selenium webdriver 第6章 selenium玩转android 第7章 selenium玩转IOS 第8章 selenium玩转Raspberry pi 第9章 selenium grid 第10章 selenium的兄弟姐妹

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

Global site tag (gtag.js) - Google Analytics