??xml version="1.0" encoding="utf-8" standalone="yes"?>av国产在线观看,欧美一区 二区,日本啊v在线http://www.aygfsteel.com/supercrsky/category/27522.html专注于JavaWeb开?/description>zh-cnMon, 05 Nov 2012 23:01:45 GMTMon, 05 Nov 2012 23:01:45 GMT60Cactus容器试入门http://www.aygfsteel.com/supercrsky/articles/205106.html々上善若水?/dc:creator>々上善若水?/author>Sat, 31 May 2008 17:11:00 GMThttp://www.aygfsteel.com/supercrsky/articles/205106.htmlhttp://www.aygfsteel.com/supercrsky/comments/205106.htmlhttp://www.aygfsteel.com/supercrsky/articles/205106.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/205106.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/205106.htmlhttp://jakarta.apache.org/cactus/integration/howto_tomcat.html

我们在web.xml中的webapp之间加入:
<servlet>
  
<servlet-name>ServletRedirector</servlet-name>
  
<servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
  
<init-param>
    
<param-name>param1</param-name>
    
<param-value>value1 used for testing</param-value>
  
</init-param>
</servlet>

<servlet>
  
<servlet-name>ServletTestRunner</servlet-name>
  
<servlet-class>org.apache.cactus.server.runner.ServletTestRunner</servlet-class>
</servlet>
加入mapping:
<servlet-mapping>
    
<servlet-name>ServletRedirector</servlet-name>
    
<url-pattern>/ServletRedirector</url-pattern>
</servlet-mapping>

<servlet-mapping>
    
<servlet-name>ServletTestRunner</servlet-name>
    
<url-pattern>/ServletTestRunner</url-pattern>
</servlet-mapping>


然后我们写一个简单的Servlet来进行测?
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

public class SampleServlet extends HttpServlet
{
    
public void saveToSession(HttpServletRequest request)
    
{
        String testparam 
= request.getParameter("testparam");
        request.getSession().setAttribute(
"testAttribute", testparam);
    }

}


对于此Servlet在xml的配|我׃写了Q想必你也了然于心了吧.

来看看我们的试c?
import junit.framework.Test;
import junit.framework.TestSuite;

import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;

public class TestSampleServlet extends ServletTestCase
{
    
public TestSampleServlet(String theName)
    
{
        
super(theName);
    }


    
public static Test suite()
    
{
        
return new TestSuite(TestSampleServlet.class);
    }


    
public void beginSaveToSessionOK(WebRequest webRequest)
    
{
        webRequest.addParameter(
"testparam""it works!");
    }


    
public void testSaveToSessionOK()
    
{
        SampleServlet servlet 
= new SampleServlet();
        servlet.saveToSession(request);
        assertEquals(
"it works!", session.getAttribute("testAttribute"));
    }

}



部v之后Q启动Tomcat,讉K:

http://localhost:8080/test/ServletTestRunner?suite=TestSampleServlet
q时候你会看到输出 Q?br />

<?xml version="1.0" encoding="UTF-8" ?> 
- <testsuites>
- <testsuite name="com.test.servlet.TestServletTest" tests="1" failures="0" errors="1" time="0.516">
- <testcase name="testSaveSessionToOK" time="0.36">
  
<error message="org/apache/commons/codec/DecoderException" type="java.lang.NoClassDefFoundError">java.lang.NoClassDefFoundError: org/apache/commons/codec/DecoderException at org.apache.commons.httpclient.HttpMethodBase.getURI(HttpMethodBase.java:265) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:383) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346) at org.apache.cactus.internal.client.connector.http.HttpClientConnectionHelper.connect_aroundBody0(HttpClientConnectionHelper.java:144) at org.apache.cactus.internal.client.connector.http.HttpClientConnectionHelper.connect_aroundBody1$advice(HttpClientConnectionHelper.java:307) at org.apache.cactus.internal.client.connector.http.HttpClientConnectionHelper.connect(HttpClientConnectionHelper.java:1) at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.callRunTest(DefaultHttpClient.java:163) at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody0(DefaultHttpClient.java:81) at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody1$advice(DefaultHttpClient.java:307) at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest(DefaultHttpClient.java:1) at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runWebTest(HttpProtocolHandler.java:164) at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody0(HttpProtocolHandler.java:83) at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody1$advice(HttpProtocolHandler.java:307) at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest(HttpProtocolHandler.java:1) at org.apache.cactus.internal.client.ClientTestCaseCaller.runTest(ClientTestCaseCaller.java:145) at org.apache.cactus.internal.AbstractCactusTestCase.runBareClient(AbstractCactusTestCase.java:218) at org.apache.cactus.internal.AbstractCactusTestCase.runBare(AbstractCactusTestCase.java:134) at org.apache.cactus.server.runner.ServletTestRunner.run(ServletTestRunner.java:309) at org.apache.cactus.server.runner.ServletTestRunner.doGet_aroundBody0(ServletTestRunner.java:187) at org.apache.cactus.server.runner.ServletTestRunner.doGet_aroundBody1$advice(ServletTestRunner.java:225) at org.apache.cactus.server.runner.ServletTestRunner.doGet(ServletTestRunner.java:1) at javax.servlet.http.HttpServlet.service(HttpServlet.java:690) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Unknown Source)</error> 
  
</testcase>
  
</testsuite>
  
</testsuites>

看来E序没有大问题,已经正确执行Q不q这时提C有一个类找不刎ͼ
对于q个问题我们可以?font style="background-color: #f4f4f4">http://commons.apache.org/downloads/download_codec.cgi下蝲Q?br />
q个xml看v来多不习惯Q我们可以下载xsl把它转换成html格式Q?br /> Ҏ下蝲 把它攑ֈ你web应用的根目录下.

q个时候你可以讉K如下地址Q?br /> http://localhost:8080/test/ServletTestRunner?suite=TestSampleServlet&xsl=cactus-report.xsl

q时候你׃看到友好的Html格式?
HTML output of ServletTestRunner


]]>
selenium初探http://www.aygfsteel.com/supercrsky/articles/162866.html々上善若水?/dc:creator>々上善若水?/author>Sat, 24 Nov 2007 08:13:00 GMThttp://www.aygfsteel.com/supercrsky/articles/162866.htmlhttp://www.aygfsteel.com/supercrsky/comments/162866.htmlhttp://www.aygfsteel.com/supercrsky/articles/162866.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/162866.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/162866.html先确保你?444端口没被占用,可以用netstat -an命o查看一?
然后保你的jdk版本?.5以上.

