记录java+testng运行selenium(四)--- 运行代码
涉及的文件有:
.\medical\BusinessFile.java :实例化excel及xml文件操作对象以及将list变成Map
.\medical\manual\business\LoginBusiness.java :通过放射获取元素路径及用例动作的执行(每个对应的test都应该有之相对应的business)
.\medical\manual\handles\LoginElement.java :元素对象路径定义类,后期元素对象的路径发生改变之后只需要修改相应的值即可。
及读取excel读取的数据返回到用例执行类中(excel读取可以放在LoginBusiness文件中)
.\medical\manual\user\TestUserLogin.java : test用例类
.\medical\manual\user\TestUserLogin.xml: test中定义的excel文件所在路径
一: 编写excel所在目录及sheet名
创建TestUserLogin.xml并编写以下内容
<?xml version="1.0" encoding="UTF-8"?>
<data>
<loginTest>
<load>.\drivers\测试用例.xlsx</load>
<sheetName>登录</sheetName>
</loginTest>
</data>
二:编写test执行类
创建TestUserLogin.java并编写以下代码
import java.util.Map; import org.testng.annotations.*; import medical.manual.business.LoginBusiness;
import medical.manual.handles.LoginElement; public class TestUserLogin { private LoginBusiness lb; @BeforeMethod
public void runDriveBrowser() {
String filename = "hospital.ini";
this.lb = new LoginBusiness(filename);
} @AfterMethod
public void closeDrive() {
lb.browser.closeBrowser(1000);
} /**
* dataProvider可以是定义的name名字也可以是函数名
* @param param 单行excel数据
*/
@Test(description = "用户的登录", dataProvider = "getLoginData", dataProviderClass = LoginElement.class)
public void loginTest(Map<?, ?> param) {
lb.medicalRecords(param);
} }
函数说明:
runDriveBrowser :每条用例执行时都重新创建浏览器对象,并把浏览器所在的ini文件当做参数传入到用例操作类中
closeDrive :用于关闭浏览器的操作,传入延迟时间主要用于延迟关闭操作
loginTest : 通过数据驱动的形式,只需要定义一个函数然后就可以执行同一个sheet下的用例(前提是用例结果相同)。
三:元素实现类
创建BusinessFile.java 并编写以下内容
package medical; import org.testng.Assert;
import toolskit.documents.ReadExcel;
import toolskit.documents.XmlUtil; import java.util.ArrayList;
import java.util.List;
import java.util.Map; /**
* @ ClassName: medical
* @ Author: DingDong
* @ Date: 2019/10/21 16:25
* @ Version: 1.0
* @ desc:
*/
public class BusinessFile { public Object[][] dataProviderSource(String load,String sheetName){ ReadExcel re = new ReadExcel(); List<Map<String, String>> maps = re.readExcel(load, sheetName); Object[][] testData = mapsToArray(maps);
return testData;
} public List<Map<String, String>> getXmlData(String methodName,String xmlPath){
List parList; List<Map<String, String>> sonList=new ArrayList<>(); // 读取xml内容
parList = XmlUtil.getXmlComent(xmlPath); // 根据名字进行区分
for (int i=0;i< parList.size();i++) {
Map map = (Map)parList.get(i);
if (map.containsKey(methodName)) {
Map<String,String> subMap = (Map<String,String>) map.get(methodName);
sonList.add(subMap);
}
} if (sonList.size() > 0) {
return sonList;
}else{
Assert.assertTrue(sonList.size()!=0,parList+"为空,找不到属性值:"+methodName );
return null;
}
} public Object[][] mapsToArray(List<Map<String, String>> maps) {
int singleListSize = maps.size(); // 创建一个二维数组
Object[][] testData = new Object[singleListSize][]; for (int singleSize = 0; singleSize < singleListSize; singleSize++) { Map<String, String> singleMap = maps.get(singleSize);
testData[singleSize] = new Object[]{singleMap}; } // 返回数据传给脚本
return testData; }
}
函数说明:
dataProviderSource:根据用例位置及sheet名字来读取excel中的内容
getXmlData : 根据现在运行的test名及xml所在位置来读取excel所在位置及sheet名字
mapsToArray : 将 map 转换 成 Array
创建LoginElement.java 并编写以下内容:
package medical.manual.handles; import java.lang.reflect.Method; import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.testng.annotations.DataProvider; import medical.BusinessFile; public class LoginElement extends BusinessFile { // 用于存储元素路径及元素类型
private Map<String, String> loginElement; private void setPathAndType(String elePath, String pathType) {
loginElement = new HashMap<>();
loginElement.put("elePath", elePath);
loginElement.put("pathType", pathType);
} public Map<String, String> getLoginTitle() {
setPathAndType("h3.title", "css");
return loginElement;
} public Map<String, String> getLoginUser() {
setPathAndType("username", "name");
return loginElement;
} public Map getLoginUserError() {
setPathAndType("form > div:nth-child(2) > div > div.el-form-item__error", "css");
return loginElement;
} public String getUserErrorMsg() {
// 账号输入框错误提示语
return "请填写账号";
} public Map getLoginPass() {
setPathAndType("password", "name"); return loginElement;
} public Map getLoginPassError() {
setPathAndType("div.el-form-item.el-tooltip.is-error.is-required > div > div.el-form-item__error", "css");
return loginElement;
} public String getPassErrorMsg() {
// 密码输入框错误提示语
return "请填写密码";
} public Map getLoginButton() {
setPathAndType("form > button:nth-child(4)", "css");
return loginElement;
} public Map getLoginRegister() {
setPathAndType("form > button:nth-child(5)", "css");
return loginElement;
} private Map getLoginError() {
setPathAndType("body > div.el-message.el-message--error", "css");
return loginElement;
} public Method getLoginPageElement(String methodName) {
Method getPassErrorMsg = null;
try {
// 根据方法名获得指定的方法, 参数name为方法名,参数parameterTypes为方法的参数类型 getPassErrorMsg = LoginElement.class.getDeclaredMethod(methodName);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return getPassErrorMsg;
} @DataProvider
public Object[][] getLoginData(Method method) { String xmlpth = ".\\src\\main\\java\\medical\\manual\\user\\TestUserLogin.xml";
List<Map<String, String>> xmlData = getXmlData(method.getName(),xmlpth);
String load = xmlData.get(0).get("load");
String sheetName =xmlData.get(0).get("sheetName"); Object[][] testData = dataProviderSource(load,sheetName); return testData; } }
函数说明:
get***并且返回Map类型的函数 : 定义元素路径及路径类型(有css、id、name 、xpath等)
getLoginPageElement : 放射机制获取元素路径
getLoginData : 数据驱动DataProvider中数据来源的准备
四: 用例操作类
创建LoginBusiness.java并编写如下内容
package medical.manual.business; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert; import toolskit.InformationLog;
import toolskit.carrier.BrowserDriver;
import toolskit.carrier.DriverFactory;
import toolskit.exhibition.ExecuteFramework;
import toolskit.exhibition.InterfaceShow;
import toolskit.incomprehension.AbnormalCodeError;
import toolskit.incomprehension.ResourceNotFoundException;
import medical.manual.handles.LoginElement; import static toolskit.documents.ReadIni.readIni; public class LoginBusiness { public BrowserDriver browser;
private InterfaceShow execute;
private LoginElement loginElement;
private WebDriver driver; public LoginBusiness(String filename) { Map<String, Object> url_ini = readIni(filename,"");
String driverType =((Map<String, String>) url_ini.get("dz_login")).get("driver");
String webUrl = ((Map<String, String>) url_ini.get("dz_login")).get("url");
this.browser = DriverFactory.getDriverBrowser(driverType,webUrl);
this.driver = browser.getDriver(); this.loginElement = new LoginElement();
this.execute = new ExecuteFramework(driver);
} private String getElement(String elePath, String pathType) {
String errorText = execute.getAttributeTextValue(elePath, pathType, null, "text");
return errorText;
} private void inputUserInfo(String loginFunction, String userData) {
try {
Method getPassErrorMsg = loginElement.getLoginPageElement(loginFunction); Map loginMap = (Map) getPassErrorMsg.invoke(loginElement); String elePath = (String) loginMap.get("elePath");
String pathType = (String) loginMap.get("pathType"); InformationLog.inputLogInfo("the element: " + loginMap.get("elePath") + " input data " + loginMap.get("pathType")); WebElement username = execute.VisibleFocus(elePath, pathType);
execute.HandleVisibleInput("", "", username, userData); // 利用js代码在指定的元素上失去焦点
JavascriptExecutor driver_js = ((JavascriptExecutor) driver);
driver_js.executeScript("arguments[0].blur();", username); } catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
} } /**
* 获取输入框中出现错误的提示语
*
* @param loginFunction 提示语所在位置的指定函数
* @param loginErrorFun 提示语内容
*/
private void getUserErrorInfo(String loginFunction, String loginErrorFun) {
Method getPassErrorMsg;
Map loginMap;
String loginError;
try {
// 找到错误提示语位置
getPassErrorMsg = loginElement.getLoginPageElement(loginFunction); loginMap = (Map) getPassErrorMsg.invoke(loginElement); String elePath = (String) loginMap.get("elePath");
String pathType = (String) loginMap.get("pathType"); // 找到错误提示语
String errorText = getElement(elePath, pathType); // 获取内置提示语进行比较
getPassErrorMsg = loginElement.getLoginPageElement(loginErrorFun); loginError = (String) getPassErrorMsg.invoke(loginElement); if (errorText != null && errorText.equals(loginError)) {
InformationLog.inputLogInfo(" element error message: " + errorText);
} else {
InformationLog.inputLogInfo(" element No error message: ");
} } catch (Exception e) {
e.printStackTrace();
} } private void clickLogin() {
// 找到错误提示语位置
Method getPassErrorMsg = loginElement.getLoginPageElement("getLoginButton"); Map loginMap = null;
try {
loginMap = (Map) getPassErrorMsg.invoke(loginElement);
} catch (Exception e) {
e.printStackTrace();
} assert loginMap != null;
String elePath = (String) loginMap.get("elePath");
String pathType = (String) loginMap.get("pathType"); WebElement userError = execute.VisibleFocus(elePath, pathType);
if (userError != null) {
userError.click();
} else {
Assert.assertThrows(NullPointerException.class,
() -> {
throw new AbnormalCodeError("excel中出现不符合要求的资源:");
}); //failed
} } public void medicalRecords(Map<?, ?> param) { // 输入内容
inputUserInfo("getLoginUser", (String) param.get("username"));
inputUserInfo("getLoginPass", (String) param.get("password")); // 点击登录按钮
clickLogin(); // 判断错误是否出现
String errorType = (String) param.get("type");
if ("info".equals(errorType)) {
getUserErrorInfo("getLoginUserError", "getUserErrorMsg");
getUserErrorInfo("getLoginPassError", "getPassErrorMsg");
} else if ("page".equals(errorType)) {
WebElement userError = new WebDriverWait(driver, 5)
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.el-message.el-message--error"))); String errorText = userError.getText();
InformationLog.inputLogInfo("page pupop error info: " + errorText);
} else {
//failed
Assert.assertThrows(NullPointerException.class, () -> {
throw new ResourceNotFoundException();
});
}
}
}
函数说明:
实例化LoginBusiness时需要传入ini所在位置,实例化时就创建浏览器对象、元素存储对象、元素操作对象
getElement : 元素text文字获取函数,这里统一调用也可以不进行创建。
inputUserInfo : 内容输入函数,其中loginFunction为LoginElement文件中对应的get***函数名,userData为需要输入的内容该内容需要从excel中读取
getUserErrorInfo : 内容输入错误时,提示语的获取,loginFunction为LoginElement文件中对应的get***函数名,loginErrorFun为出现的提示语,提示语也是从excel中读取
clickLogin : 执行元素点击操作
medicalRecords : 将上诉的函数结合在一起,整合成整个流程。流程为:账号密码号密码输入-->提示元素校验-->执行点击操作。
说明:
整体思路是:TestUserLogin 中test运行前实例化LoginBusiness,并由此打开浏览器及进入相应的url。
在运行test时由LoginElement中name为getLoginData的dataProvider来准备数据(准备过程中主要是通过xml读取用例位置)
最后将excel中的全部数据逐条进行返回最后来运行。
记录java+testng运行selenium(四)--- 运行代码的更多相关文章
- selenium从入门到应用 - 1,环境准备(Java+TestNG+Maven+Selenium)
本系列所有代码 https://github.com/zhangting85/simpleWebtest 本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境的 ...
- 记录java+testng运行selenium(二)---定义元素类及浏览器
一: 元素类 整体思路: 1. 根据状态可分可见和不可见两种 2. 同一个路径可以查找单个元素或多个元素 3. 获取元素text或者指定的value值 4. selenium对元素操作有两种,一是通过 ...
- 记录java+testng运行selenium(四)--- 结构说明
一图:主要是driver文件所在目录,及ini配置文件所在位置. 这两个文件一般我是放在其它目录下,不跟随项目所在目录 二图:用例操作类及用例执行类所在位置. 下图中有接口代码及功能代码组成,之前的文 ...
- 记录java+testng运行selenium(一)
整体的流程为下图 整体思路为: 1. 由程序开始运行时去读取ini文件中存储的浏览器及需要打开的url 2. test运行时通过description实现数据驱动,主要做两件事 2.1 第一件事为:读 ...
- 记录java+testng运行selenium(三)---xml、ini、excel、日志等配置
一: ini文件 ini目前只用处存储浏览类型及需要打开的url,ini文件放在configs文件夹下面. 读取ini代码如下: package toolskit.documents; import ...
- java testng框架的windows自动化-自动运行testng程序上篇
本文旨在让读者简单了解testng的自动运行 怎么说呢,在网上已经有了各个前辈进行代码演示以及分享,我力争说到点子上 接上文,之前讲的大部分是juint的自动化代码运行,从未涉及到testng,但是在 ...
- TestNG实现用例运行失败自动截图(转载)
转载自:https://blog.csdn.net/galen2016/article/details/70193684 重写Listener的onTestFailure方法 package com. ...
- Java程序在内存中运行详解
目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...
- java的windows自动化-自动运行java程序
那么在一些工具齐全并且已经有了一定的写好的java程序的情况下(环境变量和软件见上一章http://www.cnblogs.com/xuezhezlr/p/7718273.html),如何自动化运行j ...
随机推荐
- Game and Application Protocol
This privacy policy details the information collected by the team ("we" or "our" ...
- 报错:WARN [WorkerSender[myid=1]:QuorumCnxManager@584] - Cannot open channel to 2 at election address /x.x.x.x:3888
报错背景: zookeeper安装完成之后,启动之后正常,但是查看log文件zookeeper.log时发现报错. 报错现象: -- ::, [myid:] - INFO [WorkerSender[ ...
- Django 引用{% url "name"%} 避免链接硬编码
前提条件:为每个url指定name且name值要唯一.比如: 项目中的url.py文件: urlpatterns = patterns('', url(r'^$',TemplateView.as_vi ...
- php程序无法记录log情况下可尝试下面方法记录log
error_reporting(E_ERROR | E_PARSE); function shutdownCallback(){ $arrError = error_get_last(); // ...
- 【Leetcode_easy】929. Unique Email Addresses
problem 929. Unique Email Addresses solution: class Solution { public: int numUniqueEmails(vector< ...
- puppeteer-firefox 开启扩展
puppeteer-firefox安装扩展 puppeteer-firefox 目前已经有许多人在投入开发工作,但是和chrome的launch打开扩展api不一致,在chrome中,我们可以很容易配 ...
- 【ARM-LInux开发】利用scp 远程上传下载文件/文件夹
利用scp 远程上传下载文件/文件夹 scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o s ...
- idea的maven依赖本地jar
可以手动添加jar,但是idea手动添加jar时,有时候不行. 用maven依赖本地jar方法,感觉比较正规,不会因为自己忘记手动添加jar. 比如这个达梦数据库依赖 <dependency&g ...
- 使用Nethunter(Kali黑客手机)wifite破解无线密码
简介: NetHunter是一个基于Kali Linux为Nexus设备构建的Android渗透测试平台,其中包括一些特殊和独特的功能. NetHunter支持无线802.11注入,一键MANA AP ...
- lnmp+tp5安装纪要
1: lnmp : https://lnmp.org/install.html 官网安装帮助 运行命令:wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz ...