﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-冉翔的技术专栏-文章分类-08.tools</title><link>http://www.blogjava.net/ranxiang/category/4388.html</link><description>关注于J2SE，J2EE以及开源方面的技术。</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 09:18:23 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 09:18:23 GMT</pubDate><ttl>60</ttl><item><title>【转载】Eclipse快捷键</title><link>http://www.blogjava.net/ranxiang/articles/35121.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Mon, 13 Mar 2006 12:00:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/35121.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/35121.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/35121.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/35121.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/35121.html</trackback:ping><description><![CDATA[<P>原贴地址：<A href="http://www.eclipseworld.org/bbs/read.php?tid=102&amp;fpage=1">http://www.eclipseworld.org/bbs/read.php?tid=102&amp;fpage=1</A><BR><BR>本文档从Eclipse软件上整理，是列出了标准的快捷键，未列出Emacs快捷键。<BR>转贴请注明作者和出处。</P>
<P>编辑<BR>作用域 功能 快捷键<BR>全局 查找并替换 Ctrl+F<BR>文本编辑器 查找上一个 Ctrl+Shift+K<BR>文本编辑器 查找下一个 Ctrl+K<BR>全局 撤销 Ctrl+Z<BR>全局 复制 Ctrl+C<BR>全局 恢复上一个选择 Alt+Shift+↓<BR>全局 剪切 Ctrl+X<BR>全局 快速修正 Ctrl1+1<BR>全局 内容辅助 Alt+/<BR>全局 全部选中 Ctrl+A<BR>全局 删除 Delete<BR>全局 上下文信息 Alt+？<BR>Alt+Shift+?<BR>Ctrl+Shift+Space<BR>Java编辑器 显示工具提示描述 F2<BR>Java编辑器 选择封装元素 Alt+Shift+↑<BR>Java编辑器 选择上一个元素 Alt+Shift+←<BR>Java编辑器 选择下一个元素 Alt+Shift+→<BR>文本编辑器 增量查找 Ctrl+J<BR>文本编辑器 增量逆向查找 Ctrl+Shift+J<BR>全局 粘贴 Ctrl+V<BR>全局 重做 Ctrl+Y</P>
<P>?<BR>查看<BR>作用域 功能 快捷键<BR>全局 放大 Ctrl+=<BR>全局 缩小 Ctrl+-</P>
<P>?<BR>窗口<BR>作用域 功能 快捷键<BR>全局 激活编辑器 F12<BR>全局 切换编辑器 Ctrl+Shift+W<BR>全局 上一个编辑器 Ctrl+Shift+F6<BR>全局 上一个视图 Ctrl+Shift+F7<BR>全局 上一个透视图 Ctrl+Shift+F8<BR>全局 下一个编辑器 Ctrl+F6<BR>全局 下一个视图 Ctrl+F7<BR>全局 下一个透视图 Ctrl+F8<BR>文本编辑器 显示标尺上下文菜单 Ctrl+W<BR>全局 显示视图菜单 Ctrl+F10<BR>全局 显示系统菜单 Alt+-</P>
<P>?<BR>导航<BR>作用域 功能 快捷键<BR>Java编辑器 打开结构 Ctrl+F3<BR>全局 打开类型 Ctrl+Shift+T<BR>全局 打开类型层次结构 F4<BR>全局 打开声明 F3<BR>全局 打开外部javadoc Shift+F2<BR>全局 打开资源 Ctrl+Shift+R<BR>全局 后退历史记录 Alt+←<BR>全局 前进历史记录 Alt+→<BR>全局 上一个 Ctrl+,<BR>全局 下一个 Ctrl+.<BR>Java编辑器 显示大纲 Ctrl+O<BR>全局 在层次结构中打开类型 Ctrl+Shift+H<BR>全局 转至匹配的括号 Ctrl+Shift+P<BR>全局 转至上一个编辑位置 Ctrl+Q<BR>Java编辑器 转至上一个成员 Ctrl+Shift+↑<BR>Java编辑器 转至下一个成员 Ctrl+Shift+↓<BR>文本编辑器 转至行 Ctrl+L</P>
<P><BR>搜索<BR>作用域 功能 快捷键<BR>全局 出现在文件中 Ctrl+Shift+U<BR>全局 打开搜索对话框 Ctrl+H<BR>全局 工作区中的声明 Ctrl+G<BR>全局 工作区中的引用 Ctrl+Shift+G</P>
<P>?<BR>文本编辑<BR>作用域 功能 快捷键<BR>文本编辑器 改写切换 Insert<BR>文本编辑器 上滚行 Ctrl+↑<BR>文本编辑器 下滚行 Ctrl+↓</P>
<P>?<BR>文件<BR>作用域 功能 快捷键<BR>全局 保存 Ctrl+X<BR>Ctrl+S<BR>全局 打印 Ctrl+P<BR>全局 关闭 Ctrl+F4<BR>全局 全部保存 Ctrl+Shift+S<BR>全局 全部关闭 Ctrl+Shift+F4<BR>全局 属性 Alt+Enter<BR>全局 新建 Ctrl+N</P>
<P><BR>项目<BR>作用域 功能 快捷键<BR>全局 全部构建 Ctrl+B</P>
<P><BR>源代码<BR>作用域 功能 快捷键<BR>Java编辑器 格式化 Ctrl+Shift+F<BR>Java编辑器 取消注释 Ctrl+\<BR>Java编辑器 注释 Ctrl+/<BR>Java编辑器 添加导入 Ctrl+Shift+M<BR>Java编辑器 组织导入 Ctrl+Shift+O<BR>Java编辑器 使用try/catch块来包围 未设置，太常用了，所以在这里列出,建议自己设置。<BR>也可以使用Ctrl+1自动修正。</P>
<P>?<BR>运行<BR>作用域 功能 快捷键<BR>全局 单步返回 F7<BR>全局 单步跳过 F6<BR>全局 单步跳入 F5<BR>全局 单步跳入选择 Ctrl+F5<BR>全局 调试上次启动 F11<BR>全局 继续 F8<BR>全局 使用过滤器单步执行 Shift+F5<BR>全局 添加/去除断点 Ctrl+Shift+B<BR>全局 显示 Ctrl+D<BR>全局 运行上次启动 Ctrl+F11<BR>全局 运行至行 Ctrl+R<BR>全局 执行 Ctrl+U</P>
<P><BR>重构<BR>作用域 功能 快捷键<BR>全局 撤销重构 Alt+Shift+Z<BR>全局 抽取方法 Alt+Shift+M<BR>全局 抽取局部变量 Alt+Shift+L<BR>全局 内联 Alt+Shift+I<BR>全局 移动 Alt+Shift+V<BR>全局 重命名 Alt+Shift+R<BR>全局 重做 Alt+Shift+Y</P><img src ="http://www.blogjava.net/ranxiang/aggbug/35121.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2006-03-13 20:00 <a href="http://www.blogjava.net/ranxiang/articles/35121.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读笔记]单元测试之道Java版------使用JUnit------(2) 测试哪些内容：Right-BICEP</title><link>http://www.blogjava.net/ranxiang/articles/32364.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Fri, 24 Feb 2006 17:52:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/32364.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/32364.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/32364.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/32364.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/32364.html</trackback:ping><description><![CDATA[