W一?
扑ֈ你下载的selenium解压目录下的selenium-server-0.9.2目录.
在这个目录下写个批处?内容?
java -jar selenium-server.jar
保存为start.bat,名字随便?双击启动.q个是服?在一切工作开始之?
必须先启动这?启动后的dosH口不要关闭.

W二?
在MyEclipseZweb工程,把selenium-java-client-driver-0.9.2目录下的jar包加?br /> 到web工程的lib目录?加入junit4支持.

W三?
写个试index.jsp?

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<html>
  
<head>
    
<title>test!</title>
  
</head>
  
  
<body>
  
<form action="success.jsp" method="post">
    UserName:
<input type="text" name="username" /><br />
    
<select name="select">
        
<option value="game">游戏</option>
        
<option value="program">~程</option>
    
</select> <br/>
    
<input type="submit" name="sub" value="submit"/> <br />
    
</form>
  
</body>
</html>
q有一个success.jsp:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>
    
<title>success</title>
  
</head>
  
<body>
    ok!
  
</body>
</html>

写个试c?
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.server.SeleniumServer;
import static org.junit.Assert.*;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;


public class TestPage
{
    
private Selenium selenium;
    @Before
    
public void setUp()
    
{
        
//此url必须是Selenium服务器地址
        String url = "http://localhost:4444";
        selenium 
= new DefaultSelenium("localhost",SeleniumServer.getDefaultPort(),"*iexplore",url);
        selenium.start();
    }

    
    @After
    
public void tearDown()
    
{
        
try
        
{
            selenium.stop();
        }
 catch (RuntimeException e)
        
{
            System.out.println(e.getMessage());
        }

    }

    
//试标题,文本框输?及按钮点?/span>
    @Test
    
public void test1()
    
{
        
//我这里是tomcat的地址,我的tomcat端口?888,selenium是当前工E?我让它打开首页
        selenium.open("http://localhost:8888/selenium/index.jsp");
        String title 
= selenium.getTitle();
        
//原来|页的标?/span>
        System.out.println(title);
        selenium.type(
"xpath=//input[@name='username']""zdw");
        
//得到输入的文本框的?/span>
        System.out.println("textvalue:" + selenium.getValue("xpath=//input[@name='username']"));
        selenium.click(
"xpath=//input[@name='sub']");
        selenium.waitForPageToLoad(
"4000");
        assertEquals(title, 
"test!");
        
//输出新页的标?/span>
        System.out.println(selenium.getTitle());
    }

    
//试选择?/span>
    @Test
    
public void testSelect()
    
{
        selenium.open(
"http://localhost:8888/selenium/index.jsp");
        selenium.select(
"xpath=//select[@name='select']""index=1");
        
//得到选择的id
        System.out.println("selectid:" + selenium.getSelectedIndex("xpath=//select[@name='select']"));
        
//得到选择的?/span>
        System.out.println("selectvalue:" + selenium.getSelectedValue("xpath=//select[@name='select']"));
        selenium.click(
"xpath=//input[@type='submit']");
        selenium.waitForPageToLoad(
"3000");
    }

    
    
}










注释已经很详l了,感觉selenium很好?完全可以模拟览器操?我这里用的是ie,你当然可以用firefox或其?
源码可在我的|盘下蝲.


]]>
Selenium 使用介绍 http://www.aygfsteel.com/supercrsky/articles/162787.html々上善若水?/dc:creator>々上善若水?/author>Sat, 24 Nov 2007 02:03:00 GMThttp://www.aygfsteel.com/supercrsky/articles/162787.htmlhttp://www.aygfsteel.com/supercrsky/comments/162787.htmlhttp://www.aygfsteel.com/supercrsky/articles/162787.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/162787.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/162787.htmlSelenium ?thoughtworks公司的一个集成测试的强大工具。最q参与了一个系l移植的目Q正好用到这个工P

把一些用心得分享给大家Q希望大家能多多使用q样的强大的Q免费的工具Q来保证我们的质量?/span>

Selenium 的文档现存的不少Q不q都太简单了。用Selenium的时候,我更多的是直接去看API文档Q好在API不错Q?/span>

一个一个看Q就能找到所需要的 :-)   官方|站Q?/span>http://www.openqa.org/selenium/

好,下面q入正题Q?/span>

一、Selenium 的版?/span>

Selenium 现在存在2个版本,一个叫 selenium-core, 一个叫selenium-rc ?/span>

selenium-core 是用HTML的方式来~写试脚本Q你也可以?Selenium-IDE来录制脚本,但是目前Selenium-IDE
只有 FireFox 版本?/span>

Selenium-RC ?selenium-remote control ~写Q是使用具体的语a来编写测试类?/span>

selenium-rc 支持的语a非常多,q里我们着重关注java的方式。这里讲的也主要?selenium-rcQ因Z是喜Ƣ这U?br /> 方式 :-)

 二、一些准备工?/span>

1、当然是下蝲 selenium 了,?http://www.openqa.org/selenium/ 下蝲可以了Q记得选择selenium-rc 的版本?/span>

2、学习一?xpath 的知识。有个教E:http://www.zvon.org/xxl/XPathTutorial/General_chi/examples.html
     一定要学习q个Q不然你Ҏ看不懂下面的内容Q?/span>

3、安?jdk1.5

 三、selenium-rc 一些用方?/span>

?selenium-remote-control-0.9.0\server 目录里,我们q行 java -jar selenium-server.jar
之后你就会看C些启动信息。要使用 selenium-rc Q启动这个server 是必ȝ?/span>

当然Q启动的时候有许多参数Q这些用法可以在|站里看看教E,不过不加参数也已l够了?/span>

selenium server 启动完毕了,那么我们可以开始编写测试类了!

我们先有个概念,selenium 是模仿浏览器的行为的Q当你运行测试类的时候,你就会发现selenium 会打开一?/span>

览器,然后览器执行你的操作?/span>

 好吧Q首先生成我们的试c:

java 代码

 

public class TestPage2 extends TestCase {    
  
private Selenium selenium;    
   
  
protected void setUp() throws Exception {    
     String url 
= “http://xxx.xxx.xxx.xxx/yyy”;    
     selenium = new DefaultSelenium("localhost", SeleniumServer.getDefaultPort    
                                (), 
"*iexplore", url);    
     selenium.start();    
                
     
super.setUp();                         
            
  }
    
   
  
protected void tearDown() throws Exception {    
            
      selenium.stop();    
      
super.tearDown();    
                
   
  }
    
   
}
   

 

代码十分单,作用是初始化一?Selenium 对象。其中:
url : 是你要试的网?br /> localhost:  可以不是localhostQ但是必L selenium server 启动的地址
*iexplore :  可以是其它浏览器cdQ可以在|站上看都支持哪些?/span>

