记录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中的全部数据逐条进行返回最后来运行。

 

posted on 2019-10-23 10:45  叮咚丶哈哈  阅读(381)  评论(0编辑  收藏  举报

导航