自动化PC端部署:
1、PC自动化基于:
Java +selenium+testng+jenkins 搭建自动化测试环境
Selenium 主要完成PC前端页面自动化
2、通过java实现自动化测试代码开发
3、通过jenkins完成自动化批量执行
4、通过testng实现自动化用例运行结果正确性判断
5、通过jenkins完成测试结果输出及测试报告邮件发送
一、测试环境搭建:
1.安装JDK
2.安装Eclipse
3.安装Eclipse 插件ANT /TESTNG
4.Jenkins 构建配置、邮件发送配置
5.实例
1.1、安装JDK
用鼠标左键双击JDK安装包,会出现下图所示的安装界面。
点击下一步完成安装
1.1.2、配置环境变量
完成了JDK环境安装完成了。这个时候还要通过一系列的环境变量的配置才能使用JDK环境进行JAVA开发。
1.2.1、配置环境变量包括java_home,path和classpath三个部分。
用鼠标右击“我的电脑”,选择“属性”->“高级”->“环境变量”->“系统变量”->“新建”
“变量名”输入框中写入“java_home”,“变量值”输入框中写入“C:\ProgramFiles\Java\jdk1.6.0” (根据安装路径填写),然后点击“确定”,java_home就设置完成了。
“classpath”的配置。选中“系统变量”查看是否有classpath项目,如果没有就点击“新建”,如果已经存在就选中classpath选项,点击“编辑”按钮,然后在“变量名”中填写“classpath”,在“变量值”中填写“C:\Program Files\Java\jdk1.6.0\jre\lib”
“命令提示符”窗口。这个时候输入“java -version”
1.2、安装ant
下载Apache-ant后apache-ant-1.9.7-bin.zip为一个压缩文件,解压到你想要安装的目录(这个解压直接可以用不用安装),然后你需要配置一下环境变量
配置ANT_HOME
ANT_HOME:D:\apache-ant-1.9.4-bin\apache-ant-1.9.4 此为你的ANT安装路径;设置完成后,点击“确认”来保存。
在环境变量PATH的最后面添加一下内容:
;%ANT_HOME%\bin 注意前面的分号,如果PATH中最后没有分号“;”的话要加上,有的话就可去除。
进入cmd命令窗口,在CMD窗口中输入ant -version,敲击回城键,会显示出你安装的ANT版本,如果成功显示,说明你的配置应该是成功了,
1.3、安装TESTNG
启动Eclipse,选择“Install New Software”
单击“Add”
Name:TestNG
location:http://beust.com/eclipse
填写完毕,然后点击“OK”
选择“Select All”和“TestNG”,点击“Next”继续
选中项目,然后单击“Next”
勾选“Accept the License Agreement”,然后单击“Finish”
TestNG开始安装并且展示出进度
安装程序弹出的需要重启,单击“Yes”
安装完成后,在other里可以看到TestNG
TestNG项目
Annotations 选项一次对应的
BeforeSuite :在整个运行集合之前执行只运行一次
AfterSuite: 在集合运行之后执行只运行一次
新建完成后:
package SeleniumUI;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
public class NewTest {
@BeforeSuite
public void beforeSuite() {
}
@Test
/**添加测试方法*/
public void test() {
}
@AfterSuite
public void afterSuite() {
}
}
二、Eclipse 中配置批量执行配置(testng.xml)
<?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM"http://testng.org/testng-1.0.dtd">
<suite name="testsuite">
<!--配置执行类-->
<test verbose="3" name="ChongzhiTestngFirst"> <!--名字,日志级别-->
<classes>
<class name="SeleniumUI.ChongzhiTestngFirst"> <!--类名-->
</class> <!-- SeleniumUI.ChongzhiTestngFirst -->
</classes>
</test> <!--test2 -->
<test verbose="3" name="TixianJiekou">
<classes>
<class name="SeleniumUI.TixianJiekou">
</class> <!-- SeleniumUI.TixianJiekou -->
</classes>
</test> <!--test3 -->
<test verbose="3" name="B2Cchongzhi">
<classes>
<class name="SeleniumUI.B2Cchongzhi">
</class> <!-- SeleniumUI.B2Cchongzhi -->
</classes>
</test> <!--test4 -->
<test verbose="3" name="JiaoYiChaZhengJieKou">
<classes>
<class name="SeleniumUI.JiaoYiChaZhengJieKou">
</class> <!-- SeleniumUI.JiaoYiChaZhengJieKou -->
</classes>
</test> <!--test5 -->
<test verbose="3"name="TiXianTestNg_SeleniumUI">
<classes>
<class name="SeleniumUI.TiXianTestNg">
</class> <!-- SeleniumUI.TiXianTestNg -->
</classes>
</test> <!--test7 -->
<test verbose="3"name="HengFengChongZhi_SeleniumUI">
<classes>
<class name="SeleniumUI.HengFengChongZhi">
</class> <!-- SeleniumUI.HengFengChongZhi -->
</classes>
</test> <!--test8 -->
<test verbose="3" name="YueYingBaoDingGou_SeleniumUI">
<classes>
<class name="SeleniumUI.YueYingBaoDingGou">
</class> <!-- SeleniumUI.YueYingBaoDingGou -->
</classes>
</test> <!--test9 -->
<test verbose="3"name="DingQiBaoDingGou_SeleniumUI">
<classes>
<class name="SeleniumUI.DingQiBaoDingGou">
</class> <!-- SeleniumUI.DingQiBaoDingGou -->
</classes>
</test> <!--test10 -->
<test verbose="3"name="ShouYiRiLiYeMian_SeleniumUI">
<classes>
<class name="SeleniumUI.ShouYiRiLiYeMian">
</class> <!-- SeleniumUI.ShouYiRiLiYeMian -->
</classes>
</test> <!--test11 -->
<test verbose="3"name="ZuiXinGongGao_SeleniumUI">
<classes>
<class name="SeleniumUI.ZuiXinGongGao">
</class> <!-- SeleniumUI.ZuiXinGongGao -->
</classes>
</test> <!--test12 -->
</suite> <!--Default suite -->
三、ant配置,通过ant的build.xml配置完成自动化脚步编译、批量运行、生成报告
Build.xml配置
<?xml version="1.0"encoding="UTF-8"?>
<projectbasedir="."default="testoutput"name="automation test"><!--默认使用testoutput任务-->
<propertyname="base.dir"value="D:/JA/SeleniumUI/SeleniumUI"/><!--项目根目录-->
<propertyname="testng.output.dir"value="${base.dir}/result"/><!--配置结果输出地址-->
<propertyname="lib.dir"value="${base.dir}/lib"/><!--设置其他jar包目录-->
<propertyname="testng.file"value="${base.dir}/testng.xml"/><!--调用的testng用例执行xml文件,这里是文件名-->
<propertyname="testdir"location="test"/><!--设置编译的2进制文件目录-->
<taskdefresource="testngtasks"classpath="${lib.dir}/testng.jar"/><!--导入testng的jar包-->
<targetname="clean"><!--清除之前的2进制文件-->
<deletedir="${testdir}"/>
</target>
<targetname="compile"depends="clean">
<mkdirdir="${testdir}"/><!--新建2进制文件存放目录-->
<mkdirdir="result"/><!--新建结果导出目录-->
<javacsrcdir="${base.dir}/src"encoding="UTF-8"destdir="${testdir}"classpathref="classes"
includeantruntime="on"debug="on"debuglevel="lines,vars,source"/></target><!--编译java程序-->
<pathid="classes"><!--设置jar包相关-->
<filesetdir="${lib.dir}"includes="*.jar"/>
<pathelementlocation="${testdir}"/>
<pathelementlocation="${base.dir}/src"/>
</path>
<targetname="runtest"depends="compile">
<!--运行testng文件-->
<!-- 在target里面新建一个testng标签,里面需要设置的属性有:outputdir – 测试结果输出目录;classpathref – 那些自动化测试代码的目标路径,通常就是编译完成以后的那个目标路径,例如xxx/bin;delegateCommandSystemProperties –接受传递命令行参数作为系统变量,这个设置为true可以在调用Ant的时候通过 -Dfoo=value 把参数传递给TestNG;里面还有一个xmlfileset节点,这个节点就是指定testng.xml文件的目录以及具体文件。 -->
<testngoutputdir="${base.dir}/test-output"
classpathref="classes"
delegateCommandSystemProperties="true">
<xmlfilesetdir="${base.dir}"includes="testng.xml"/><!--在指定路径下,找文件名由testng.file-->
</testng><!--定义的testng.xml文件-->
</target>
<tstamp>
<formatproperty="CURTIME"pattern="yyyyMMdd_HHmmss"locale="us"/> <!--设置当前时间-->
</tstamp>
<pathid="test.classpath">
<filesetdir="${lib.dir}"includes="*.jar"/>
</path>
<targetname="testoutput"depends="runtest">
<xsltin="test-output/testng-results.xml"style="test-output/testng-results.xsl"
out="result/${CURTIME}/index.html">
<paramname="testNgXslt.outputDir"expression="${base.dir}/result/${CURTIME}/"/>
<paramname="testNgXslt.showRuntimeTotals"expression="true"/>
<paramname="testNgXslt.sortTestCaseLinks"expression="true"/>
<paramname="testNgXslt.testDetailsFilter"expression="FAIL,SKIP,PASS,CONF,BY_CLASS"/>
<classpathrefid="test.classpath"/>
</xslt>
</target>
</project>
四、Jenkins配置
Jenkins 地址:
用户名:admin
密码:a123456
All TestNg 是调用的Build.xml 完成编译、批量运行
运行过程中可以看到运行日志
4.1、新增用户信息
账号名称随便输入
E-mail 配置为管理员邮箱
其余默认
4.2、系统配置(系统管理-系统设置)
主目录、系统消息、执行者数量、标记、用法、生成前等待时间默认
Jenkins Location 配置为Jenkins路径
系统管理员邮箱地址为发送的邮箱地址
Extended E-mail Notification
Smtp server :smtp.qq.com
选择:Use SMTP Authentication
选择:Use SSL
Charset :UTF-8
Default Content Type :Plain Text(text/plain)
邮件通知配置
SMTP:smtp.qq.com
选择:适用SMTP认证
用户名:邮箱地址
密码:加密后的邮箱地址
选择:使用SSL协议
字符集:UTF-8
4.3、新增构建信息:
General 为配置信息:
1、输入项目名称,项目名称随便输入
2、源码管理、构建触发器、构建环境默认
3、Invoke Ant 配置 build.xml的路径
D:\JA\SeleniumUI\SeleniumUI\build.xml
Execute Windowsbatch command 配置,生成报告的处理
d:
cdD:\JA\SeleniumUI\SeleniumUI\result
"C:\ProgramFiles (x86)\WinRAR\rar" a result.zip -r
moveD:\JA\SeleniumUI\SeleniumUI\result\result.zip "C:\Program Files(x86)\Jenkins\workspace\All TestNg"
4、EditableEmail Notification 配置邮件信息
Project Recipient List接收人,可以多个多个邮箱直接用英文逗号分隔
ProjectReply-To List 抄送列表
ContentType Html(text/html)邮件格式
DefaultSubject 邮件主题
DefalutContent 邮件内容
Attachments 发送邮件内容,取C:\ProgramFiles (x86)\Jenkins\workspace\All TestNg(Jenkins安装路径)路径下 .zip的文件
Attach Build Log 配置发送构建日志,选择AttachBuild Log
Pre-send Script /Post-send Script 默认
Triggers 触发器配置
Always 所有情况都发送
Send To配置
Developers 单个人时选中
Recipient List 邮件发送多个人时选择
Jenkins 配置完成后,执行构建后会向配置的邮箱发送邮件
配置定时执行
Build periodically
日程表:
10 9,17 * * *
每天9:10 17:10 执行构建
五、实例
5.1、Selenium 充值实例:
package SeleniumUI;
import org.testng.annotations.Test;
import SeleniumUI.ChaXunShuJuKuYanZhengMa;
import org.testng.annotations.BeforeSuite;
import staticorg.testng.Assert.assertEquals;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
importorg.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterSuite;
public class HengFengChongZhi {
@BeforeSuite
public void beforeSuite() {
}
@Test
public void hengfengchongzhi() {
System.out.println("Selenium 启动...");
WebDriverdriver=new FirefoxDriver();
// driver.get("http://pc.zcb.sit.kaifa.frbao.com/login.html");//资产包主干
driver.get("https://test.validate2.frbao.com/login.html");//预发布恒丰
driver.findElement(By.xpath("//*[@id='loginForm']/div/div[1]/input")).sendKeys("frb98713333");
driver.findElement(By.xpath("//*[@id='password']")).sendKeys("a123456");
driver.findElement(By.xpath("//*[@id='loginForm']/div/input[2]")).click();
//保存当前页面句柄
Stringfrblogin=driver.getWindowHandle();
System.out.println("登录frbao。。。");
try{
Thread.sleep(2000);
}catch (InterruptedException e) {
e.printStackTrace();
}
//点击用户名
driver.findElement(By.xpath("//*[@id='globalCont']/ul[2]/li[1]/a[1]")).click();
try{
Thread.sleep(2000);
}catch (InterruptedException e1) {
e1.printStackTrace();
}
//保存当前多个句柄
Set<String>gerenzhongxin=driver.getWindowHandles();
System.out.println("关闭frbao首页...");
for(Stringgbym:gerenzhongxin){
if(gbym.equals(frblogin)){
driver.close();
}
}
System.out.println("切换至个人中心...");
for(Stringqiehuan:gerenzhongxin){
if(qiehuan.equals(frblogin)==false){
driver.switchTo().window(qiehuan);
}
}
// }
try{
Thread.sleep(2000);
}catch (InterruptedException e) {
e.printStackTrace();
}
driver.findElement(By.xpath("//*[@id='ff3']")).click();
System.out.println("跳转至充值页");
driver.findElement(By.xpath("//*[@id='payAble']")).sendKeys("0.01");
driver.findElement(By.xpath("//*[@id='container']/div[2]/div/div[2]/div/table[3]/tbody/tr[4]/td/input[2]")).click();
try{
Thread.sleep(4000);
}catch (InterruptedException e) {
e.printStackTrace();
}
Stringyzm=ChaXunShuJuKuYanZhengMa.chongzhi("15721232640");
System.out.println("最新验证码为:"+yzm);
driver.findElement(By.xpath("//*[@id='payCode']")).sendKeys(yzm);
driver.findElement(By.xpath("//*[@id='popContent']/div/div[2]/input")).click();
try{
Thread.sleep(5000);
}catch (InterruptedException e) {
e.printStackTrace();
}
Stringczjg=driver.findElement(By.xpath("//*[@id='popContent']/div/p")).getText();
assertEquals(czjg,"恭喜您,充值成功!");
if(czjg=="恭喜您,充值成功!"){
System.out.println("操作成功");
}else{
System.out.println(czjg);
}
driver.quit();
}
@AfterSuite
public void afterSuite() {
}
}
5.2、Httpclient Post实例
package SeleniumUI;
import staticorg.testng.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
importorg.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
importorg.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class ChongzhiTestngFirst {
/**
* 验证银行卡信息与充值账号,获取短信验证码
* */
@BeforeSuite
publicvoid beforeSuite() {
}
// @Test(expectedExceptions =TestException.class)
@Test
publicvoid jiekouchongzhixinxiyanzhengfirst() throws Exception {
HttpClientclient=HttpClients.createDefault();
StringrespContent =null;
HttpPostpost=new HttpPost("http://192.168.0.167:9302/frbao-ei-fund/b2c/recharge.do");
// HttpPost post=null;
try{
// post = newHttpPost(canshu.getValue("url"));
post.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101Firefox/46.0");
JsonObject object=newJsonObject();
object.addProperty("eAccNo","EA1000655585");//虚账户
object.addProperty("soleId","84696790B6FB685C0EC0CAD9492CB6EE");//虚账户标识
object.addProperty("payAccNo","6217001210061200885");//银行卡
object.addProperty("payAccName","袁秀娟");
// object.addProperty("mobileCode",ChaXunShuJuKuYanZhengMa.chongzhi("15721232640"));//短信验证码
HashMap<String,Object> hashMap=chongzhiYanZhengMa.chongzhiYanZhengMa();
Stringxlh=(String) hashMap.get("validateSeq");
Stringyzm=(String)hashMap.get("validCode");
System.out.println(xlh);
System.out.println(yzm);
object.addProperty("mobileCode",yzm);//短信验证码
object.addProperty("validateSeq",xlh);//验证序列
object.addProperty("txnAmt","0.01");
object.addProperty("rechargeType","02");
// object.addProperty("channelSerialNumber",canshu.getValue("chongzhiliushui"));//充值流水每次需要更新,参数文件获取
object.addProperty("channelSerialNumber",SuiJiShu.getRandom());//充值流水每次需要更新 ,自动生成随机数
StringEntityentity=new StringEntity(object.toString(),"UTF-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
post.setEntity(entity);
HttpResponseresponse=client.execute(post);
System.out.println("<接口返回status>"+response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode()==200){
HttpEntityhe=response.getEntity();
respContent=EntityUtils.toString(he,"UTF-8");
System.out.println("<接口返回信息:>"+respContent);
JsonParserparser=new JsonParser();
JsonObjectobjecta=(JsonObject) parser.parse(respContent);
Stringstatusa= objecta.get("responseCode").getAsString();
assertEquals(statusa,"000000");
if(statusa.equals("000000")){
System.out.println("<返回status:>"+statusa);
System.out.println("<接口返回信息:>"+respContent);
}else{
System.out.println("<接口返回status:>"+statusa);
System.out.println("<接口返回信息:>"+respContent);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterSuite
publicvoid afterSuite() {
}
}
注:
Build.xml 为配置文件
Testng.xml 为配置文件
Test-output 为testng生成的报告路径
Result 为ant运行完后后生成的报告路径
Lib 为依赖jar包
Src为java文件
Bin为编译后的class文件
报告优化:
2、复制testng-results.xsl(testng-xslt-1.1\src\main\resources)文件到test-output目录下
3、复制saxon-8.7.jar(testng-xslt-1.1\lib)文件到project的lib目录下(没有的话,自己新建)
5、配置好环境变量PATH(ant 配置在jmeter中已配置)
7、在cmd里,切换到project的目录,执行anttransform:
8、配置好后,先TestNG执行一次,生成testng-results.xml ,然后ANT执行时调用 testng-results.xml 文件里的配置的数据执行;(可以同时执行多条)
需要导入的jar包
Selenium 依赖:
selenium-java-2.52.0.jar
selenium-java-2.52.0-srcs.jar
selenium-server-standalone-2.52.0.jar
Httpclient 依赖:
httpclient-4.5.3.jar
httpclient-cache-4.5.3.jar
httpclient-win-4.5.3.jar
httpcore-4.4.6.jar
httpmime-4.5.3.jar
java-client-2.2.1-SNAPSHOT.jar
获取数据库验证码:
ojdbc14.jar
获取Linux验证码:
automation-3.2.jar
Json数据格式依赖:
gson-2.2.4.jar