下面我就要讲讲怎么使用selenium q个对象来进行测试?/span>

1、测试文本输入框

假设面上有一个文本输入框Q我们要试的内Ҏ 在其中输入一些内容,然后点击一个按钮,看看面的是否蟩?br /> 到需要的面?br />

public void test1() {    
            
    selenium.open(
"http://xxx.xxx.xxx/yyy");    
            
    selenium.type(
"xpath=//input[@name='userID']""test-user");    
    selenium.click(
"xpath=//input[@type='button']");    
    selenium.waitForPageToLoad(
"2000");    
    assertEquals(selenium.getTitle(), 
"Welcome");    
}
   


上面的代码是q个意思:
1、调?selenium.open ҎQ浏览器会打开相应的页?br /> 2、?type Ҏ来给输入框输入文?br /> 3、等待页面蝲?br /> 4、看看新的页面标题是不是我们惌的?/span>

2、测试下拉框

java 代码
public void test1() {        
                
    selenium.open(
"http://xxx.xxx.xxx/yyy");        
                
    selenium.select(
"xpath=//SELECT[@name='SBBUSYO']""index=1");    
    selenium.click(
"xpath=//input[@type='button']");        
    selenium.waitForPageToLoad(
"2000");        
    assertEquals(selenium.getTitle(), 
"Welcome");        
}
      

可以看到Q我们可以?select Ҏ来确定选择下拉框中的哪个选项?br /> select Ҏq有很多用法Q具体去看看文档吧?/span>

3、测试check box

java 代码

public void test1() {            
                    
    selenium.open(
"http://xxx.xxx.xxx/yyy");            
                    
    selenium.check(
"xpath=//input[@name='MEICK_000']");      
    selenium.click(
"xpath=//input[@type='button']");            
    selenium.waitForPageToLoad(
"2000");            
    assertEquals(selenium.getTitle(), 
"Welcome");            
}
       


我们可以使用 check Ҏ来确定选择哪个radio button

4、得到文本框里的文字

java 代码

    

assertEquals(selenium.getValue("xpath=//input[@name='WNO']"), "1");   

 

getValue Ҏ是得到文本框里的数|可不?getText ҎQ用错了可就郁闷了?/span>

5、判断页面是否存在一个元?/span>

java 代码

    

assertTrue(selenium.isElementPresent("xpath=//input[@name='MEICK_000']"));  

 

一般这个是用来试当删除一些数据后Q页面上有些东西׃会显C的情况?/span>

6、判断下拉框里选择了哪个选项

java 代码

    

assertEquals(selenium.getSelectedIndex("xpath=//SELECT[@name='HATIMING']"), "1");   

 

q个可以用来判断下拉框显C的选项是否是期望的选项?/span>

7、如果有 alert 弹出对话框怎么办?

q个问题弄了挺长旉Q可以这h关闭弹出的对跨框Q?/span>

java 代码
if(selenium.isAlertPresent()) {    
   
   selenium.getAlert();    
   
}
   

其实当调?selenium.getAlert() Ӟ׃关闭 alert 弹出的对话框?br /> 也可以?System.out.println(selenium.getAlert()) 来查看对跨框昄的信息?/span>

在测试的时候,有的Z昄许多alert 来查看运行时的数据,那么我们可以用下面的方式来关闭那?alert:

java 代码
while(selenium.isAlertPresent()) {        
       
   selenium.getAlert();        
       
}
    

8、如何测试一些错误消息的昄Q?/span>

java 代码
assertTrue(selenium.getBodyText().indexOf("错误消息")>=0);   

切记Q?getBodyText q回的时览器页面上的文字,不回包含html 代码的,如果要显Chtml 代码Q用下面q个:

java 代码
System.out.println(selenium.getHtmlSource());   

