环境如何搭建不讲了
需要的jar包:selenium-server-standalone-2.53.1.jar
将以上jar包及Junit添加到build path中
1、编写脚本
刚开始并不知道webdriver的具体语法,所以是用selenium IDE变更format为java/webdriver/junit,然后把代码复制到eclipse中,在此基础上进行更改的。直接复制出来的代码就是JUnit 脚本。
2、运行脚本
直接在代码中右键-> Run As -> JUnit Test,就可以运行脚本了。一般默认是由Firefox运行,也可以下载其他浏览器的driver来替代。
3、创建自动截图
确认脚本可以正常运行后,在此基础上增强功能,一般自动截图是必不可少的。但是由于本人刚开始接触webdriver,只能看懂网上一些主动截图的代码,看不懂那些利用监听达到自动截图目的的代码,就只能在主动截图的方法上改进了一些,但是目前还是够用了。
主动截图:只能在每个断言中都添加一次截图方法,会用到很多重复的代码。
截图方法:AutoScreenShot.java
import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class AutoScreenShot { public static int t = 1; public static String getDateTime(){ SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss"); return df.format(new Date()); } public static void ScreenShot(WebDriver dr, String dir){ File screenShot = ((TakesScreenshot)dr).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(screenShot, new File(dir+getDateTime()+"_"+t+".jpg")); ++t; } catch (IOException e) { e.printStackTrace(); } } } 实现截图操作: AutoScreenShot.ScreenShot(driver, "E:\\selenium\\FILE\\"); 利用监听器自动截图:http://www.jianshu.com/p/ddc9a3fcc8d9
因为上述方法本人并没有使用成功过,等以后再试一下。
改进后的截图方法:利用重写的assertEquals方法实现
从selenium IDE中得到的断言代码是这么写的:
try { assertEquals("76", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[4]")).getText()); } catch (Error e) { verificationErrors.append(e.toString()); } 失败抛出异常: @After public void tearDown() throws Exception { driver.quit(); String verificationErrorString = verificationErrors.toString(); if (!"".equals(verificationErrorString)) { fail(verificationErrorString); } }如果要实现主动截图的话就需要在每个断言的抛出异常中加入实现的代码: try { assertEquals("1x", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[1]")).getText()); } catch (Error e) { verificationErrors.append(e.toString()); AutoScreenShot.ScreenShot(driver, "E:\\selenium\\FILE\\"); } 这样代码就会很多很多,然后决定重写一个方法,代码如下: import static org.junit.Assert.assertEquals; import org.openqa.selenium.WebDriver; public class BaseClass{ private StringBuffer verificationErrors; private WebDriver driver; public BaseClass(StringBuffer verificationErrors,WebDriver driver){ this.verificationErrors = verificationErrors; this.driver = driver; } public void assertEqualsReWrite(Object a, Object b) { try{ assertEquals(a,b); }catch (Error e) { AutoScreenShot.ScreenShot(driver, "E:\\selenium\\FILE\\screenshot\\"); System.out.println("Expected Result:" + a +" , " + "Actual Result:" + b); verificationErrors.append(e.toString()); } } }具体的功能其实就是断言assertEquals,只是在其之上又加入了断言失败抛出异常并截图的功能。使用方法,在测试类中添加以下代码:
BaseClass baseclass = new BaseClass(verificationErrors,driver); baseclass.assertEqualsReWrite("1", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[1]")).getText());完整代码:
AutoScreenShot.java
package xxx; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class AutoScreenShot { public static int t = 1; public static String getDateTime(){ SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss"); return df.format(new Date()); } public static void ScreenShot(WebDriver dr, String dir){ File screenShot = ((TakesScreenshot)dr).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(screenShot, new File(dir+getDateTime()+"_"+t+".jpg")); ++t; } catch (IOException e) { e.printStackTrace(); } } } BaseClass.java package xxx; import static org.junit.Assert.assertEquals; import org.openqa.selenium.WebDriver; public class BaseClass{ private StringBuffer verificationErrors; private WebDriver driver; public BaseClass(StringBuffer verificationErrors,WebDriver driver){ this.verificationErrors = verificationErrors; this.driver = driver; } public void assertEqualsReWrite(Object a, Object b) { try{ assertEquals(a,b); }catch (Error e) { AutoScreenShot.ScreenShot(driver, "E:\\selenium\\FILE\\screenshot\\"); System.out.println("Expected Result:" + a +" , " + "Actual Result:" + b); verificationErrors.append(e.toString()); } } } TestDemo.java(测试类) package xxx; import static org.junit.Assert.*; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class TestDemo { private WebDriver driver; private String baseUrl; private StringBuffer verificationErrors = new StringBuffer(); @Before public void setUp() throws Exception { driver = new FirefoxDriver(); baseUrl = "http://localhost:8080/"; driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); } @Test public void testAssert() throws Exception{ driver.get(baseUrl); for (int second = 0;; second++) { if (second >= 60) fail("timeout"); try { if (driver.findElement(By.id("username")).isDisplayed()) break; } catch (Exception e) {} Thread.sleep(1000); } driver.findElement(By.id("username")).clear(); driver.findElement(By.id("username")).sendKeys("Admin"); driver.findElement(By.id("password")).clear(); driver.findElement(By.id("password")).sendKeys("123456"); for (int second = 0;; second++) { if (second >= 60) fail("timeout"); try { if (driver.findElement(By.id("login")).isDisplayed()) break; } catch (Exception e) {} Thread.sleep(1000); } driver.findElement(By.id("login")).click(); Thread.sleep(1000); BaseClass baseclass = new BaseClass(verificationErrors,driver); baseclass.assertEqualsReWrite("1", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[1]")).getText()); baseclass.assertEqualsReWrite("76", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[4]")).getText()); baseclass.assertEqualsReWrite("1042", driver.findElement(By.xpath("//table[@id='xxxx']/tbody/tr[1]/td[5]")).getText()); System.out.println("group 1"); } @After public void tearDown() throws Exception { driver.quit(); String verificationErrorString = verificationErrors.toString(); if (!"".equals(verificationErrorString)) { fail(verificationErrorString); } } } 至此截图功能完成,如果断言有错误就会在"E:\\selenium\\FILE\\screenshot\\"中保存图片4、利用ant生成Junit测试报告
ant是eclipse中自带的工具,所以不需要再安装,使用方法如下。
1> 确保每个测试都已经运行一遍
2> 右键项目-> Export... -> General -> Ant Buildfiles -> 选择需要的项目名勾上复选框 -> 其他都是默认,点击next -> finish,然后会在根目录下生成build.xml文件
3> 修改build.xml文件 具体代码如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- WARNING: Eclipse auto-generated file. Any modifications will be overwritten. To include a user specific buildfile here, simply create one in the same directory with the processing instruction <?eclipse.ant.import?> as the first entry and export the buildfile again. --><project basedir="." default="build" name="RegressionTest"> <property environment="env"/> <property name="ECLIPSE_HOME" value="D:/DEV/Eclipse/eclipse"/> <property name="junit.output.dir" value="junit"/> <property name="debuglevel" value="source,lines,vars"/> <property name="target" value="1.7"/> <property name="source" value="1.7"/> <path id="JUnit 4.libraryclasspath"> <pathelement location="${ECLIPSE_HOME}/plugins/org.junit_4.11.0.v201303080030/junit.jar"/> <pathelement location="${ECLIPSE_HOME}/plugins/org.hamcrest.core_1.3.0.v201303031735.jar"/> </path> <path id="RegressionTest.classpath"> <pathelement location="bin"/> <pathelement location="E:/selenium/selenium-server-standalone-2.53.1.jar"/> <path refid="JUnit 4.libraryclasspath"/> </path> <target name="init"> <mkdir dir="bin"/> <copy includeemptydirs="false" todir="bin"> <fileset dir="src"> <exclude name="**/*.launch"/> <exclude name="**/*.java"/> </fileset> </copy> </target> <target name="clean"> <delete dir="bin"/> </target> <target depends="clean" name="cleanall"/> <target depends="build-subprojects,build-project" name="build"/> <target name="build-subprojects"/> <target depends="init" name="build-project"> <echo message="${ant.project.name}: ${ant.file}"/> <javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}"> <src path="src"/> <classpath refid="RegressionTest.classpath"/> </javac> </target> <target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/> <target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler"> <copy todir="${ant.library.dir}"> <fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/> </copy> <unzip dest="${ant.library.dir}"> <patternset includes="jdtCompilerAdapter.jar"/> <fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/> </unzip> </target> <target description="compile project with Eclipse compiler" name="build-eclipse-compiler"> <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/> <antcall target="build"/> </target> <target name="TestDemo"> <mkdir dir="${junit.output.dir}"/> <junit fork="yes" printsummary="withOutAndErr"> <formatter type="xml"/> <test name="xxx" todir="${junit.output.dir}"/> <classpath refid="RegressionTest.classpath"/> </junit> <antcall target="junitreport"/> </target> <target name="junitreport"> <junitreport todir="${junit.output.dir}"> <fileset dir="${junit.output.dir}"> <include name="TEST-*.xml"/> </fileset> <report format="frames" todir="${junit.output.dir}"/> </junitreport> </target> </project> 主要关注的是以下的代码部分,需要与自己的项目名及class名、包名相对应。RegressionTest、RegressionTest.classpath、TestDemo、xxx
特别要关注<antcall target="junitreport"/>的代码,因为之前自动生成的build.xml文件中没有这一句代码,所以不管我怎么运行都只生成了Junit文件夹和一个xml文件,而没有网上说的index.html文件,后来看了很多其他人的代码才发现他们都有这句代码,添加后果然就生成了很多的文件。 4> 运行build.xml生成报告
右键点击build.xml - > Run As -> Ant Build... -> 在Targets中选择需要的测试名(build [default]是需要默认勾上的),也可在Target execution order中进行测试用例的排序 -> 点击Run运行测试用例,完成后会在根目录下生成Junit文件夹,使用Web Browser方式查看其中的index.html文件,会有测试报告。
PS:原来想实现不关闭浏览器执行所有的测试案例的功能,但是网上一直没有查到可行的方法,有些人说这么做是不符合测试规则的,但是我觉得现在每测试一个案例都需要关闭浏览器重启浏览器真的太烦躁了,之后看看有没有别的方式可以在上一个测试结果的情况下继续下一个测试而不需要重启浏览器吧。