<h1><span style="font-family: 宋体;">第</span><span lang="EN-US">4</span><span style="font-family: 宋体;">章</span> <span style="font-family: 宋体;">测试哪些内容：</span><span lang="EN-US">Right-BICEP</span></h1>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.1 </span><span style="font-family: 黑体;">结果是否正确</span> <span style="color: red;" lang="EN-US">Right</span><span style="font-weight: normal;" lang="EN-US">-BICEP </span></h2>

<h3><span style="font-family: 宋体;">如果代码能够运行正确，我要怎么才知道它是正确的呢</span></h3>

<p class="MsoNormal"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">如果你不能很好地回答这个问题，那么编写代码——或者测试——完全就是在浪费时间。</span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">在代码的整个生命期中，“正确”的定义可能会不断在变；但是无论如何，你至少需要确认代码所做的和你的期望是一致的。</span></p>

<h3><span style="font-family: 宋体;">·使用数据文件</span></h3>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">对于许多有大量测试数据的测试，你可能会考虑用一个独立的数据文件来存储这些测试数据，然后让单元测试读取该文件。</span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">多注意一下测试数据。经验告诉我们，测试数据比代码更有可能是错的，特别是人工计算的，或者来自原有系统计算结果的测试数据。因此，当测试数据显示有错误发生的时间，你应该在怀疑代码前先对测试数据检查两三遍。</span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">一个原则是：对于验证被测方法是正确的这件事情，如果某些做法能够使它变得更加容易，那么就采纳它吧。</span></p>

<p class="MsoNormal" style="margin-left: 10.5pt; text-indent: -10.5pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.2 </span><span style="font-family: 黑体;">边界条件</span> <span style="font-weight: normal;" lang="EN-US">Right-</span><span style="color: red;" lang="EN-US">B</span><span style="font-weight: normal;" lang="EN-US">ICEP</span></h2>

<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">找边界条件是做单元测试中最有价值的工作之一，因为</span><span lang="EN-US">bug</span><span style="font-family: 宋体;">一般就出现在边界上。一些需要你考虑得条件有。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span style="font-family: 宋体;">·完全伪造或者不一致的输入数据，例如一个名为“</span><span lang="EN-US">!*W:X\&amp;Gi/w~&gt;g/h#WQ@</span><span style="font-family: 宋体;">”的文件。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span style="font-family: 宋体;">·格式错误的数据，例如没有顶层域名的电子邮件地址就像</span><span lang="EN-US">fred@foobar</span><span style="font-family: 宋体;">这样的。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span style="font-family: 宋体;">·控制或者不完整的值（如</span><span lang="EN-US">0, 0.0, “”</span><span style="font-family: 宋体;">和</span><span lang="EN-US">null</span><span style="font-family: 宋体;">）。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span style="font-family: 宋体;">·一些与意料中的合理值相去甚远的数值。例如一个人的岁数为</span><span lang="EN-US">10000</span><span style="font-family: 宋体;">岁。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span style="font-family: 宋体;">·如果要求的是一个不允许出现重复数值的</span><span lang="EN-US">list</span><span style="font-family: 宋体;">，但是传入的是一个存在重复数值的</span><span lang="EN-US">list</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal" style="margin-left: 21pt; text-indent: -10.5pt;"><span style="font-family: 宋体;">·如果要求的是一个有序</span><span lang="EN-US">list</span><span style="font-family: 宋体;">，但是传入的是一个无序的</span><span lang="EN-US">list</span><span style="font-family: 宋体;">；或者反之。例如，给一个要求排好序的算法传入一个未排序的</span><span lang="EN-US">list</span><span style="font-family: 宋体;">——甚至一个反序的</span><span lang="EN-US">list</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal" style="margin-left: 21pt; text-indent: -10.5pt;"><span style="font-family: 宋体;">·事情到达的次序是错误的，或者碰巧和期望的次序不一致。例如，在未登录系统之前，就尝试打印文档。</span></p>