以上是最常用的几个方法了Q例?click, type, getValue {等?br /> q有是一定要学习 xpath, 其实xpath 也可以有“与、或、非”的操作:

java 代码

四、其?/span>

selenium q有更多的用法,例如弹出面{等。当面对没见q的试要求Ӟ我最W的Ҏ是按照api文档一个一个找Q?br /> 好在不多Q肯定能扑ֈ?br />

selenium.check("xpath=//input[(@name='KNYKBN')and(@value='Y')]"); 


]]>
TestSuite集合试的?/title><link>http://www.aygfsteel.com/supercrsky/articles/162777.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Sat, 24 Nov 2007 00:50:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/162777.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/162777.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/162777.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/162777.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/supercrsky/services/trackbacks/162777.html</trackback:ping><description><![CDATA[<p>有时候需要一ơ测试所有的c?或多?,q时候就用到了TestSuite.<br /> 举例说明:<br /> q里有两个TestCasec?<br /> Person:<br /> </p> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff">package</span><span style="color: #000000"> com;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.TestCase;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> Person </span><span style="color: #0000ff">extends</span><span style="color: #000000"> TestCase<br /> <img id="Codehighlighter1_83_237_Open_Image" onclick="this.style.display='none'; Codehighlighter1_83_237_Open_Text.style.display='none'; Codehighlighter1_83_237_Closed_Image.style.display='inline'; Codehighlighter1_83_237_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_83_237_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_83_237_Closed_Text.style.display='none'; Codehighlighter1_83_237_Open_Image.style.display='inline'; Codehighlighter1_83_237_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedBlock.gif" align="top" alt="" /></span><span id="Codehighlighter1_83_237_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_83_237_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> testMethod1()<br /> <img id="Codehighlighter1_113_156_Open_Image" onclick="this.style.display='none'; Codehighlighter1_113_156_Open_Text.style.display='none'; Codehighlighter1_113_156_Closed_Image.style.display='inline'; Codehighlighter1_113_156_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_113_156_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_113_156_Closed_Text.style.display='none'; Codehighlighter1_113_156_Open_Image.style.display='inline'; Codehighlighter1_113_156_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" /> </span><span id="Codehighlighter1_113_156_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_113_156_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Person:method1</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /> }</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> <br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> testMethod2()<br /> <img id="Codehighlighter1_188_231_Open_Image" onclick="this.style.display='none'; Codehighlighter1_188_231_Open_Text.style.display='none'; Codehighlighter1_188_231_Closed_Image.style.display='inline'; Codehighlighter1_188_231_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_188_231_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_188_231_Closed_Text.style.display='none'; Codehighlighter1_188_231_Open_Image.style.display='inline'; Codehighlighter1_188_231_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" /> </span><span id="Codehighlighter1_188_231_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_188_231_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Person:method2</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /> }</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> <br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> <br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></span></div> <p><br /> Student:<br /> </p> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff">package</span><span style="color: #000000"> com;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.TestCase;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> Student </span><span style="color: #0000ff">extends</span><span style="color: #000000"> TestCase<br /> <img id="Codehighlighter1_84_158_Open_Image" onclick="this.style.display='none'; Codehighlighter1_84_158_Open_Text.style.display='none'; Codehighlighter1_84_158_Closed_Image.style.display='inline'; Codehighlighter1_84_158_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_84_158_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_84_158_Closed_Text.style.display='none'; Codehighlighter1_84_158_Open_Image.style.display='inline'; Codehighlighter1_84_158_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedBlock.gif" align="top" alt="" /></span><span id="Codehighlighter1_84_158_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_84_158_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> testMethod()<br /> <img id="Codehighlighter1_113_156_Open_Image" onclick="this.style.display='none'; Codehighlighter1_113_156_Open_Text.style.display='none'; Codehighlighter1_113_156_Closed_Image.style.display='inline'; Codehighlighter1_113_156_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_113_156_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_113_156_Closed_Text.style.display='none'; Codehighlighter1_113_156_Open_Image.style.display='inline'; Codehighlighter1_113_156_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" /> </span><span id="Codehighlighter1_113_156_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_113_156_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Student:method</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /> }</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span></div> <p><br /> 集合试的类:PersonSuite<br /> </p> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff">package</span><span style="color: #000000"> com;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.awtui.TestRunner;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.Test;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.TestCase;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.TestSuite;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> PersonSuite </span><span style="color: #0000ff">extends</span><span style="color: #000000"> TestCase<br /> <img id="Codehighlighter1_182_443_Open_Image" onclick="this.style.display='none'; Codehighlighter1_182_443_Open_Text.style.display='none'; Codehighlighter1_182_443_Closed_Image.style.display='inline'; Codehighlighter1_182_443_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_182_443_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_182_443_Closed_Text.style.display='none'; Codehighlighter1_182_443_Open_Image.style.display='inline'; Codehighlighter1_182_443_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedBlock.gif" align="top" alt="" /></span><span id="Codehighlighter1_182_443_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_182_443_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> Test suite()<br /> <img id="Codehighlighter1_213_330_Open_Image" onclick="this.style.display='none'; Codehighlighter1_213_330_Open_Text.style.display='none'; Codehighlighter1_213_330_Closed_Image.style.display='inline'; Codehighlighter1_213_330_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_213_330_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_213_330_Closed_Text.style.display='none'; Codehighlighter1_213_330_Open_Image.style.display='inline'; Codehighlighter1_213_330_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" /> </span><span id="Codehighlighter1_213_330_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_213_330_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  TestSuite ts </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> TestSuite();<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  ts.addTestSuite(Person.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  ts.addTestSuite(Student.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  </span><span style="color: #0000ff">return</span><span style="color: #000000"> ts;<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /> }</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> <br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args)<br /> <img id="Codehighlighter1_375_441_Open_Image" onclick="this.style.display='none'; Codehighlighter1_375_441_Open_Text.style.display='none'; Codehighlighter1_375_441_Closed_Image.style.display='inline'; Codehighlighter1_375_441_Closed_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><img id="Codehighlighter1_375_441_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_375_441_Closed_Text.style.display='none'; Codehighlighter1_375_441_Open_Image.style.display='inline'; Codehighlighter1_375_441_Open_Text.style.display='inline';" src="http://www.aygfsteel.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" alt="" /> </span><span id="Codehighlighter1_375_441_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_375_441_Open_Text"><span style="color: #000000">{<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" />  </span><span style="color: #008000">//</span><span style="color: #008000">用TestRunner呼叫suite Ҏ</span><span style="color: #008000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/InBlock.gif" align="top" alt="" /></span><span style="color: #000000">  TestRunner.run(PersonSuite.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /> }</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span></div> <img src ="http://www.aygfsteel.com/supercrsky/aggbug/162777.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2007-11-24 08:50 <a href="http://www.aygfsteel.com/supercrsky/articles/162777.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面认识JUnit4.0http://www.aygfsteel.com/supercrsky/articles/162775.html々上善若水?/dc:creator>々上善若水?/author>Sat, 24 Nov 2007 00:43:00 GMThttp://www.aygfsteel.com/supercrsky/articles/162775.htmlhttp://www.aygfsteel.com/supercrsky/comments/162775.htmlhttp://www.aygfsteel.com/supercrsky/articles/162775.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/162775.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/162775.html提要 本文向你介l如何实CJUnit 3.8向JUnit 4的迁UR同Ӟq讨论JUnit 4中的一些新特征Q特别包括对注解的用;最后,要介l这个新版本的IDE集成现状?/font>

  一?引言

  在本文开始,我将假定Q你已经了解由Kent Beck和Erich Gamma发明的这个Java单元试框架q因此而略q必要的介。所以,我将集中分析从JUnit 3.8到最新版?JUnit 4的迁U过E以及其在IDE和Ant中的集成?br />
  JUnit 4是一U与其之前的版本完全不同的APIQ它ҎJava 5.0中的新特?注解Q静态导入等)构徏而成。如你所见,JUnit 4更简单、更丰富和更易于使用Q而且它引入了更ؓ灉|的初始化和清理工作,q有限时的和参数化测试用例?

  代码实例最能说明问题。因此,在本文中Q我用一个例子来展示不同的测试用例:一个计器。该CZ计算器很单,效率q不高,甚至q有一些错误;它仅仅操作整敎ͼq且把结果存储在一个静态变量中。SubstractҎq不q回一个有效的l果Q而且也没有实C法运,而且看上dsquareRootҎ中还存在一个错误:无限循环。这些错误将帮助说明使用JUnit 4q行试的有效性。你可以打开和关闭这个计器Q而且你可以清除这些结果。下面是其实C码:

package calc;
public class Calculator {
 private static int result; //存储l果的静态变?br />  public void add(int n) {
  result = result + n;
 }
 public void substract(int n) {
  result = result - 1; //错误Q应该是"result = result - n"
 }
 public void multiply(int n) {} //q没实现
 public void divide(int n) {
  result = result / n;
 }
 public void square(int n) {
  result = n * n;
 }
 public void squareRoot(int n) {
  for (; ;) ; //错误Q无限@?br />  }
 public void clear() { //清除l果
  result = 0;
 }
 public void switchOn() { //打开屏幕Q显C?hello"Qƈ报警
  result = 0; //实现其它的计器功能
 }
 public void switchOff() { } //昄"bye bye"Q报警,q关闭屏q?br />  public int getResult() {
  return result;
 }
}

  二?q移一个测试类

  现在Q我把一个已l用JUnit 3.8~写成的单的试c迁UdJUnit 4。这个类有一些缺P它没有测试所有的业务ҎQ而且看上dtestDivideҎ中还存在一个错?8/2不等?)。因没有实现乘法q算功能Q所以对其测试将被忽略?br />
  下面Q我们把两个版本的框架之间的差别以粗体显C出C表格1中?br />
  表格1.分别以JUnit 3.8和JUnit 4实现的CaculatorTest?br />
  JUnit 3.8

