??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
]]>
]]>
先来看看 String.split(String arg0) 是如何实现的Q下面是最惛_然的写法Q?BR>
public static void main( String[] args ){
String ip = "192.168.0.1";
String[] ips = ip.split(".");
System.out.println(ips.length);
}
}
嗯,试以后Q控制台打印出?”,那这样一?String.split(String arg0) 岂不是不能实现需求咯Q且慢,我们如果加上转义W会怎样呢?
public static void main( String[] args ){
String ip = "192.168.0.1";
String[] ips = ip.split("\\.");
System.out.println(ips.length);
}
}
q次l于如愿以偿了,控制台打印出?”。至于ؓ什么会q样Q我也没有深入探索,和朋友交后大概是说?”在 Java 中有Ҏ(gu)含义Q如果要q行正则匚wQ就必须转义一下?BR>
转入 Jakarta-OROQ下面看看它是如何进行匹配的Q?BR>
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
public class SplitTest {
public static void main( String[] args ) throws MalformedPatternException{
String ip = "192.168.0.1";
PatternCompiler pc = new Perl5Compiler();
PatternMatcher pm = new Perl5Matcher();
Pattern pattern = pc
.compile("([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})");
pm.contains(ip, pattern);
MatchResult mr = pm.getMatch();
int ip0 = Integer.parseInt(mr.group(1));
int ip1 = Integer.parseInt(mr.group(2));
int ip2 = Integer.parseInt(mr.group(3));
int ip3 = Integer.parseInt(mr.group(4));
System.out.println(ip0+" "+ip1+" "+ip2+" "+ip3);
}
}
关于 Jakarta-ORO 更多的信息,|上一搜一大堆Q在此就不进行细致的代码解释了?BR>
h意!引用、{贴本文应注明原作者:Rosen Jiang 以及出处Q?/FONT>http://www.tkk7.com/rosen
]]>
首先观察下面?XML 文gQ?
<?xml version = '1.0' encoding = 'gb2312'?>
<ROOT>
<ARSUBITEM num="1">
<C_ITEMNO>300200500009</C_ITEMNO>
<C_ITEMNAME>20050112试</C_ITEMNAME>
<C_SUBITEMNO>200543030000010</C_SUBITEMNO>
<C_SUBITEMNAME>20010112标段2</C_SUBITEMNAME>
<C_FUNCNAME>监督备案</C_FUNCNAME>
</ARSUBITEM>
</ROOT>
?XML 文g描述了一个标D当前流E信息,接下来把它翻译成 VO Q?/P>
public class BidProcess implements Serializable{ private String itemNo; /** |
?XML 构?VO Q放?List 中,代码如下Q?/P>
public class VOFactory { // 构造出的对象集?BR> private ArrayList list=new ArrayList(); |
通过对以上代码原形进行修改,可实现分c结果集嵌套{需求。在写作本文Ӟ我偶然发C Jakarta Commons BeanUtils 也提供了cM的功能。那么本文就作ؓ一个了解反的范例|了?BR>
h意!引用、{贴本文应注明原作者:Rosen Jiang 以及出处Q?/FONT>http://www.tkk7.com/rosen
class Logic{ public ststic void main(String[] args){ int a=1; int b=1; if(a<b && b<a/0){ System.out.println("OhQThat's Impossible!!!"); }else{ System.out.println("That's in my control."); } } } |
class Logic{ |
class Logic{ |
class Logic{ public ststic void main(String[] args){ int a=1; int b=1; if(a==b | b<a/0){ System.out.println("That's in my control."); }else{ System.out.println("OhQThat's Impossible!!!"); } } } |
最后。短路运符只能用于逻辑表达式内Q非短\q算W可用于位表辑ּ和逻辑表达式内。也可以_短\q算只能操作布尔型的Q而非短\q算不仅可以操作布尔型,而且可以操作数值型?br />
h意!引用、{贴本文应注明原作者:Rosen Jiang 以及出处Q?/font>http://www.tkk7.com/rosen
包括Q?br /> ?gt;> 右移”;?lt;< 左移”;?gt;>> 无符号右UZ?/p>
例子Q?br />-5>>3=-1
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1111 1111
其结果与 Math.floor((double)-5/(2*2*2)) 完全相同?/p>
-5<<3=-40
1111 1111 1111 1111 1111 1111 1111 1011
1111 1111 1111 1111 1111 1111 1101 1000
其结果与 -5*2*2*2 完全相同?/p>
5>>3=0
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0000
其结果与 5/(2*2*2) 完全相同?/p>
5<<3=40
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0010 1000
其结果与 5*2*2*2 完全相同?/p>
-5>>>3=536870911
1111 1111 1111 1111 1111 1111 1111 1011
0001 1111 1111 1111 1111 1111 1111 1111
无论正数、负敎ͼ它们的右UR左UR无W号右移 32 位都是其本nQ比?-5<<32=-5?5>>32=-5?5>>>32=-5?br />一个有的现象是,?1 左移 31 位再右移 31 位,其结果ؓ -1?br />0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 1111 1111 1111 1111 1111
位逻辑q算W?/strong>
包括Q?br /> & 与;| 或;~ 非(也叫做求反)Q^ 异或
?amp; 与”、“| 或”、“~ 非”是基本逻辑q算Q由此可以演变出“与非”、“或非”、“与或非”复合逻辑q算。“^ 异或”是一U特D的逻辑q算Q对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑?/p>
例子Q?br />5&3=1
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0001
-5&3=3
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0011
5|3=7
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0111
-5|3=-5
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1011
~5=-6
0000 0000 0000 0000 0000 0000 0000 0101
1111 1111 1111 1111 1111 1111 1111 1010
~-5=4
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0100
5^3=6
0000 0000 0000 0000 0000 0000 0000 0101
0000 0000 0000 0000 0000 0000 0000 0011
0000 0000 0000 0000 0000 0000 0000 0110
-5^3=-8
1111 1111 1111 1111 1111 1111 1111 1011
0000 0000 0000 0000 0000 0000 0000 0011
1111 1111 1111 1111 1111 1111 1111 1000
h意!引用、{贴本文应注明原作者:Rosen Jiang 以及出处Q?/font>http://www.tkk7.com/rosen
今天是一Ҏ(gu)日子Q本人特推出一篇译文Q希望大家喜Ƣ!
本文列出?/span> Bruce Eckel 所推荐的各U?/span> Java 工具Q不知道你用了吗Q?/span>
正文
非常荣幸Q我在这里向大家探讨关于最好的 Java 工具的话题。它们已被全部罗列在下面了。每个工具都是从他h的徏议以及我的切w体会中提炼出来的?/span>
IDE Q?/span> Eclipse (www.Eclipse.org)
它拥有杰出的性能Q在各个斚wQ,q且q是免费的。免费ƈ不L重点Q但是对于一?/span> IDE 来说Q免费很重要Q因为它降低了开发的屏障Q成本)Q也为想要从书本上学习编码技术的一cMh提供了条件?/span>
另外Q实际上 Eclipse 被设计ؓ可进行二ơ开发的产品Q可以扩展和重新发布成ؓ独立的应用程序^収ͼq是非常吸引人的。它?yu)会吸引Z对它q行更多的关注(投资Q?/span>
代码的格式化器:暂缺
Eclipse 有一内徏工具Q几乎可以在q方面做得很完美Q但也不是万能的。如果特别挑剔的话,据我所知,无论哪一个格式化器,Ҏ(gu)释的重定格式不会让h那么满意。我所需要的是所有的东西都要_的放在所规定的格式限制中?/span>
Jalopy 像是一个领跑者,但是U观历史Q它也不能解x释的重定格式问题。它是一个商业化的品( 40 元非常合理Q?/span>
单元试Q?/span> JUnit
我发?/span> JUnit 初始版本不太令h愉快Q所以我p己开发了一个。接着 JUnit 组法般的修正?/span> JUnit Q以至于它可以和我的产品做一L事情Q所?/span> JUnit 可以以这一Ҏ(gu)推销自己Q好像有点傲慢)。目前,大多数用户都在用它Q以至于 JUnit 成ؓ一U事实上的标准?/span>
为单元测试进行覆盖测试:
Clover
不太了解q个工具Q我没有使用q,但是q种概念看上d好。它?/span> 250 元的高仗?/span>
架构理Q?/span> Ant
参?/span> http://mindview.net/WebLog/log-0046 来学习“ؓ什么?/span> Ant ”?/span> Maven 像是作ؓ Ant 的替换品,但如果要用的话,q必L深入的研I一下?/span>
样式?/span>
/Bug
探测?/span>
Checkstyle 是开源的Q有点像下面的工P
Teamstudio 295 元Q我认ؓ官方站点只是一个演C?/span> 2003 12 月䆾有一?/span> JDJ 的评论,其他的我׃清楚了。如果你已经体验q的话,L我留a?/span>
性能调整Q?/span>
JProbe
我没有用q它Q不能从它的|站上断定出q个产品的性能Qh(hun)|?/span>
字节码淆器Q?/span>
YGuard
如果你不想他人反~译
(reverse-engineer)
你的代码Q你可以用它。再ơ重画I我也没有用过。显然这是一个基?/span>
LGPL
协议发布的工Pl你一个免费的选择?br />
h意!引用、{贴本文应注明原译者:Rosen Jiang 以及出处Q?/font>http://www.tkk7.com/rosen
现在有一典型?VO c?Auto(LightWeight)Q?/STRONG> package com.test; public class Auto implements Cloneable{ public String setNo(String no){ 使用克隆?BeanQ?/STRONG> package com.test; import java.io.*; public class MyXMLReader { Auto auto=new Auto(); //h较不?BR> ArrayList al=new ArrayList(); public ArrayList go() { package com.test; import java.io.*; public class MyXMLReader { ArrayList al=new ArrayList(); public ArrayList go() { 通过比较Q克隆与非克隆,在构?Auto 上花的时间是差不多的?BR> 且慢Q让我们再看下面?Auto cR?BR> package com.test; public class Auto implements Cloneable{ //以下Ҏ(gu)仅仅Z构造一?HeavyWeight 对象?BR> public Auto(){ public String setNo(String no){ 使用克隆构?Auto 实例Q?nbsp; 不用克隆构?Auto 实例Q?/P>
q行旉Q?88 毫秒 q行旉Q?219 毫秒 好了Q让我们查看一?Auto cR可以看见只是在其构造函C加入d10K XML文g的代码,而克隆与非克隆运行时间却有近 10 倍的差距Q?BR> 对象的构Z仅仅是“分配内存+初始化一些值域”那么简单,它可能涉及非常多个步骤。所以将“待建对象”的数量和体U减到最低,才是明智之D?/P>
让我们看看创Z?LightWeight c都发生了什么: 1、从 heap 分配内存Q用来存?Auto cȝ实例变量Q以及一份“实C|数据”?BR> 2、Auto cȝ实例变量 No ?AddrQ被初始化ؓ~省|~省值都为null?BR> 3、调?Auto cL造函数?BR> 4、Auto cL造函数调用其类Qjava.lang.ObjectQ的构造函数?BR> 5、java.lang.Object 构造函数返回?BR> 6、对象引用“auto”指?heap 中完成的 Auto 对象?BR> 1、从 heap 分配内存Q用来存?Auto cȝ实例变量Q以及一份“实C|数据”?BR> 2、Auto cȝ实例变量 No、Addr、str、f、sbQ被初始化ؓ~省|~省值都为null?BR> 3、File cȝ构造函数蝲?10K XML 文g得到实例变量 fQ调?StringBuffer 的构造函数得到实例变?sbQ接着调用 Auto cL造函数。(在构造函数本体执行之前,所有实例变量的初始讑֮值和初始化区D先获得执行Q然后才执行构造函数本体。针?f ?sbQ又从步?1 开始重复这个过E。)
private String No;
private String Addr;
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
return this.No=no;
}
public String getNo(){
return this.No;
}
public String setAddr(String addr){
return this.Addr=addr;
}
public String getAddr(){
return this.Addr;
}
}
接着分别通过使用克隆和不使用克隆?Bean 来构?Auto 实例?/P>
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;
long lasting = System.currentTimeMillis();
try {
File f = new File("data_100k.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
foo = (Element) i.next();
auto.setNo(foo.elementText("NO"));
auto.setAddr(foo.elementText("ADDR"));
al.add(auto.clone()); //h较不?BR> }
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("q行旉Q? + (System.currentTimeMillis() - lasting) + " 毫秒");
return al;
}
}
取八ơ运行时?BR> q行旉Q?72 毫秒
q行旉Q?3 毫秒
q行旉Q?4 毫秒
q行旉Q?41 毫秒
q行旉Q?25 毫秒
q行旉Q?8 毫秒
q行旉Q?03 毫秒
q行旉Q?3 毫秒
没有使用克隆?BeanQ?/STRONG>
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;
long lasting = System.currentTimeMillis();
try {
File f = new File("data_100k.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
foo = (Element) i.next();
Auto auto=new Auto(); //h较不?BR> auto.setNo(foo.elementText("NO"));
auto.setAddr(foo.elementText("ADDR"));
al.add(auto); //h较不?BR> }
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("q行旉Q? + (System.currentTimeMillis() - lasting) + " 毫秒");
return al;
}
}
取八ơ运行时?BR> q行旉Q?87 毫秒
q行旉Q?3 毫秒
q行旉Q?72 毫秒
q行旉Q?8 毫秒
q行旉Q?04 毫秒
q行旉Q?9 毫秒
q行旉Q?04 毫秒
q行旉Q?8 毫秒
修改一?Auto cȝ构造函敎ͼ像这?HeavyWeight)Q?/STRONG>
import java.io.*;
private String No;
private String Addr;
private String str;
private File f = new File("data_10k.xml");
private StringBuffer sb=new StringBuffer();
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
try{
BufferedReader inbuffer=new BufferedReader(new FileReader(f));
while ((str=inbuffer.readLine())!=null){
sb.append(str);
}
}catch(Exception e){
System.out.println(e.toString());
}
}
return this.No=no;
}
public String getNo(){
return this.No;
}
public String setAddr(String addr){
return this.Addr=addr;
}
public String getAddr(){
return this.Addr;
}
}
再看看测试数据呢Q?/STRONG>
q行旉Q?8 毫秒 q行旉Q?266 毫秒
q行旉Q?09 毫秒 q行旉Q?156 毫秒
q行旉Q?19 毫秒 q行旉Q?093 毫秒
q行旉Q?10 毫秒 q行旉Q?266 毫秒
q行旉Q?8 毫秒 q行旉Q?141 毫秒
q行旉Q?57 毫秒 q行旉Q?078 毫秒
q行旉Q?8 毫秒 q行旉Q?172 毫秒
Z么会q样Q?/STRONG>
再让我们看看创徏一?HeavyWeight c都发生了什么:
4、Auto cL造函C调用 FileReader cȝ构造函数将实例变量 f 载入Q接着调用 BufferedReader cȝ构造函数将 FileReader cȝ实例载入Q得到局部变?inbuffer。(针对 FileReader cȝ实例?inbufferQ又从步?1 开始重复这个过E。)
5、读?inbuffer 中的数据Q实例变?sb 被@环赋倹{?BR> 6、蟩出@环后Q实例变?sb l过Ҏ(gu)调用q回l实例变?str?BR> 7、Auto cL造函数调用其类Qjava.lang.ObjectQ的构造函数?BR> 8、java.lang.Object 构造函数返回?BR> 9、对象引用“auto”指?heap 中完成的 Auto 对象?BR>
通过比较可以看出Q徏?HeavyWeight 对象比徏?LightWeight 对象的性能相差很多。步?3? 代h(hun)最高,因ؓ它不得不对四个聚合对象重复全q程?BR> 创徏对象代h(hun)高昂Q特别是 HeavyWeight 对象Q!应尽量减创建次数。创建对象的ơ数少Q意味代码执行越快。对?Auto c?HeavyWeight)Q复用对象引用“auto”所指向的对象才是正解?BR> 对象复用的一U重要方式就是克隆。Q何类如果支持克隆操作Q就必须实现 Cloneable 接口Q这只是一个标识接口,它ƈ没有实现MҎ(gu)。Q何类如果实现 CloneableQ就宣布它支持克隆操作。正如以上这些代码,利用克隆来提高性能是非常简单的?BR>
h意!引用、{贴本文应注明原作者:Rosen Jiang 以及出处Q?/FONT>http://www.tkk7.com/rosen
]]>
许多书上都讨Z自动试Q但是只有很的著作注意到这么一个问题,那就是怎样把这些测试组lv来。随着试的增加,攄和调用这些测试却变得更加ȝ。这成Z个重要问题,以至于出CTDDQ极限编E(XPQTDD得以普及。另外,你可以这L解TDDQ通过试来开发?nbsp;
TDD的主要规范:
在编写程序代码之前,与之对应的自动测试必被写好。甚至程序代码ƈ不存在,那也要看见一个失败的试l果?
在测试通过后,副本代码必须被丢弃?nbsp;
有一个具体步骤(可能指的是《Extreme Programming》)可以被Q何一个程序员来参考,而不需要特D的其他Ҏ(gu)。在我们开始写试之前Q这些步骤(章节Q应该被首先阅读——怎样l织自动试?nbsp;
讲解一下不同种cȝ试Q?nbsp;
单元试Q?/B>模块(也就是类Q的正确性。如果对象需要访问外部的数据资源Q例如数据库Q就需要模拟一个mock objectsQ但在实际中真实数据与测试环境是不同的?
客户试Q?/B>q是功能性、系l、和验收试。用来测试整体的pȝҎ(gu)。在XP中,q些试qL写?
l合试Q?/B>介于用户试和单元测试之间的桥梁。综合测试帮助测试应用程序的交互性。一般情况下Qmock objects不被用于l合试Q它会增加测试时间。同Pl合试l常依赖Ҏ(gu)的测试环境,例如数据库送来的测试数据。综合测试也需要用到外部类库。例如ؓJ2EE应用E序q行l合试的类库Cactus。解释这些测试超Z本文的范_需要更加详l的信息请参?/FONT>http://jakarta.apache.org/cactus/?
开发h员测试:q是用来让开发h员检验自׃码或新函数的。对于每一个开发h员,只要有可能,需要有更多的测试来验代码。组l这些测试和l织E序代码一样重要?nbsp;
在以下章节,只要提到“测试”,那就指的是开发h员测试?nbsp;
我们几乎准备好开始徏立测试了Q先应该为我们的试选择名字。你也许会说Q“这不是问题Q把‘Test’这个字攑֜cd前面Q就好了Q”不会这么快Q让我来说一下这个步骤存在的问题Q?nbsp;
在TDD中,被测试的cL者方法还不存在?
一个测试能够覆盖多个方法,甚至多个c,q是可能的?nbsp;
以上只是一些普遍问题;q存在更多的问题?nbsp;
让我来提一个徏议,在测试命名时Q测试类的名字应该让Z眼就知道q是一个测试类Q且能说明它要测试什么,注意是否和其他类重名。按照以上徏议做Q就很简单了Q也不用担心名字太长或难听?/FONT>
卛_在Eclipse中用JUnit工具创徏我们W一个测试了。假设你已经下蝲了一个最新的Eclipse版本。如果还没有Q你应该d方站点http://www.eclipse.org下蝲。还需要JUnitQ也可以从http://www.junit.org/下蝲?nbsp;
q行Eclipse。新Z个workplace目Q点?B style="mso-bidi-font-weight: normal">文g->新徏->目Q选择Java目Q点?B style="mso-bidi-font-weight: normal">下一?/B>。v一个项目名Uͼ例如ProjectWithJUnit。点?B style="mso-bidi-font-weight: normal">完成。这样就完成新项目的建立了。再来配|一下EclipseQ在构徏路径中添加JUnitcd。在工具条上点击目->属?/B>Q选择Java构徏路径Q?B style="mso-bidi-font-weight: normal">?/B>Q选择d外部JARQ浏览Junit被存储的目录Q选择junit.jarQ点?B style="mso-bidi-font-weight: normal">打开。你会看见JUnit出现在库的列表中。点?B style="mso-bidi-font-weight: normal">定Q让Eclipse重徏路径?nbsp;
现在开发我们的“Hello World”例子。按照TDD的规则,应该在代码徏立以前先把测试写好。ؓ了能够在某出开始,我们假设未来的类名是HelloWorldQƈ且有一个方法Say()Q这个方法返回String的|例如“Hello World!”)?nbsp;
建立试Q在ProjectWithJUnit的标题上面点d键,选择新徏->其他Q展开“Java”选项Q选择JUnit。在双的栏目对话框中选择试案例Q然后下一步。参考图1?/FONT>
?SPAN lang=EN>1. 在Eclipse中徏立JUnit试
在测试类q一栏中Q写上将要被试的类名HelloWorld。选择一?B style="mso-bidi-font-weight: normal">试案例的名字,例如TestThatWeGetHelloWorldPromptQ是的,看上d长,但是很清楚它的行为。)点击完成?nbsp;
TestThatWeGetHelloWorldPrompt的代码如下:
import junit.framework.TestCase;
public class TestThatWeGetHelloWorldPrompt
extends TestCase {
public TestThatWeGetHelloWorldPrompt(
String name) {
super(name);
}
public void testSay() {
HelloWorld hi = new HelloWorld();
assertEquals("Hello World!", hi.say());
}
public static void main(String[] args) {
junit.textui.TestRunner.run(
TestThatWeGetHelloWorldPrompt.class);
}
}
代码q不复杂Q只是有点与众不同。然而,让我们考察一下细节。我们承了JUnit的TestCasec,它在JUnit的javadocs定义为“运行众多测试的夹具。”JUnit也有TestSuitec,它是一l测试案例的集合Q但在本文中不做讨论?
建立试案例的步骤如下:
1、徏立一个junit.framework.TestCase的实例?
2、定义一些以“test”开头的无返回方法(例如testWasTransactionSuccessful()QtestShow()Q等{)?
TestThatWeGetHelloWorldPrompt.java包含q些QTestCase的子cd一个叫做testSay()的方法。这个方法调用了assertEquals()函数Q它用来比较我们预期的值和由say()q回的倹{?nbsp;
main()Ҏ(gu)用来q行试和显C出的。JUnit的TestRunner处理试Q提供基于图像和文本的输现Ş式。我们用基于文本的版本Q因为Eclipse支持它,且也适合我们。当开始运行后Q基于文本的版本试会以文本形式输出QEclipse会把q些输出自动变成囑փ界面的输出?nbsp;
按照TDD规范Q首ơ运行测试,应该故意让它p|。点?B style="mso-bidi-font-weight: normal">q行->q行?/B>->Junit试Q记住TestThatWeGetHelloWorldPrompt.java应该被突出的昄在包资源理器中Q。在左边H口Q应该看见JUnitH口而不?B style="mso-bidi-font-weight: normal">包资源管理器Q它昄一个红条,一ơ失败的试Q具体的p|原因参看?。如果没有自动显C些内容,点击JUnit标签Q在底部的左边)?/FONT>
?SPAN lang=EN>2. JUnit中失败的试
很好Q的却失败了。现在我们来建立被测试代码:在包资源理器窗口的ProjectWithJUnit标题上右击,选择新徏->c?/B>。选择cdQ我们已l假设了它叫HelloWorldQ然后直接点?B style="mso-bidi-font-weight: normal">完成。ؓHelloWorld.java填入下列代码Q?/FONT>
public class HelloWorld {
public String say() {
return("Hello World!");
}
}
q段代码很简单,甚至不需要注解,我们再来看看l果。按照上面描q过的方式,?B style="mso-bidi-font-weight: normal">JUnit的窗口中昄了一个绿条,参看?。绿条证明测试成功?/FONT>
?SPAN lang=EN>3. JUnit中成功的试
现在Q我们想再让试p|一ơ,但原因不同。这有助于展CJUnit试中不同的报错信息。修改assertEquals()代码Q把“Hello World!”变成“Hello Me!”。当再次q行JUnitӞl果变成了红条,?B style="mso-bidi-font-weight: normal">JUnitH口的底部输Zp|原因Q参看图4?/FONT>
?SPAN lang=EN>4. JUnit中的ComparisonError
最后,我想说一下关于测试是开发过E中的必要部分的话题。测试代码一直是开发中的重要部分。经q近几年的发展,已得C很大的提高,q要归功于强大的理论研究Q比如“expectations-based development”等{)Q和快速发展的试工具包,q有试q程的改q。如果你对这文章感兴趣Q那请你׃些时间来正式的学习一下测试理论吧Q这对你的工作很有用?
关于作者:
Alexander Prohorenko 一名UNIXpȝ理员、网l安全管理员?
Olexiy Prohorenko 一名Java开发者居住在乌克兰的Dniepropetrovsk?BR>
h意!引用、{贴本文应注明原译者:Rosen Jiang 以及出处Q?/FONT>http://www.tkk7.com/rosen