<p class="MsoNormal" style="margin-left: 21pt; text-indent: -10.5pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 19.3pt;"><span style="font-family: 宋体;">一个向导可能的边界条件</span><b style=""><span lang="EN-US">CORRECT</span></b><span style="font-family: 宋体;">。对于其中的每一条，都应该想想它是否与存在于被测方法中的某个条件非常类似，而当这些条件被违反的时，出现的又是什么情况。</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">C</span></b><span lang="EN-US">onformance</span><span style="font-family: 宋体;">（一致性）——值是否和预期的一致。</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">O</span></b><span lang="EN-US">rdering</span><span style="font-family: 宋体;">（顺序性）——值是否如应该的那样，是有序或者无序的。</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">R</span></b><span lang="EN-US">ange</span><span style="font-family: 宋体;">（区间性）——值是否位于合理的最小值和最大值之内。</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">R</span></b><span lang="EN-US">eference</span><span style="font-family: 宋体;">（依赖性）——代码是否引用了一些不再代码本身控制范围之内的外部资源。</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">E</span></b><span lang="EN-US">xistence</span><span style="font-family: 宋体;">（存在性）——值是否存在（例如，是否是非</span><span lang="EN-US">null</span><span style="font-family: 宋体;">，非</span><span lang="EN-US">0</span><span style="font-family: 宋体;">，再一个集合中等等）</span></p>

<p class="MsoNormal" style="text-indent: 8.9pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">C</span></b><span lang="EN-US">ardinatity</span><span style="font-family: 宋体;">（基数性）——是否恰好有足够的值？</span></p>

<p class="MsoNormal" style="margin-left: 19.4pt; text-indent: -10.5pt;"><span style="font-family: 宋体;">·</span><b style=""><span lang="EN-US">T</span></b><span lang="EN-US">ime</span><span style="font-family: 宋体;">（相对或者绝对的时间性）——所有事情的发生是否是有序的？是否是在正确的时刻？是否恰好及时？</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.3 </span><span style="font-family: 黑体;">检查反向关联</span> <span style="font-weight: normal;" lang="EN-US">Right-B</span><span style="color: red;" lang="EN-US">I</span><span style="font-weight: normal;" lang="EN-US">CEP</span></h2>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">对于一些方法，我们可以使用反向的逻辑关系来验证它们。</span></p>

<p class="MsoNormal" style="text-indent: 10.5pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">要注意的是：当你同时编写了原方法和它的反向测试时，一些</span><span lang="EN-US">bug</span><span style="font-family: 宋体;">可能会被在两个函数中都出现的错误所掩盖。在可能的情况下，应该使用不同的原理来编写反向测试。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.4 </span><span style="font-family: 黑体;">使用其他手段来实现交叉检查</span> <span style="font-weight: normal;" lang="EN-US">Right-BI</span><span style="color: red;" lang="EN-US">C</span><span style="font-weight: normal;" lang="EN-US">EP</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">通常而言，计算一个量会有一种以上的算法。我们可能会基于运行效率或者其他的特性，来选择算法。那是我们要在产品中使用的；但是在测试用的系统中，可以使用剩下算法中的一个来交叉测试结果。当确实存在一种经过验证并能完成任务的算法，只是由于速度太慢或者太不灵活而没有在产品代码中使用，这种交叉检查的技术将非常有效。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">另一种办法就是：使用类本身不同组成部分的数据，并且确信它们能和“合起来”。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.5 </span><span style="font-family: 黑体;">强制产生错误条件</span> <span style="font-weight: normal;" lang="EN-US">Right-BIC</span><span style="color: red;" lang="EN-US">E</span><span style="font-weight: normal;" lang="EN-US">P</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">在真实世界中，错误总是会发生：磁盘会慢，网络连线会断开，电子邮件会多的像掉进了黑洞，而程序会崩溃。你应当能够通过强制引发错误，来测试你的代码是如何处理所有这些真实世界中的问题的。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">4.6 </span><span style="font-family: 黑体;">性能特性</span> <span style="font-weight: normal;" lang="EN-US">Right-BICE</span><span style="color: red;" lang="EN-US">P</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">一个检查起来会很有益处的部分是性能特性，而不是性能本身。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">你也许需要一些测试辅助工具。它们嫩构提供对单个测试进行计时，模拟告负在情况之类的功能，比如免费的</span><span lang="EN-US">JUnitPerf</span><span style="font-family: 宋体;">。</span></p>