package junit3;
import calc.Calculator;
import junit.framework.TestCase;
public class CalculatorTest extends TestCase {
 private static Calculator calculator = new Calculator();
 @Override protected void setUp() { calculator.clear(); }
 public void testAdd() {
  calculator.add(1);
  calculator.add(1);
  assertEquals(calculator.getResult()Q?2);
 }
 public void testSubtract() {
  calculator.add(10);
  calculator.subtract(2);
  assertEquals(calculator.getResult()Q?8);
 }
 public void testDivide() {
  calculator.add(8);
  calculator.divide(2);
  assert calculator.getResult() == 5;
 }
 public void testDivideByZero() {
  try {
   calculator.divide(0);
   fail();
  }
  catch (ArithmeticException e) { }
 }
 public void notReadyYetTestMultiply() {
  calculator.add(10);
  calculator.multiply(10);
  assertEquals(calculator.getResult()Q?100);
 }
}

  JUnit 4

package JUnit 4;
import calc.Calculator;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
public class CalculatorTest {
 private static Calculator calculator = new Calculator();
 @Before public void clearCalculator() {
  calculator.clear();
 }
 @Test public void add() {
  calculator.add(1);
  calculator.add(1);
  assertEquals(calculator.getResult()Q?2);
 }
 @Test public void subtract() {
  calculator.add(10);
  calculator.subtract(2);
  assertEquals(calculator.getResult()Q?8);
 }
 @Test public void divide() {
  calculator.add(8);
  calculator.divide(2);
  assert calculator.getResult() == 5;
 }
 @Test(expected = ArithmeticException.class)
 public void divideByZero() {
  calculator.divide(0);
 }
 @Ignore("not ready yet")
 @Test
 public void multiply() {
  calculator.add(10);
  calculator.multiply(10);
  assertEquals(calculator.getResult()Q?100);
 }
}
  三??br />
  首先Q你可以看到QJUnit 4使用org.junit.*包而JUnit 3.8使用的是junit.framework.*。当ӞZ向后兼容性v见,JUnit 4jar文g发行中加入了q两U包?br />
  四?l承

  在JUnit4中,试cM必再扩展junit.framework.TestCaseQ事实上Q它们不必须扩展M内容。但是,JUnit 4中用的是注解。ؓ了以一个测试用例方式执行,一个JUnit 4cM臛_需要一个@Test注解。例如,如果你仅使用@Before和@After注解而没有至提供一个@TestҎ来编写一个类Q那么,当你试图执行它时得C个错误:

java.lang.Exception: No runnable methods.

  五?断言QAssertQ方?/strong>

  因ؓ在JUnit 4中一个测试类q不l承自TestCase(在JUnit 3.8中,q个cM定义了assertEquals()Ҏ)Q所以你必须使用前缀语法(举例来说QAssert.assertEquals())或者(׃JDK5.0Q静态地导入AssertcR这样以来,你就可以完全象以前一样用assertEqualsҎ(举例来说QassertEquals())?br />
  另外Q在JUnit 4中,q引入了两个新的断言ҎQ它们专门用于数l对象的比较。如果两个数l包含的元素都相{,那么q两个数l就是相{的?br />
public static void assertEquals(String messageQ?Object[] expectedsQ?Object[] actuals);
public static void assertEquals(Object[] expectedsQ?Object[] actuals);

  ׃JDK 5.0的自动装机制的出现Q原先的Q2个assertEqualsҎ全部L了。例如,原先JUnit 3.8中的assertEquals(longQlong)Ҏ在JUnit 4中要使用assertEquals(ObjectQObject)。对于assertEquals(byteQbyte)、assertEquals(intQint){也是这栗这U改q将有助于避免反模式?br />
  在JUnit 4中,新集成了一个assert关键?见我们的例子中的divide()Ҏ)。你可以象用assertEqualsҎ一h使用它,因ؓ它们都抛出相同的异常(java.lang.AssertionError)。JUnit 3.8的assertEquals抛Z个junit.framework.AssertionFailedError。注意,当用assertӞ你必L定Java?-ea"参数Q否则,断言被忽略?br />
  六?预设环境QFixtureQ?/strong>

  Fixture是在试期间初始化和释放M普通对象的Ҏ。在JUnit 3.8中,你要使用setUp()来实现运行每一个测试前的初始化工作Q然后用tearDown()来进行每个测试后的清理。这两个Ҏ在TestCasecM都得到重载,因此都被唯一定义。注意,我在q个SetupҎ使用的是Java5.0内置的@Override注解-q个注解指示该方法声明要重蝲在超cM的方法声明。在JUnit 4中,则代之用的是@Before和@After注解Q而且Q可以以M命名(在我们的例子中是clearCalculator())来调用这些方法。在本文后面Q我更多地解释q些注解?br />
  七?试

  JUnit 3.8通过分析它的{֐来识别一个测试方法:Ҏ名必M"test"为前~Q它必须q回voidQ而且它必L有Q何参?举例来说QpublicvoidtestDivide())。一个不遵@q个命名U定的测试方法将被框架简单地忽略Q而且不抛ZQ何异常(指示发生了一个错误)?br /> JUnit 4不用与JUnit 3.8相同的约定。一个测试方法不必以'test'为前~Q但是要使用@Test注解。但是,正如在前一个框架中一P一个测试方法也必须q回voidq且是无参数的。在JUnit 4中,可以在运行时L制这个要求,q且不符合要求的话会抛出一个异常:

java.lang.Exception: Method xxx should have no parameters
java.lang.Exception: Method xxx should be void

  @Test注解支持可选参数。它声明一个测试方法应该抛Z个异常。如果它不抛出或者如果它抛出一个与事先声明的不同的异常Q那么该试p|。在我们的例子中Q一个整数被雉应该引发一个ArithmeticException异常?br />
  八?忽略一个测?/strong>

  CQ不能执行多个方法。然而,如果你不惌试p|的话Q你可以仅仅忽略它。那么,在JUnit 3.8中,我们是如何实C时禁止一个测试的?Ҏ是:通过注释掉它或者改变命名约定,q样试q行机就无法扑ֈ它。在我的例子中,我用了Ҏ名notReadyYetTestMultiply()。它没有?test"开_所以它不会被识别出来。现在的问题是,在成百上千的试中间Q你可能C住重命名q个Ҏ?br />
  在JUnit 4中,Z忽略一个测试,你可以注释掉一个方法或者删除@Test注解(你不能再改变命名U定Q否则将抛出一个异?。然而,该问题将保留Q该q行机将不报告这样一个测试。现在,你可以把@Ignore注解d到@Test的前面或者后面。测试运行机报告被忽略的测试的个数Q以及运行的试的数目和q行p|的测试数目。注意,@Ignore使用一个可选参?一个String)Q如果你惌录ؓ什么一个测试被忽略的话?br />
  九?q行试

  在JUnit 3.8中,你可以选择使用若干q行机:文本型,AWT或者Swing。JUnit 4仅仅使用文本试q行机。注意,JUnit 4不会昄Ml色条来通知你测试成功了。如果你想看CQ何类型的l色的话Q那么你可能需要用JUnit扩展或一U集成了JUnit的IDEQ例如IDEA或者EclipseQ?br />
  首先Q我想用老式但好用的junit.textui.TestRunner来运行该JUnit 3.8试c?考虑C用assert关键字,我用了-ea参数)?br /> java -ea junit.textui.TestRunner junit3.CalculatorTest

..F.E.
There was 1 error:
1) testDivide(junit3.CalculatorTest)java.lang.AssertionError
at junit3.CalculatorTest.testDivide(CalculatorTest.java:33)
There was 1 failure:
1) testSubtract(junit3.CalculatorTest)junit.framework.AssertionFailedError: expected:Q?Q?but was:Q?Q?br /> at junit3.CalculatorTest.testSubtract(CalculatorTest.java:27)
FAILURES!!!
Tests run: 4Q?Failures: 1Q?Errors: 1

  TestDivide产生一个错误,因ؓ断言定?/2不等?。TestSubstract产生一个失败,因ؓ10-2应该{于8Q但是在q个实现中存在一个错误:它返??br />
  现在Q我使用新的org.junit.runner.JUnitCoreq行机来q行q两个类。注意,它能执行JUnit 4和JUnit 3.8试Q甚xq二者的l合?br />

java -ea org.junit.runner.JUnitCore junit3.CalculatorTest

JUnit version 4.1

..E.E.
There were 2 failures:
1) testSubtract(junit3.CalculatorTest)
junit.framework.AssertionFailedError: expected:Q?Q?but was:Q?Q?br /> at junit.framework.Assert.fail(Assert.java:47)
2) testDivide(junit3.CalculatorTest)
java.lang.AssertionError
at junit3.CalculatorTest.testDivide(CalculatorTest.java:33)
FAILURES!!!
Tests run: 4Q?Failures: 2
***

