用java构建企业级自动化框架(前序篇)
这个是我后来写的一本书,http://www.ituring.com.cn/minibook/10775。这个是我后来找到的自动化完美解决方案。
谈到企业级自动化测试,大家肯定会想到QTP,Ration Robot等自动化测试软件,这些软件无论在成熟度还是在用户认可度上都比较高,但它们都有致命的缺点,1,都需要钱去买且价格不菲。2,并不是专门针对本企业产品所设计,所以会出现测试功能点不能完全涵盖的缺陷。也正是是这些缺点限制了它们你能大范围的使用。
那如何能让自己企业的软件能应用上自动化测试且不受上述缺点的限制呢?一个答案,构建属于自己的企业自动化测试框架。
那我们接下来谈下自动化测试要测试什么, 我以一个购物网站京东商城为例: 比如京东商城是每隔2个月发布一个新版本,那么在新版本即将上线的时候,就要把新版本的所有功能和所有流程手工执行一遍,以确保新版本在发布的时候没有BUG。手工测试的时候最主要测试的三点是什么呢?1,手工点击页面去完成某个流程,如购物,退款等。2,连接上数据库检测下相应的数据库表有没有被正确修改。3,检测下购物网站所特有的业务,比如消息的发送(如购物网站的订单信息发送到客户关系网站让业务人员能完成退单和换地址等功能)。
闲话少说:首先我们来用一段代码来告诉下什么叫自动化。
建一个java工程,百度谷歌下这两个Jar包加入到你的工程中(selenium-java-client-driver.jar,selenium-server.jar),如图所示:
建一个java类:
import org.openqa.selenium.server.RemoteControlConfiguration;
import org.openqa.selenium.server.SeleniumServer;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
public class TestJingDong {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 建立并启动Selenium Server
SeleniumServer server;
Selenium selenium;
RemoteControlConfiguration cfg = new RemoteControlConfiguration();
try {
server = new SeleniumServer(cfg);
server.boot();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 启动Selenium
selenium = new DefaultSelenium("localhost", 4444, "*iexplore",
"http://www.360buy.com/");
selenium.start();
selenium.windowMaximize();
// Selenium 设定页面响应时间最大值
selenium.setTimeout("600000");
// 打开执行页面
selenium.open("http://www.360buy.com/product/286048.html");
//等待20秒等待页面加载
Thread.sleep(20000);
selenium.click("xpath=id('InitCartUrl')");
Thread.sleep(20000);
selenium.click("xpath=id('GotoShoppingCart')");
Thread.sleep(20000);
selenium.click("xpath=id('gotoOrderInfo')");
Thread.sleep(5000);
selenium.type("xpath=id('loginname')", "testjingdongcom");
selenium.type("xpath=id('loginpwd')", "jingdong");
selenium.click("xpath=id('loginsubmitframe')");
Thread.sleep(10000);
selenium.type("xpath=id('consignee_addressName')", "张俊卿");
selenium.select("xpath=id('consignee_province')", "index=2");
Thread.sleep(5000);
selenium.select("xpath=id('consignee_city')", "普陀区*");
Thread.sleep(10000);
selenium.select("xpath=id('consignee_county')", "桃浦新村*");
selenium.type("xpath=id('consignee_address')", "上海西站");
selenium.type("xpath=id('consignee_message')", "13999999999");
selenium
.click("xpath=id('part_consignee')//div[@class='footer']/input");
Thread.sleep(5000);
selenium.check("xpath=id('IdPaymentType1')");
String s = selenium
.getText("xpath=id('part_cart')//div[@class='middle']//tr[@class='align_Center']/td[1]");
System.out.println(s);
}
}
我们能看到,当你执行这个类的时候,这个程序会代替你手工执行页面去京东订购一件商品。
下面是它执行的时候所产生的日志文件。
17:52:46.350 INFO - Preparing Firefox profile...
17:52:50.037 INFO - Launching Firefox...
17:52:56.085 INFO - Got result: OK,f5af93f896a24a5f893c9b1d6b576129 on session f5af93f896a24a5f893c9b1d6b576129
17:52:56.085 INFO - Command request: windowMaximize[, ] on session f5af93f896a24a5f893c9b1d6b576129
17:52:56.100 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:52:56.100 INFO - Command request: setTimeout[600000, ] on session f5af93f896a24a5f893c9b1d6b576129
17:52:56.116 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:52:56.116 INFO - Command request: open[http://www.360buy.com/product/286048.html, ] on session f5af93f896a24a5f893c9b1d6b576129
17:53:17.320 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:53:37.321 INFO - Command request: click[xpath=id('InitCartUrl'), ] on session f5af93f896a24a5f893c9b1d6b576129
17:53:37.352 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:53:57.353 INFO - Command request: click[xpath=id('GotoShoppingCart'), ] on session f5af93f896a24a5f893c9b1d6b576129
17:53:57.368 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:17.367 INFO - Command request: click[xpath=id('gotoOrderInfo'), ] on session f5af93f896a24a5f893c9b1d6b576129
17:54:17.383 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.383 INFO - Command request: type[xpath=id('loginname'), xhyspring] on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.414 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.414 INFO - Command request: type[xpath=id('loginpwd'), 19830210] on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.445 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.445 INFO - Command request: click[xpath=id('loginsubmitframe'), ] on session f5af93f896a24a5f893c9b1d6b576129
17:54:22.461 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:32.476 INFO - Command request: type[xpath=id('consignee_addressName'), 张俊卿] on session f5af93f896a24a5f893c9b1d6b576129
17:54:33.492 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:33.492 INFO - Command request: select[xpath=id('consignee_province'), index=2] on session f5af93f896a24a5f893c9b1d6b576129
17:54:33.507 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:38.507 INFO - Command request: select[xpath=id('consignee_city'), 普陀区*] on session f5af93f896a24a5f893c9b1d6b576129
17:54:38.523 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:48.616 INFO - Command request: select[xpath=id('consignee_county'), 桃浦新村*] on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.553 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.553 INFO - Command request: type[xpath=id('consignee_address'), 上海西站] on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.569 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.569 INFO - Command request: type[xpath=id('consignee_message'), 13999999999] on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.585 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.585 INFO - Command request: click[xpath=id('part_consignee')//div[@class='footer']/input, ] on session f5af93f896a24a5f893c9b1d6b576129
17:54:49.600 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:54.600 INFO - Command request: check[xpath=id('IdPaymentType1'), ] on session f5af93f896a24a5f893c9b1d6b576129
17:54:54.647 INFO - Got result: OK on session f5af93f896a24a5f893c9b1d6b576129
17:54:54.647 INFO - Command request: getText[xpath=id('part_cart')//div[@class='middle']//tr[@class='align_Center']/td[1], ] on session f5af93f896a24a5f893c9b1d6b576129
17:54:54.663 INFO - Got result: OK,286048 on session f5af93f896a24a5f893c9b1d6b576129
286048
呵呵,运行完上面程序,大概你对自动化有个初步的印象,别急,我们对上面这个程序在做修改。
首先把这个脚本类做成以testUite4方式运行的类,有些数据比较经常变动的就不要放在这个类里面,可以放在外部properties文件里。
创建一个properties文件放在Src目录下,命名为resource,内容如下:
PRODUCTID=286048
NAME= testjingdongcom
PASSWORD=jingdong
public class TestJingDongTest1 {
SeleniumServer server;
Selenium selenium;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
RemoteControlConfiguration cfg = new RemoteControlConfiguration();
try {
server = new SeleniumServer(cfg);
server.boot();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 启动Selenium
selenium = new DefaultSelenium("localhost", 4444, "*firefox D:\\Program Files\\Mozilla Firefox\\firefox.exe",
"http://www.360buy.com/");
selenium.start();
selenium.windowMaximize();
// Selenium 设定页面响应时间最大值
selenium.setTimeout("600000");
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
selenium.close();
server.stop();
}
/**
* Test method for {@link TestJingDongTest#execute()}.
* @throws InterruptedException
*/
@Test
public void testExecute() throws InterruptedException {
private static String PROPERTIES_FILE = "resource";
private static String PRODUCTID;
private static String NAME;
private static String PASSWORD;
ResourceBundle rb = ResourceBundle.getBundle(PROPERTIES_FILE);
PRODUCTID = rb.getString("PRODUCTID");
NAME = rb.getString("NAME");
PASSWORD = rb.getString("PASSOWRD");
selenium.open("http://www.360buy.com/product/"+PRODUCTID+".html");
//等待20秒等待页面加载
Thread.sleep(20000);
selenium.click("xpath=id('InitCartUrl')");
Thread.sleep(20000);
selenium.click("xpath=id('GotoShoppingCart')");
Thread.sleep(20000);
selenium.click("xpath=id('gotoOrderInfo')");
Thread.sleep(5000);
selenium.type("xpath=id('loginname')", NAME);
selenium.type("xpath=id('loginpwd')", PASSWORD);
selenium.click("xpath=id('loginsubmitframe')");
Thread.sleep(10000);
selenium.type("xpath=id('consignee_addressName')", "张俊卿");
selenium.select("xpath=id('consignee_province')", "index=2");
Thread.sleep(5000);
selenium.select("xpath=id('consignee_city')", "普陀区*");
Thread.sleep(10000);
selenium.select("xpath=id('consignee_county')", "桃浦新村*");
selenium.type("xpath=id('consignee_address')", "上海西站");
selenium.type("xpath=id('consignee_message')", "13999999999");
selenium
.click("xpath=id('part_consignee')//div[@class='footer']/input");
Thread.sleep(5000);
selenium.check("xpath=id('IdPaymentType1')");
String s = selenium
.getText("xpath=id('part_cart')//div[@class='middle']//tr[@class='align_Center']/td[1]");
System.out.println(s);
if(Integer.valueOf(s)>0){
System.out.println(" 你所订购的商品已经产生,商品号是 :"+s);
getQuery("select * from product where product id ="+s);
Date date=new Date();
SentMessageToCustomerService(s+date.toString());
}
}
public void getQuery(String sql) {
try {
Connection conn = getConnection();
if (conn != null) {
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(sql);
int c = rs.getMetaData().getColumnCount();
while (rs.next()) {
System.out.println("你所要的商品在数据库中已保存");
for (int i = 1; i <= c; i++) {
System.out.print(rs.getObject(i));
}
}
rs.close();
}
freeConnection(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void SentMessageToCustomerService(String xml) {
//add you JMS function
}
}
呵呵,这个测试的脚本是不是已经能符合网站的基本测试需求了,当你运行一下这个脚本的时候,以前需要手工测试人员手工去做的工作自动化脚本就能自行替你完成了。
当写的这种自动化的脚本多的时候,可以采用suit的方法去执行它们,当运行suit文件的时候,suit里所有指定的脚本类都能被依次执行
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(value=org.junit.runners.Suite.class)
@SuiteClasses({
TestJingDongTest1.class
TestJingDongTest2.class
TestJingDongTest3.class
TestJingDongTest4.class
TestJingDongTest5.class
TestJingDongTest6.class
TestJingDongTest7.class
TestJingDongTest8.class
TestJingDongTest9.class
TestJingDongTest10.class
})
public class TestSuit {
}
一个简单的小自动化框架就成型了,当然,这种小框架的能力成熟度达不到检验企业大型网站的成熟度的,那么企业级自动化框架需要的是哪些东西呢。
1,脚本语言的管理,在很多企业自动化脚本都是测试人员来写,所以决定脚本语言不可能让java写,只是让他们按照你制定的语言来写,然后你的框架能把语言翻译成java类来执行。
2,测试结果既日志的显示,日志要考虑展示的方式,因为这就是测试报告,日志展示要清晰明了。
3,测试脚本的组织和管理,比如一个大型购物网站,它有几千多个case这些测试脚本怎么管理,每次运行时要运行哪些。
4.大量测试数据运行时多线程分布式处理。
在下面的章节中,我们会一步步的展示这些怎么实现的。
用java构建企业级自动化框架(前序篇)相关推荐
- 用java构建企业级自动化框架(首篇-制定测试者使用语言1)
这个是我后来写的一本书,http://www.ituring.com.cn/minibook/10775.这个是我后来找到的自动化完美解决方案. 首先我们谈论下Automation语言组织管理,因为一 ...
- Java接口自动化框架系列07:Web接口自动化测试框架设计思路
1.Java web接口自动化框架 框架名称:Java+Maven+httpClients+TestNg+Allure (因本次只讲解java部分,未包括git和jenkins,如果是包括git和je ...
- 「构建企业级推荐系统系列」推荐系统的未来发展
作者 | gongyouliu 编辑 | auroral-L 全文共11510字,预计阅读时间60分钟 目录 一.政策及技术发展对推荐系统的影响 1.政治层面 2.科技层面 二.推荐系统的就业 1.推 ...
- Java安全(十三) SSM-Spring框架
概述 Spring 是目前主流的 Java Web 开发框架,是一个轻量级的开源框架,具有很高的凝聚力和吸引力. Spring 框架不局限于服务器端的开发.从简单性.可测试性和松耦合的角度而言,任何 ...
- CI/CD——构建企业级Docker+Jenkins+Git+Harbor流水线自动化持续集成持续发布平台
构建企业级Docker+Jenkins+Git+Harbor流水线自动化持续集成持续发布平台 CI/CD是什么? 持续集成(CI)/持续交付(CD)的优势 自动化部署流程图 Git Github Gi ...
- 基于K8S构建企业级Jenkins CI/CD平台实战(三) 之 带你实战Spring boot/Cloud 项目 CI/CD jenkins自动化构建、部署过程
需要环境 Git(GitLab) Harbor 私服 kubernetes-plugin 使用 Kubernetes jenkins 通过前面三篇我们已经了解了jenkins和 kubernetes- ...
- java接口自动化(三) - 手工接口测试到自动化框架设计之鸟枪换炮
1.简介 上一篇宏哥介绍完了接口用例设计,那么这一章节,宏哥就趁热打铁介绍一下,接口测试工具.然后小伙伴们或者童鞋们就可以用接口测试工具按照设计好的测试用例开始执行用例进行接口手动测试了.关于手动测试 ...
- java接口自动化监控_java接口自动化(三) - 手工接口测试到自动化框架设计之鸟枪换炮...
1.简介 上一篇宏哥介绍完了接口用例设计,那么这一章节,宏哥就趁热打铁介绍一下,接口测试工具.然后小伙伴们或者童鞋们就可以用接口测试工具按照设计好的测试用例开始执行用例进行接口手动测试了.关于手动测试 ...
- Java+Rest-Assrued+Gradle+Allure搭建接口测试自动化框架
背景 上一篇<4个步骤,搭建接口测试自动化框架>我分享了如何搭建接口测试自动化框架的理论部分,今天我们就利用Java+Rest-Assrued+Gradle+Allure来搭建一个完整的接 ...
最新文章
- 西湖大学鞠峰组招聘微生物组学、病毒组学与生物信息学博士后
- Java Web学习总结(22)——使用kaptcha生成验证码
- 22.网络提速(最短路)
- python中的__str__ __name__ 和__call__方法
- 【B站视频教程笔记】基于VSCode和CMake实现C/C++开发 | Linux篇(gcc/g++)(安装、配置、使用详细教程)(VSCode教程)(CMake教程)(精!)
- 创作一个数字人,总共分几步?(上)
- 不放弃WM,依旧开发WM应用
- 洪水同频率放大的方法_我们应该怎么选择放大器配件?
- 帮别人改的代码 我也不知道他爬的什么 记录下
- linux dhcp 绑定mac地址,●DHCP协议的功能是 (58) 。在Linux中提供DHCP服务的程序是 (59) ;DHCP服务将主机的MAC地址和IP地 - 赏学吧...
- ios保存录制好的视频 图片 到相簿
- 程序员做脚底鱼疗,因脚臭熏死一大批鱼,老板据说是这表情
- (83)--用代码实现超越函数
- Attention!当推荐系统遇见注意力机制
- 添加多浏览器支持是什么意思_低gi什么意思,减肥期间一定要多吃低gi的食物吗?- 理财技巧...
- 23种设计模式之单例模式、工厂模式、原型模式、建造者模式
- Web安全之文件上传漏洞
- 实验课第四次随堂测试
- 0602 翻转xy轴
- DELL服务器R230旧磁盘换新磁盘,新磁盘复制旧磁盘所以数据
热门文章
- Moonlight Shadow
- Mac:使用大写锁定键切换输入法
- DATAX 数据迁移 oracle-oracle
- 与黄牛、号贩子斗争的思考
- SQLServer 计算两个日期间的工作日(排除周六和周日,不排除节假日)
- Vue-cli中报错:Module not found: Error: Can‘t resolve ‘vue-router ‘
- Docker 三剑客之 Swarm
- 迷人的神经网络——机器学习笔记1
- 爱旅行项目-环境搭建
- 基于LPWAN技术的低成本 IoT 物联网企业资产管理解决方案