<img src ="http://www.blogjava.net/ranxiang/aggbug/32364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2006-02-25 01:52 <a href="http://www.blogjava.net/ranxiang/articles/32364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读笔记]单元测试之道Java版------使用JUnit------(1) 序言&amp;使用JUnit编写测试</title><link>http://www.blogjava.net/ranxiang/articles/32310.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Fri, 24 Feb 2006 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/32310.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/32310.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/32310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/32310.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/32310.html</trackback:ping><description><![CDATA[

<p class="MsoNormal"><span style="font-family: 宋体;">单元测试之道</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">版</span><span lang="EN-US">------</span><span style="font-family: 宋体;">使用</span><span lang="EN-US">JUnit------</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h1><span style="font-family: 宋体;">第</span><span lang="EN-US">1</span><span style="font-family: 宋体;">章</span> <span style="font-family: 宋体;">序言</span><span style="font-size: 10.5pt; line-height: 240%;" lang="EN-US"><o:p></o:p></span></h1>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·什么是单元测试</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">单元测试是开发者编写的一小段代码，用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言，一个单元测试是用于判断某个特定条件（或者场景）下某个特定函数的行为。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·为什么要使用单元测试</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">单元测试不但会使你的工作完成得更轻松，而且会令你的设计变得更好。甚至大大减少你花在调试上面的时间。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·不写测试的借口</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">编写单元测试太花时间了</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">运行测试的时间太长了</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">测试代码并不是我的工作</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">我并不清楚代码的行为，所以也就无从测试</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">但是这些代码都能够编译通过</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">公司请我来试我是为了写代码，而不是写测试</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">如果我让测试员或者</span><span lang="EN-US">QA</span><span style="font-family: 宋体;">人员没有工作，那么我会觉得很内疚</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">我的公司并不会让我在真实系统中运行单元测试</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h1><span style="font-family: 宋体;">第</span><span lang="EN-US">3</span><span style="font-family: 宋体;">章</span> <span style="font-family: 宋体;">使用</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">编写测试</span></h1>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.1 </span><span style="font-family: 黑体;">构建单元测试</span></h2>

<p class="MsoNormal"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">测试代码必须要做以下几件事情：</span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·准备测试所需要的各种条件（创建所有必须的对象，分配必要的资源等等）。</span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·调用要测试的方法。</span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·验证被测试方法的行为和期望是否一致。</span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·完成后清理各种资源。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.2 JUnit</span><span style="font-family: 黑体;">的各种断言</span></h2>

<p class="MsoNormal"><span lang="EN-US"><span style="">&nbsp;
</span>JUnit</span><span style="font-family: 宋体;">提供了一些辅助函数，用于帮助你确定某个被测试函数是否工作正常。通常而言，我们把所有这些函数统称为断言。断言是单元测试最基本的组成部分。</span></p>

<p class="MsoNormal"><span lang="EN-US"><span style="">&nbsp; </span></span><span style="font-family: 宋体;">当一个失败或错误出现的时候，当前测试方法的执行流程将会被种植，但是（位于同一个测试类中的）其他测试将会继续运行。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span lang="EN-US"><span style="">&nbsp;</span></span><span style="font-family: 宋体;">·</span><span lang="EN-US"> assertEquals</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertEquals([String
message],</span></p>

<p class="MsoNormal" style="text-indent: 79.5pt;"><span lang="EN-US">expected,</span></p>

<p class="MsoNormal" style="text-indent: 79.5pt;"><span lang="EN-US">actual)</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">这是使用得最多的断言形式。在上面的参数中，</span><span lang="EN-US">expected</span><span style="font-family: 宋体;">是你的期望值（通常都是硬编码的），</span><span lang="EN-US">actual</span><span style="font-family: 宋体;">是被测试代码实际产生的值，</span><span lang="EN-US">message</span><span style="font-family: 宋体;">是一个可选的消息，如果提供的话，将会在发生错误的时候报告这个消息。当然，你完全可以不提供这个</span><span lang="EN-US">message</span><span style="font-family: 宋体;">参数，而只提供</span><span lang="EN-US">expected</span><span style="font-family: 宋体;">和</span><span lang="EN-US">value</span><span style="font-family: 宋体;">这两个值。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">任何对象都可以拿来做相等性测试：适当的相等性判断方法会被用来做这样的比较。值得注意的是使用原生数组的</span><span lang="EN-US">equals</span><span style="font-family: 宋体;">方法时，它并不是比较数组的内容，而只是比较数组引用本身，而这大概不是你希望的吧。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">计算机并不能精确地表示所有的浮点数，通常都会有一些偏差。因而，如果你想用断言来比较浮点数（在</span><span lang="EN-US">Java</span><span style="font-family: 宋体;">中，是类型为</span><span lang="EN-US">float</span><span style="font-family: 宋体;">或者</span><span lang="EN-US">double</span><span style="font-family: 宋体;">的数），则需要制定一个额外的误差参数。它表明你需要多接近才能认为两数“相等”。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertEquals([String
message],</span></p>