java -ea org.junit.runner.JUnitCore JUnit 4.CalculatorTest

JUnit version 4.1
...E.EI
There were 2 failures:
1) subtract(JUnit 4.CalculatorTest)
java.lang.AssertionError: expected:Q?Q?but was:Q?Q?br /> at org.junit.Assert.fail(Assert.java:69)
2) divide(JUnit 4.CalculatorTest)
java.lang.AssertionError
at JUnit 4.CalculatorTest.divide(CalculatorTest.java:40)
FAILURES!!!
Tests run: 4Q?Failures: 2

  W一个非常明昄区别是,JUnit版本可昄于控制台?4.1)。第二个区别是,JUnit 3.8区分p|和错误;JUnit 4则仅使用p|q行化。一个新奇的地方是,字母"I"Q它昄一个测试被忽略?br />  十?高񔋹试

  现在Q我展CJUnit 4的一些高U特征。列?(见下载源?是一个新的测试类-AdvancedTestQ它z自AbstractParent?br />
  (一) 高预设环境

  两个c都使用新的注解@BeforeClass和@AfterClassQ还有@Before和@After。表?展示了在q些注解之间的主要区别?br />
  表格2.@BeforeClass/@AfterClass比较于@Before/@After?br />

@BeforeClass和@AfterClass @Before和@After
在每个类中只有一个方法能被注解? 多个Ҏ能被注解Q但其执行的序未特别指定,且不q行重蝲Ҏ?
Ҏ名是不相关的 Ҏ名是不相关的
每个c运行一? 在每个测试方法运行前或运行后q行
在当前类的@BeforeClassҎq行前先q行类的@BeforeClassҎ。在类中声明的@AfterClassҎ在所有当前类的该Ҏq行后才q行? 类中的@Before在所有子cȝ该方法运行前q行。在类中的@After在在所有子cȝ该方法运行后才运行?
必须是公共和非静态的? 必须是公共和非静态的?
即一个@BeforeClassҎ抛出一个异常,所有的@AfterClassҎ也保证被q行? 即一个@Before或者@TestҎ抛出一个异常,所有的@AfterҎ也保证被q行?/td>

  如果你仅有一ơ需要分配和释放昂贵的资源,那么@BeforeClass和@AfterClass可能很有用。在我们的例子中QAbstractParent使用q些在startTestSystem()和stopTestSystem()Ҏ上的注解启动和停止整个测试系l。ƈ且它使用@Before和@After初始化和清除pȝ。子cAdvancedTest也؜合用这些注解?br />
  在你的测试代码中使用System.out.println不是一U良好的实践习惯Q但是,在这个用例中Q它有助于理解这些注解被调用的顺序。当我运行AdvancedTestӞ我得到如下结果:

Start test system //父类的@BeforeClass
Switch on calculator //子类的@BeforeClass

Initialize test system //W一个测?br /> Clear calculator

Initialize test system //W二个测?br /> Clear calculator
Clean test system

Initialize test system //W三个测?br /> Clear calculator
Clean test system

Initialize test system //W四个测?br /> Clear calculator
Clean test system

Switch off calculator //子类的@AfterClass
Stop test system //父类的@AfterClass

  如你所见,@BeforeClass和@AfterClass仅被调用一ơ,而@Before和@Afterare在每ơ测试中都要调用?

  (? 限时试

  在前面的例子中,我ؓsquareRoot()Ҏ~写了一个测试用例。记住,在这个方法中存在一个错?能够D它无限@环。如果没有结果的话,我想让这个测试在Q秒钟后退出。这一功能正是timeout参数所要实现的。@Test注解的第二个可选参敎ͼW一个参数是必需?可以使一个测试失败,如果该测试花Ҏ一个预先确定的旉(毫秒)q长的时间的话。当我运行该试Ӟ我得到如下的q行l果Q?br />
There was 1 failure:

1) squareRoot(JUnit 4.AdvancedTest)
java.lang.Exception: test timed out after 1000 milliseconds
at org.junit.internal.runners.TestMethodRunner.runWithTimeout(TestMethodRunner.java:68)
at org.junit.internal.runners.TestMethodRunner.q行(TestMethodRunner.java:43)

FAILURES!!!
Tests run: 4Q?Failures: 1

  (? 参数化测?br />
  在列?中,我测试了squareRootQ它是squareҎ而不是squareRootҎQ?通过创徏若干试Ҏ(square2Qsquare4Qsquare5)Q这些方法都完成相同的事情(通过被一些变量参数化实现Q。其实,现在q里的复?_脓技术可以通过使用一个参数化试用例加以优化(列表2)?br />
  在列?Q见本文相应下蝲源码Q中的测试用例用了两个新的注解。当一个类被用@RunWith注释ӞJUnit调用被参考的cLq行该测试而不是用缺省的q行机。ؓ了用一个参数化试用例Q你需要用运行机org.junit.runners.Parameterized。ؓ了确定用哪个参敎ͼ该测试用例需要一个公共静态方?在此是data()Q但是名字似乎无?Q该Ҏq回一个CollectionQƈ且被使用@参数加以注解。你q需要一个用这些参数的公共构造函数?br />
  当运行这个类Q该输出?

java org.junit.runner.JUnitCore JUnit 4.SquareTest
JUnit version 4.1

.......E

There was 1 failure:
1) square[6](JUnit 4.SquareTest)
java.lang.AssertionError: expected:Q?8Q?but was:Q?9Q?br /> at org.junit.Assert.fail(Assert.java:69)

FAILURES!!!
Tests run: 7Q?Failures: 1

  在此Q共执行?个测试,好象~写了7个单独的squareҎ。注意,在我们的试中出C一个失败,因ؓ7的^Ҏ49Q而不?8?br />
  (? 试?br />
  Z在JUnit 3.8的一个测试集中运行若q测试类Q你必须在你的类中添加一个suite()Ҏ。而在JUnit 4中,你可以用注解来代之。ؓ了运行CalculatorTest和SquareTestQ你需要用@RunWith和@Suite注解~写一个空cR?br />
package JUnit 4;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
CalculatorTest.classQ?br /> SquareTest.class
})
public class AllCalculatorTests {}
java -ea org.junit.runner.JUnitCore JUnit 4.AllCalculatorTests
JUnit version 4.1
...E.EI.......E
There were 3 failures:
1) subtract(JUnit 4.CalculatorTest)
java.lang.AssertionError: expected:Q?Q?but was:Q?Q?br /> at org.junit.Assert.fail(Assert.java:69)
2) divide(JUnit 4.CalculatorTest)
java.lang.AssertionError
at JUnit 4.CalculatorTest.divide(CalculatorTest.java:40)
3) square[6](JUnit 4.SquareTest)
java.lang.AssertionError: expected:Q?8Q?but was:Q?9Q?br /> at org.junit.Assert.fail(Assert.java:69)
FAILURES!!!
Tests run: 11Q?Failures: 3

  (? 试q行?br />
  在JUnit 4中,q泛C用测试运行机。如果没有指定@RunWithQ那么你的类仍然会用一个默认运行机(org.junit.internal.runners.TestClassRunner)执行。注意,最初的CalculatorcMq没有显式地声明一个测试运行机Q因此,它用的是默认运行机。一个包含一个带有@Test的方法的c都隐含地拥有一个@RunWith。事实上Q你可以把下列代码添加到CalculatorcMQ而且其输出结果会完全一栗?br />
import org.junit.internal.runners.TestClassRunner;
import org.junit.runner.RunWith;
@RunWith(TestClassRunner.class)
public class CalculatorTest {
...
}

  在@Parameterized和@Suite的情况下Q我需要一个特定的q行机来执行我的试用例。这是Z么我昑ּ地注解了它们?br />  十一?工具集成功能

  当我写本文时QJUnit 4在IDE斚w的集成还不是很理惟뀂事实上Q如果你试图q行我们刚才看到的那个测试类的话Q它们无法工作在MIDE环境中,因ؓ它们不能被识别ؓ试cRؓ了向前兼Ҏv见,JUnit 4发行中带有一个适配?junit.framework.JUnit 4TestAdapter)Q你必须把它使用于一个suite()Ҏ中。下面是你必L加到每个cM的代码;q样以来Q它们才能ؓ各种IDEQAnt以及JUnit 3.8中的文本q行机所识别Q?br />
