??xml version="1.0" encoding="utf-8" standalone="yes"?>
我们在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>
<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格式?
]]>
然后保你的jdk版本?.5以上.
W一?
扑ֈ你下载的selenium解压目录下的selenium-server-0.9.2目录.
在这个目录下写个批处?内容?
java -jar selenium-server.jar
必须先启动这?启动后的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>
<!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");
}
}
源码可在我的|盘下蝲.
]]>
把一些用心得分享给大家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 代码
代码十分单,作用是初始化一?Selenium 对象。其中:
url : 是你要试的网?br />
localhost: 可以不是localhostQ但是必L selenium server 启动的地址
*iexplore : 可以是其它浏览器cdQ可以在|站上看都支持哪些?/span>
下面我就要讲讲怎么使用selenium q个对象来进行测试?/span>
1、测试文本输入框
假设面上有一个文本输入框Q我们要试的内Ҏ 在其中输入一些内容,然后点击一个按钮,看看面的是否蟩?br /> 到需要的面?br />
上面的代码是q个意思:
1、调?selenium.open ҎQ浏览器会打开相应的页?br />
2、?type Ҏ来给输入框输入文?br />
3、等待页面蝲?br />
4、看看新的页面标题是不是我们惌的?/span>
2、测试下拉框
java 代码可以看到Q我们可以?select Ҏ来确定选择下拉框中的哪个选项?br /> select Ҏq有很多用法Q具体去看看文档吧?/span>
3、测试check box
java 代码
我们可以使用 check Ҏ来确定选择哪个radio button
4、得到文本框里的文字
java 代码
getValue Ҏ是得到文本框里的数|可不?getText ҎQ用错了可就郁闷了?/span>
5、判断页面是否存在一个元?/span>
java 代码
一般这个是用来试当删除一些数据后Q页面上有些东西׃会显C的情况?/span>
6、判断下拉框里选择了哪个选项
java 代码
q个可以用来判断下拉框显C的选项是否是期望的选项?/span>
7、如果有 alert 弹出对话框怎么办?
q个问题弄了挺长旉Q可以这h关闭弹出的对跨框Q?/span>
java 代码其实当调?selenium.getAlert() Ӟ׃关闭 alert 弹出的对话框?br /> 也可以?System.out.println(selenium.getAlert()) 来查看对跨框昄的信息?/span>
在测试的时候,有的Z昄许多alert 来查看运行时的数据,那么我们可以用下面的方式来关闭那?alert:
java 代码8、如何测试一些错误消息的昄Q?/span>
java 代码切记Q?getBodyText q回的时览器页面上的文字,不回包含html 代码的,如果要显Chtml 代码Q用下面q个:
java 代码以上是最常用的几个方法了Q例?click, type, getValue {等?br /> q有是一定要学习 xpath, 其实xpath 也可以有“与、或、非”的操作:
java 代码四、其?/span>
selenium q有更多的用法,例如弹出面{等。当面对没见q的试要求Ӟ我最W的Ҏ是按照api文档一个一个找Q?br /> 好在不多Q肯定能扑ֈ?br />
Student:
集合试的类:PersonSuite
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; } } |
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); } } |
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); } } |
public static void assertEquals(String messageQ?Object[] expectedsQ?Object[] actuals); public static void assertEquals(Object[] expectedsQ?Object[] actuals); |
..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 |
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 |
@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> |
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 |
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 |
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 |
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 |
import org.junit.internal.runners.TestClassRunner; import org.junit.runner.RunWith; @RunWith(TestClassRunner.class) public class CalculatorTest { ... } |
public static junit.framework.Test suite() { return new JUnit 4TestAdapter(CalculatorTest.class); } |
![]() ?.IDEADemetra仅能q行CalculatorTest?br /> ![]() ?.Eclipse 3.2RC7能够q行试集类AllCalculatorTests?/div> |
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> |
()而在JUnit4.x中不必承TestCase,采用了注解的方式.只要在测试的Ҏ上加上注?/span>
@Test,卛_.在JUnit4.x中如果承了TestCase,而注解就不v作用?q且有很重要的一?/span>
是在JUnit4.x中承了TestCase?在OutLine视图中测试单个方法时,l果整个c都run
? q有一点就??.x中需要实现setUp和tearDownҎ,而在4.x中无需q样,可以自定?/span>
需要在试前和试后的Ҏ,在方法前加上Annotation@before,@after可以了.
Ҏ,在JUnit4.x不必l承TestCase用注解即可对单个Ҏq行试.q个问题郁闷?br />
我半?解决?真高?