<p class="MsoNormal" style="text-indent: 79.5pt;"><span lang="EN-US">expected,</span></p>

<p class="MsoNormal" style="text-indent: 79.5pt;"><span lang="EN-US">actual,</span></p>

<p class="MsoNormal" style="text-indent: 79.5pt;"><span lang="EN-US">tolerance)</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·</span><span lang="EN-US">assertNull</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertNull([String
message], java.lang.Object object)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertNotNull([String
message], java.lang.Object object)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">验证一个给定的对象是否为</span><span lang="EN-US">null</span><span style="font-family: 宋体;">（或者为非</span><span lang="EN-US">null</span><span style="font-family: 宋体;">），如果答案为否，则将会失败。</span><span lang="EN-US">message</span><span style="font-family: 宋体;">参数是可选的。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·</span><span lang="EN-US">assertSame</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertSame([String
message], expected, actual)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">验证</span><span lang="EN-US">expected</span><span style="font-family: 宋体;">参数和</span><span lang="EN-US">actual</span><span style="font-family: 宋体;">参数所引用的是否为同一个对象，如果不是的话，将会失败。</span><span lang="EN-US">message</span><span style="font-family: 宋体;">参数是可选的。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertNotSame([String
message], expected, actual)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">验证</span><span lang="EN-US">expected</span><span style="font-family: 宋体;">参数和</span><span lang="EN-US">actual</span><span style="font-family: 宋体;">参数所应用的是否为不同的对象，如果是相同的话，将会失败。</span><span lang="EN-US">message</span><span style="font-family: 宋体;">参数是可选的。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·</span><span lang="EN-US">assertTrue</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertTrue([String
message], Boolean condition)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">验证给定的二元条件是否为真，如果为假的话，将会失败。</span><span lang="EN-US">meesage</span><span style="font-family: 宋体;">参数是可选的。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">如果你发现测试代码像下面这样，宛如废话一般：</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">asserTrue(true);</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">那么你就该好好想想这些代码了。对于这种写法，除非是被用于确认某个分支，或者一场逻辑才有可能是正确的选择；否则的话，很可能就是一个糟糕的主意。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">assertFalse([String
message], Boolean condition)</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">上面的代码用于验证给定的二元条件是否为假。如果不是的话，该测试将会失败。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h3><span style="font-family: 宋体;">·</span><span lang="EN-US">fail</span></h3>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">fail([String
message])</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">上面的断言将会使测试立即失败，其中</span><span lang="EN-US">message</span><span style="font-family: 宋体;">参数是可选的。这种断言通常被用于标记某个不应该被到达的分支（譬如，在一个与预期发生的异常之后）。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·使用断言</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">一般而言，一个测试方法会包含有多个断言，因为你需要验证该方法的多个方面以及内在的多种联系。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">当有测试失败的时候，无论如何都不能给原有代码再添加新的特性！此时你应该尽快地修复这个错误，直到让所有的测试都能顺利通过。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.3 JUnit</span><span style="font-family: 黑体;">框架</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">每个包含测试的类都必须如所示那样由</span><span lang="EN-US">TestCase</span><span style="font-family: 宋体;">继承而来。基类</span><span lang="EN-US">TestCase</span><span style="font-family: 宋体;">提供了我们所需的大部分单元测试功能，包括所有在前面讲述过的断言方法。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">基类需要一个以</span><span lang="EN-US">String</span><span style="font-family: 宋体;">为参数的构造函数，因而我们必须调用</span><span lang="EN-US">super</span><span style="font-family: 宋体;">以传递这么一个名字。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">测试类包含了名为</span><span lang="EN-US">test…</span><span style="font-family: 宋体;">的方法。而所有以</span><span lang="EN-US">test</span><span style="font-family: 宋体;">开头的方法都会被</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">自动运行。你还可以通过定义</span><span lang="EN-US">suite</span><span style="font-family: 宋体;">方法制定特殊的函数来运行。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.4 JUnit</span><span style="font-family: 黑体;">测试的组成</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">一个测试类包含一些测试方法；每个方法包含一个或者多个断言语句。但是测试类也能调用其它测试类：单独的类、包、甚至完整的一个系统。可以通过创建</span><span lang="EN-US">test suite</span><span style="font-family: 宋体;">来取得。任何测试类都能包含一个名为</span><span lang="EN-US">suite</span><span style="font-family: 宋体;">的静态方法。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">public static
Test suite();</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">你可以提供</span><span lang="EN-US">suite()</span><span style="font-family: 宋体;">方法来返回任何你想要的测试集合（没有</span><span lang="EN-US">suite()</span><span style="font-family: 宋体;">方法，</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">会自动运行所有的</span><span lang="EN-US">test…</span><span style="font-family: 宋体;">方法）。但是你可能需要手工添加特殊的测试，包括其他</span><span lang="EN-US">suite</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·</span><span lang="EN-US"> Per-method</span><span style="font-family: 宋体;">的</span><span lang="EN-US">Setup</span><span style="font-family: 宋体;">和</span><span lang="EN-US">Tear-down</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">的</span><span lang="EN-US">TestCase</span><span style="font-family: 宋体;">基类提供两个方法供你改写，分别用于环境的建立和清理：</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">protected void setup();</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US">protected void teardown();</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">·</span><span lang="EN-US"> Per-suite
Setup</span><span style="font-family: 宋体;">和</span><span lang="EN-US">Tear-down</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">一般而言，你只须针对每个方法设置运行环境；但是在某些情况下，你须为整个</span><span lang="EN-US">test suite</span><span style="font-family: 宋体;">设置一些环境，以及在</span><span lang="EN-US">test suite</span><span style="font-family: 宋体;">中的所有方法都执行完成后做一些清理工作。要达到这种效果，你需要</span><span lang="EN-US">per-suite setup</span><span style="font-family: 宋体;">和</span><span lang="EN-US">per-suite teardown</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">Per-suite</span><span style="font-family: 宋体;">的</span><span lang="EN-US">setup</span><span style="font-family: 宋体;">要复杂一些。你需要提供所需测试的一个</span><span lang="EN-US">suite</span><span style="font-family: 宋体;">（无论通过什么样的方式）并且把它包装进一个</span><span lang="EN-US">TestSetup</span><span style="font-family: 宋体;">对象。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">注意你可以在同一个类中同时使用</span><span lang="EN-US">per-sutie</span><span style="font-family: 宋体;">和</span><span lang="EN-US">per-test</span><span style="font-family: 宋体;">的</span><span lang="EN-US">setup()</span><span style="font-family: 宋体;">和</span><span lang="EN-US">teardown</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.5 </span><span style="font-family: 黑体;">自定义</span><span lang="EN-US">JUnit</span><span style="font-family: 黑体;">断言</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">如果你有需要在整个项目中共享的断言或者公共代码，你也许需要考虑从</span><span lang="EN-US">TestCase</span><span style="font-family: 宋体;">继承一个类并且使用这个字类来进行所有的测试。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">事实上，开始新项目时总是从自己的自定义基类继承而不直接从</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">的类继承通常是一个好主意——即便你的基类在一开始没有添加任何额外的功能。这样做的好处是当你需要添加一个所有测试类都需要的方法或者能力时，可以简单地编辑你的基类而不需要改动项目中的所有</span><span lang="EN-US">test case</span><span style="font-family: 宋体;">。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.6 JUnit</span><span style="font-family: 黑体;">和异常</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">对于测试而言，下面两种异常是我们可能会感兴趣的：</span></p>