public static junit.framework.Test suite() {
 return new JUnit 4TestAdapter(CalculatorTest.class);
}

  (一) Intellij IDEA

  IDEA 5q没有集成JUnit 4。没有办法,我们只好{待IDEA 6中实现这一集成了。在q个例子中,我用了较早的发行版?Demetra build 5321)Q但是,参数化测试用例仍不能工作。图1展示了这个CalculatorTest的执行情?被忽略的试以一个不同的图标标志)?br />

?.IDEADemetra仅能q行CalculatorTest?br />
?.Eclipse 3.2RC7能够q行试集类AllCalculatorTests?/div>

  (? Eclipse

  我现在用的是Eclipse?.2 RC7版本。虽然它q不是一个稳定发行版本,但是其与JUnit 4的集成优于IDEA。上图2展示了在q行AllCalculatorTestscL你能看到的结果?br />
  如你所见,该参数化试用例(SquareTest)被描qCؓ7个单独的试?br />
  (? Ant集成

  junitd当前仅仅支持JUnit 3.8风格试Q这也就是说Q你q必ȝ一个JUnit 4 TestAdapter来包装你的JUnit 4试Q这P它们才能在Ant中运行。这个<junitQQ务与其在JUnit 3.8中用法一P

Q?-- Test --Q?br /> Qtarget name="test" depends="compile"Q?br /> Qjunit fork="yes" haltonfailure="yes"Q?br /> Qtest name=" JUnit 4.AllCalculatorTests"/Q?br /> Qformatter type="plain" usefile="false"/Q?br /> Qclasspath refid="classpath"/Q?br /> Q?junitQ?br /> Q?targetQ?/td>

  十二?l论

  有很长一D|_JUnit直成了事实上的单元测试框架标准。但是,q来Q这个框架似乎无?动静"Q没有重要的发行版本Q没有引人注目的新特征出现。这可能是ؓ什么其它测试框Ӟ例如Test-NG开始逐渐占居试框架市场l治C的原因?br />
  随着q个新版本的发行QJUnit又出C新的转机。如今,它提供了许多新的APIQ而且现在q用注解,所以开发测试用例更为容易。事实上Q该JUnit开发者已l开始考虑新的未来的注解问题。例如,你可以在一个依赖于前提(举例来说Q你需要在U地执行q个试)的测试用例上d一个@Prerequisite注解Q或者添加一个能够指定重复次数及旉(举例来说Q重复测?ơ以保真正出现了一个时限问?的@Repeat注解Q或者甚臛_@Ignore注解上添加一个^台参敎ͼ举例来说Q@Ignore(platform=macos)Q这只有你在一个MacOSq_上运行时才忽略一个测?。从本文中你能看刎ͼJUnit的未来依然灿烂辉煌?/font>

]]>
TestSuite议http://www.aygfsteel.com/supercrsky/articles/162774.html々上善若水?/dc:creator>々上善若水?/author>Sat, 24 Nov 2007 00:34:00 GMThttp://www.aygfsteel.com/supercrsky/articles/162774.htmlhttp://www.aygfsteel.com/supercrsky/comments/162774.htmlhttp://www.aygfsteel.com/supercrsky/articles/162774.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/162774.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/162774.html您定义自qTestCaseQƈ使用TestRunner来运行测试,事实上TestRunnerq不直接q行 TestCase上的单元ҎQ而是透过TestSuiteQTestSuite可以数个TestCase在一P而让每个TestCase保持单?/font>

来看看一个例子:
  • MathToolTest.java
package onlyfun.caterpillar.test;

import onlyfun.caterpillar.MathTool;
import junit.framework.TestCase;

public class MathToolTest extends TestCase
{
    
public MathToolTest(String testMethod)
    
{
        
super(testMethod);
    }


    
public void testGcd()
    
{
        assertEquals(
5, MathTool.gcd(105));
    }


    
public static void main(String[] args)
    
{
        junit.textui.TestRunner.run(MathToolTest.
class);
    }

}

在这个例子中Q您q没有看CQ何的TestSuiteQ事实上Q如果您没有提供M的TestSuiteQTestRunner会自己徏立一个,然后q个 TestSuite会用反(reflectionQ自动找出testXXX()Ҏ?br />
如果您要自行生成TestSuiteQ则在承TestCase之后Q提供静态的QstaticQ的suite()ҎQ例如:
public static Test suite() {
     
return new TestSuite(MathTool.class);
}


如果您没有提供Q何的TestSuiteQ则TestRunner׃像上面这栯动ؓ您徏立一个,q找出testXXX()ҎQ您也可以如下面定义 suite()ҎQ?br />
public static Test suite() {
     TestSuite suite 
= new TestSuite(MathTool.class);
     suite.addTest(
new MathToolTest("testGcd"));
     
return suite;
}


 
JUnitq没有规定您一定要使用testXXX()q样的方式来命名您的试ҎQ如果您要提供自qҎQ当然JUnit 鼓励您用testXXX()q样的方法名UͼQ则可以如上撰写Qؓ了要能够使用建构函式提供试Ҏ名称Q您的TestCase必须提供如下的徏构函式:
public MathToolTest(String testMethod) {
    
super(testMethod);
}

 

如果要加入更多的试ҎQ用addTest()可以了Qsuite()Ҏ传回一个TestSuite物gQ它?TestCase都实作了Test介面QTestRunner会调用TestSuite上的run()ҎQ然后TestSuite会将之委托给 TestCase上的run()ҎQƈ执行每一个testXXX()Ҏ?br />
除了l合TestCase之外Q您q可以将CTestSuitel合在一P例如Q?/font>
public static Test suite() 
    TestSuite suite
= new TestSuite(); 
    suite.addTestSuite(TestCase1.
class);
    suite.addTestSuite(TestCase2.
class); 
    
return suite; 
}

 
如此之来Q您可以一ơ运行所有的试Q而不必个别的q行每一个测试案例,您可以写一个运行全部测试的L试,而在使用TestRunner时呼?suite()ҎQ例如:
junit.textui.TestRunner.run(TestAll.suite());


TestCase与TestSuite都实作了Test介面Q其q行方式?Command 模式 的一个实例,而TestSuite可以l合CTestSuite或TestCaseQ这?Composite 模式 的一个实例?br />

]]>
JUnit4.x与JUnit3.x的一个重要区?/title><link>http://www.aygfsteel.com/supercrsky/articles/162772.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Fri, 23 Nov 2007 23:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/162772.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/162772.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/162772.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/162772.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/supercrsky/services/trackbacks/162772.html</trackback:ping><description><![CDATA[<p><br /> <span style="font-family: Comic Sans MS">在JUnit3.x中对试必须l承 TestCase,q且每个Ҏ名必Mtest开?比如:testMethod1</span></p> <p><span style="font-family: Comic Sans MS">()而在JUnit4.x中不必承TestCase,采用了注解的方式.只要在测试的Ҏ上加上注?/span></p> <p><span style="font-family: Comic Sans MS">@Test,卛_.在JUnit4.x中如果承了TestCase,而注解就不v作用?q且有很重要的一?/span></p> <p><span style="font-family: Comic Sans MS">是在JUnit4.x中承了TestCase?在OutLine视图中测试单个方法时,l果整个c都run</span></p> <p><span style="font-family: Comic Sans MS">? q有一点就??.x中需要实现setUp和tearDownҎ,而在4.x中无需q样,可以自定?/span></p> <p><span style="font-family: Comic Sans MS">需要在试前和试后的Ҏ,在方法前加上Annotation@before,@after可以了.<br /> Ҏ,在JUnit4.x不必l承TestCase用注解即可对单个Ҏq行试.q个问题郁闷?br /> 我半?解决?真高?</span></p> <p> <br /> </p> <img src ="http://www.aygfsteel.com/supercrsky/aggbug/162772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2007-11-24 07:56 <a href="http://www.aygfsteel.com/supercrsky/articles/162772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EasyMock使用手记http://www.aygfsteel.com/supercrsky/articles/162766.html々上善若水?/dc:creator>々上善若水?/author>Fri, 23 Nov 2007 23:22:00 GMThttp://www.aygfsteel.com/supercrsky/articles/162766.htmlhttp://www.aygfsteel.com/supercrsky/comments/162766.htmlhttp://www.aygfsteel.com/supercrsky/articles/162766.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/162766.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/162766.html阅读全文

]]>
վ֩ģ壺 | ɽ| ٽ| ͺ| | | | ԫ| SHOW| «| | ̨| | | | | | ˶| Ͻ| ĵ| | | ˮ| | ƽ| ʲ| | ֵ| | ƽ| | | | ľ| | | ˮ| | | | |