<p class="MsoNormal" style="margin-left: 39.75pt; text-indent: -18pt;"><!--[if !supportLists]--><span style="" lang="EN-US"><span style="">1．<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">从测试代码抛出的可预测异常。</span></p>

<p class="MsoNormal" style="margin-left: 39.75pt; text-indent: -18pt;"><!--[if !supportLists]--><span style="" lang="EN-US"><span style="">2．<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">由于某个模块（或代码）发生严重错误，而抛出的不可预测异常。</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">任何对</span><span lang="EN-US">assertTrue(true)</span><span style="font-family: 宋体;">的使用都应该被翻译为“我预期控制流程会达到这个地方”。这对将来可能的误解来说会起到强有力的文档的作用。然而，不要忘记一个</span><span lang="EN-US">assertTrue(true)</span><span style="font-family: 宋体;">没有被调用不会产生任何错误的。</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">通常而言，对于方法中每个被期望的异常，你都应该写一个专门的测试来确认该方法在应该抛出异常的时候确实会抛出异常。</span></p>

<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">对于处于出乎意料的异常，你最好简单的改变你的测试方法的声明让它能抛出可能的异常。</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">框架可以捕获任何异常，并且把它报告为一个错误，这些都不需要你的参与。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.7 </span><span style="font-family: 黑体;">关于命名的更多说明</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">如果编写了一个测试，但是实现代码还没有准备好，可以将以“</span><span lang="EN-US">test</span><span style="font-family: 宋体;">”打头的测试方法名米功能为别的，譬如把“</span><span lang="EN-US">test</span><span style="font-family: 宋体;">”去掉，然后等准备好了要来运行测试的时候再改回来。</span></p>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">无论如何，你要避免养成忽略“失败的测试结果”的习惯。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<h2><span lang="EN-US">3.8 JUnit</span><span style="font-family: 黑体;">测试骨架</span></h2>

<p class="MsoNormal" style="text-indent: 21.75pt;"><span style="font-family: 宋体;">用</span><span lang="EN-US">JUnit</span><span style="font-family: 宋体;">写测试真正所需要的就三件事：</span></p>

<p class="MsoNormal" style="margin-left: 39.75pt; text-indent: -18pt;"><!--[if !supportLists]--><span style="" lang="EN-US"><span style="">1．<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">一个</span><span lang="EN-US">import</span><span style="font-family: 宋体;">语句引入所有</span><span lang="EN-US">junit.framework.*</span><span style="font-family: 宋体;">下的类。</span></p>

<p class="MsoNormal" style="margin-left: 39.75pt; text-indent: -18pt;"><!--[if !supportLists]--><span style="" lang="EN-US"><span style="">2．<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">一个</span><span lang="EN-US">extends</span><span style="font-family: 宋体;">语句让你的类从</span><span lang="EN-US">TestCase</span><span style="font-family: 宋体;">继承。</span></p>

<p class="MsoNormal" style="margin-left: 39.75pt; text-indent: -18pt;"><!--[if !supportLists]--><span style="" lang="EN-US"><span style="">3．<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">一个调用</span><span lang="EN-US">super(string)</span><span style="font-family: 宋体;">的构造函数。</span></p>

<img src ="http://www.blogjava.net/ranxiang/aggbug/32310.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2006-02-24 16:45 <a href="http://www.blogjava.net/ranxiang/articles/32310.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我收集的Eclipse及相关插件的资料（持续完善ING）</title><link>http://www.blogjava.net/ranxiang/articles/23157.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Fri, 09 Dec 2005 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/23157.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/23157.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/23157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/23157.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/23157.html</trackback:ping><description><![CDATA[<P>我收集的Eclipse及相关插件的资料（持续完善ING）</P>
<P>Eclipse官方主页：<A href="http://www.eclipse.org">http://www.eclipse.org</A></P>
<P><BR>Myeclipse：一个基于Eclipse的很全面好用的J2EE开发平台（需付费使用）<BR>主页：<A href="http://www.myeclipseide.com">http://www.myeclipseide.com</A></P>
<P><BR>VE Editor：图形化的开发GUI界面的插件。<BR>主页：<A href="http://www.eclipse.org/vep/">http://www.eclipse.org/vep/</A><BR>&nbsp;&nbsp;&nbsp;&nbsp; 先决条件是安装EMF和GET。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EMF：<A href="http://www.eclipse.org/emf/">http://www.eclipse.org/emf/</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GEF：<A href="http://www.eclipse.org/gef/">www.eclipse.org/gef/</A></P>
<P><BR>XMLBuddy：很不错的开发XML插件。<BR>主页：<A href="http://xmlbuddy.com">http://xmlbuddy.com</A></P>
<P><BR>Lomboz：开发J2EE首选插件。<BR>主页：<A href="http://www.objectlearn.com/">http://www.objectlearn.com/</A></P>
<P><BR>sysdeo Tomcat Plugin：一个方便实用的tomcat插件。<BR>主页：<A href="http://www.sysdeo.com/eclipse/tomcatPlugin.html">http://www.sysdeo.com/eclipse/tomcatPlugin.html</A></P>
<P><BR>UML2：一个支持UML开发的插件。<BR>主页：<A href="http://www.eclipse.org/uml2/">http://www.eclipse.org/uml2/</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 先决条件是安装EMF。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EMF：<A href="http://www.eclipse.org/emf/">http://www.eclipse.org/emf/</A></P>
<P><BR>Easy Struts：开发struts的插件。<BR>主页：<A href="http://easystruts.sourceforge.net/">http://easystruts.sourceforge.net/</A></P>
<P><BR>JInto：开发资源文件的一个插件。<BR>主页：<A href="http://www.guh-software.de/jinto_en.html">http://www.guh-software.de/jinto_en.html</A></P>
<P><BR>KeePresident：加快Eclipse速度的插件。（仅适用于Windows平台）<BR>主页：<A href="http://suif.stanford.edu/pub/keepresident/">http://suif.stanford.edu/pub/keepresident/</A></P>
<P><BR>JBossIDE：在JBOSS服务器上的开发J2EE的插件。<BR>主页：<A href="http://www.jboss.com/products/jbosside">http://www.jboss.com/products/jbosside</A></P>
<P>&nbsp;</P>
<P><BR>如果想采取link方式安装插件，可看这篇文章（<A href="http://blog.csdn.net/javamxj/archive/2004/10/11/132311.aspx">点击这里</A>）。<BR>一些介绍eclipse插件使用的地方（<A href="http://blog.csdn.net/javamxj/category/53508.aspx">点击这里</A>）。</P>
<P>你有什么好用的插件吗？留言告诉我，大家一起分享吧：）<BR></P><img src ="http://www.blogjava.net/ranxiang/aggbug/23157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2005-12-09 15:41 <a href="http://www.blogjava.net/ranxiang/articles/23157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Myeclipse插件启动app server遇到的JDK name的怪问题以及解决办法。</title><link>http://www.blogjava.net/ranxiang/articles/23158.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Fri, 09 Dec 2005 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/23158.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/23158.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/23158.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/23158.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/23158.html</trackback:ping><description><![CDATA[
		<!--StartFragment --> 症状描述：使用MyEclipse插件启动app server（tomcat, jboss, sun one server）。均报错，提示我JDK name这个错误。百思不得其解，将eclipse下的configuration文件夹内容删除，发现好用了。但是后来又不好用了，反反复复折腾了很久。终于发现了问题的根本。<br /><br />原来我机器上的JDK好像是1.5.01的，这次重做系统，换成1.5.03的了。然后我在开启eclipse选择缺省路径的时候，如果选择的是我以前用 eclipse开发项目用的路径的时候，因为这个路径包含一下以前的一些eclipse配置或者jdk版本的一些信息，就造成上面所述的JDK name这个错误。如果我在这里选择一个干净的新的目录。那么就一切正常了。我说怎么一会好用一会不好用，原来就是这个开始时候选择目录的问题。<br /><br />解决办法：<br /><br />在MyEclipse的配置下面的App Server配置的tomcat，有个选择JDK的，有时候会自动变成JRE，换成JDK的目录就可以了。<br /><br /><br />之后，就不会出现JDK name的错误了。可以通过myeclipse的插件正常的start和shutdown了。<br /><br /><br /><br />后记：很郁闷的因为这个事情，寻思了差不多一天的时间。而且eclipse，Myeclipse以及各种插件，是装了又删删了又装的，最后才想到这一点。有点笨了。以后一定要加强自己分析问题的思路方面的办法。 <img src ="http://www.blogjava.net/ranxiang/aggbug/23158.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2005-12-09 15:41 <a href="http://www.blogjava.net/ranxiang/articles/23158.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一点心得：关于用myeclipse在struts-config.xml中配置datasource的注意事项</title><link>http://www.blogjava.net/ranxiang/articles/23155.html</link><dc:creator>冉翔</dc:creator><author>冉翔</author><pubDate>Fri, 09 Dec 2005 07:39:00 GMT</pubDate><guid>http://www.blogjava.net/ranxiang/articles/23155.html</guid><wfw:comment>http://www.blogjava.net/ranxiang/comments/23155.html</wfw:comment><comments>http://www.blogjava.net/ranxiang/articles/23155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ranxiang/comments/commentRss/23155.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ranxiang/services/trackbacks/23155.html</trackback:ping><description><![CDATA[<P>&nbsp;<BR>我想这算个BUG吧。</P>
<P>&nbsp;</P>
<P>直接在struts-config.xml中右键data-sources然后New。</P>
<P>默认的type是：</P>
<P>org.apache.struts.util.GenericDataSource</P>
<P>struts自带的一个数据库连接池。</P>
<P>然后正确输入各种property的value。</P>
<P>测试，好用。</P>
<P>&nbsp;</P>
<P>如果将type选择为：</P>
<P>org.apache.commons.dbcp.BasicDataSource</P>
<P>这个DBCP的数据库连接池。</P>
<P>然后键入正确的value。</P>
<P>测试，提示各种异常&amp;找不到Driver。</P>
<P>&nbsp;</P>
<P>查看DBCP的文档，发现MYECLIPSE生成的配置XML元素有问题。</P>
<P>DBCP需要的是driverClassName和username这两个propertys。</P>
<P>而Myeclipse自动生成的是driverClass和user这两个propertys。</P>
<P>&nbsp;</P>
<P>改过来之后发现DBCP的数据库连接池也好用了：）</P>
<P>这应该算是MYECLIPSE开发struts的一个BUG吧，数据库连接池的配置是按照struts默认的GenericDataSource来的。如果能动态的在选择数据库连接池的时候，找寻set()/get()方法来生成属性的名字应该更好。</P>
<P>也看出来不同的数据库连接池在命名规则方面存在的一些差异。</P>
<P>其实很简单的东西，我却花费了半天的时间，原因是我太相信工具了，以为生成的东西一定是正确的，所以一直在想是不是别的方面出错了。得到这次教训之后，要更加清晰的对工具持怀疑态度了。不能太过相信和依靠，还是自己对这些技术的了解最重要。</P>
<P>&nbsp;</P>
<P>PS：TOMCAT有自带DBCP。不过我是自己从jakarta上面下的commons dbcp放到自己的lib里面的，当然，官方doc上面有这样的说明：</P>
<P>Commons-DBCP depends at runtime on commons-pool and commons-collections . </P>
<P>所以记得要把这两项也下回来和dbcp的jar文件一起放进lib才能保证不出错。</P>
<P>总之，认真＋心细，才能更好的解决问题。</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>本文环境：<BR>Win2003&nbsp; + jdk1.5.0_01<BR>Tomcat 5.5 +&nbsp; MySql4.1<BR>Eclipse 3.0.1 + Myeclipse 3.8.4</P>
<P>本文提到的一些软件的下载地址：</P>
<P>J2SE 5.0（SUN弄的这些乱七八糟的名字真讨厌，混乱的感觉）：<BR><A href="http://java.sun.com/j2se/1.5.0/download.jsp">http://java.sun.com/j2se/1.5.0/download.jsp</A></P>
<P>Tomcat：<BR><A href="http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi">http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi</A></P>
<P>MySql4.1：<BR><A href="http://dev.mysql.com/downloads/">http://dev.mysql.com/downloads/</A></P>
<P>Eclipse：<BR><A href="http://www.eclipse.org/downloads/index.php">http://www.eclipse.org/downloads/index.php</A></P>
<P>Jakarta commons（DBCP和其所需要的commons pool和commons collections都是在这里下）：<BR><A href="http://jakarta.apache.org/site/downloads/downloads_commons.html">http://jakarta.apache.org/site/downloads/downloads_commons.html</A><BR></P><img src ="http://www.blogjava.net/ranxiang/aggbug/23155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ranxiang/" target="_blank">冉翔</a> 2005-12-09 15:39 <a href="http://www.blogjava.net/ranxiang/articles/23155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>