• 测试框架——luckyframeclient之Jenkins部署


    背景

    client端执行webUI自动化测试时依赖操作系统上安装了对应的浏览器,并且浏览器与驱动要进行版本的对应——而selenium是可以部署集群,通过远程的方式执行对应的自动化用例,方便高效。

    原理

    1、通过代码可知,自动化运行的主类接收了任务id,获取到任务信息后根据任务类型判断进行接口测试  或  UI测试

    public class RunAutomationTest extends TestControl {
        public static void main(String[] args) {
            try {
                PropertyConfigurator.configure(RunService.APPLICATION_HOME + File.separator + "log4j.conf");
                String taskid = args[0];
                TaskExecute task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
                TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(Integer.parseInt(taskid));
                if (taskScheduling.getTaskType() == 0) {
                    // 接口测试
                    TestControl.taskExecutionPlan(task);
                } else if (taskScheduling.getTaskType() == 1) {
                    // UI测试
                    WebTestControl.taskExecutionPlan(task);
                } else if (taskScheduling.getTaskType() == 2) {
                    AppTestControl.taskExecutionPlan(task);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                LogUtil.APP.error("启动测试任务运行主函数出现异常,请检查!",e);
            } finally{
                System.exit(0);
            }
        }
    }

    2、通过wd = WebDriverInitialization.setWebDriverForTask(drivertype)  这行代码可知,根据浏览器的类型获取了驱动。UI自动化浏览器类型 0 IE 1 火狐 2 谷歌 3 Edge 4 集群,其中4 集群是我自己添加的,用来标识远程集群。

        public static void taskExecutionPlan(TaskExecute task) {
            // 记录日志到数据库
            serverOperation.exetype = 0;
            String taskid = task.getTaskId().toString();
            TestControl.TASKID = taskid;
            String restartstatus = RestartServerInitialization.restartServerRun(taskid);
            BuildResult buildResult = BuildingInitialization.buildingRun(taskid);
            List<ProjectCaseParams> pcplist = GetServerApi.cgetParamsByProjectid(task.getProjectId().toString());
            TaskScheduling taskScheduling = GetServerApi.cGetTaskSchedulingByTaskId(task.getTaskId());
            String projectname = taskScheduling.getProject().getProjectName();
            task = GetServerApi.cgetTaskbyid(Integer.parseInt(taskid));
            String jobname = taskScheduling.getSchedulingName();
            int drivertype = serverOperation.querydrivertype(taskid);
            int[] tastcount;
            // 判断是否要自动重启TOMCAT
            if (restartstatus.contains("Status:true")) {
                // 判断是否构建是否成功
                if (BuildResult.SUCCESS.equals(buildResult)) {
                    WebDriver wd = null;
                    try {
                        wd = WebDriverInitialization.setWebDriverForTask(drivertype);
                    } catch (WebDriverException e1) {
                        LogUtil.APP.error("初始化WebDriver出错 WebDriverException!", e1);
                    } catch (IOException e2) {
                        LogUtil.APP.error("初始化WebDriver出错 IOException!", e2);
                    }
                    serverOperation caselog = new serverOperation();
    
                    List<ProjectCase> cases = GetServerApi.getCasesbyplanId(taskScheduling.getPlanId());
                    LogUtil.APP.info("当前测试任务 {} 中共有【{}】条待测试用例...",task.getTaskName(),cases.size());
                    serverOperation.updateTaskExecuteStatusIng(taskid, cases.size());
                    int i = 0;
                    for (ProjectCase testcase : cases) {
                        i++;
                        LogUtil.APP.info("开始执行当前测试任务 {} 的第【{}】条测试用例:【{}】......",task.getTaskName(),i,testcase.getCaseSign());
                        List<ProjectCaseSteps> steps = GetServerApi.getStepsbycaseid(testcase.getCaseId());
                        if (steps.size() == 0) {
                            continue;
                        }
                        try {
                            // 插入开始执行的用例
                            caselog.insertTaskCaseExecute(taskid, taskScheduling.getProjectId(),testcase.getCaseId(),testcase.getCaseSign(), testcase.getCaseName(), 4);
                            WebCaseExecution.caseExcution(testcase, steps, taskid, wd, caselog, pcplist);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            LogUtil.APP.error("用户执行过程中抛出异常!", e);
                        }
                        LogUtil.APP.info("当前用例:【{}】执行完成......进入下一条",testcase.getCaseSign());
                    }
                    tastcount = serverOperation.updateTaskExecuteData(taskid, cases.size(),2);
    
                    String testtime = serverOperation.getTestTime(taskid);
                    LogUtil.APP.info("当前项目【{}】测试计划中的用例已经全部执行完成...",projectname);
                    MailSendInitialization.sendMailInitialization(HtmlMail.htmlSubjectFormat(jobname),
                            HtmlMail.htmlContentFormat(tastcount, taskid, buildResult.toString(), restartstatus, testtime, jobname),
                            taskid, taskScheduling, tastcount,testtime,buildResult.toString(),restartstatus);
                    // 关闭浏览器
                    assert wd != null;
                    wd.quit();
                } else {
                    LogUtil.APP.warn("项目构建失败,自动化测试自动退出!请前往JENKINS中检查项目构建情况。");
                    MailSendInitialization.sendMailInitialization(jobname, "构建项目过程中失败,自动化测试自动退出!请前去JENKINS查看构建情况!", taskid,
                            taskScheduling, null,"0小时0分0秒",buildResult.toString(),restartstatus);
                }
            } else {
                LogUtil.APP.warn("项目TOMCAT重启失败,自动化测试自动退出!请检查项目TOMCAT运行情况。");
                MailSendInitialization.sendMailInitialization(jobname, "项目TOMCAT重启失败,自动化测试自动退出!请检查项目TOMCAT运行情况!", taskid,
                        taskScheduling, null,"0小时0分0秒",buildResult.toString(),restartstatus);
            }
        }

     3、在类WebDriverInitialization的setWebDriverForTask方法中添加针对浏览器集群的驱动,代码如下,添加了else if通过配置生成浏览器驱动。

     1     public static WebDriver setWebDriverForTask(int drivertype) throws WebDriverException,IOException{
     2         // 参数为空
     3         String drivenpath= RunService.APPLICATION_HOME + File.separator+"BrowserDriven"+File.separator;
     4         WebDriver webDriver = null;
     5         LogUtil.APP.info("准备初始化WebDriver对象...检查到当前操作系统是:{}",OS);
     6         if(drivertype==0){
     7             if(OS.startsWith("win")){
     8                 System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
     9                 webDriver = new InternetExplorerDriver();
    10             }else{
    11                 LogUtil.APP.warn("当前操作系统无法进行IE浏览器的Web UI测试,请选择火狐或是谷歌浏览器!");
    12             }        
    13         }else if(drivertype==1){
    14             FirefoxOptions options = new FirefoxOptions();
    15             if(OS.startsWith("win")){
    16                 System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver.exe");
    17             }else if(OS.contains("mac")){
    18                 options.addArguments("start-maximized");
    19                 System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_mac");
    20             }else{
    21                 LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Firefox浏览器的Web UI自动化...");
    22                 //无界面参数
    23                 options.setHeadless(true);
    24                 //禁用沙盒
    25                 options.addArguments("no-sandbox");
    26                 options.addArguments("start-maximized");
    27                 System.setProperty("webdriver.gecko.driver",drivenpath+"geckodriver_linux64");
    28             }
    29             webDriver = new FirefoxDriver(options);
    30         }else if(drivertype==2){
    31             ChromeOptions options = new ChromeOptions();
    32             if(OS.startsWith("win")){
    33                 System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver.exe");
    34             }else if(OS.contains("mac")){
    35                 options.addArguments("start-maximized");
    36                 System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_mac");
    37             }else{
    38                 LogUtil.APP.info("检测到当前系统环境是Linux,默认使用headless方式运行Chrome浏览器的Web UI自动化...");
    39                 //无界面参数
    40                 options.setHeadless(true);
    41                 //禁用沙盒
    42                 options.addArguments("no-sandbox");
    43                 options.addArguments("start-maximized");
    44                 System.setProperty("webdriver.chrome.driver",drivenpath+"chromedriver_linux64");
    45             }            
    46             webDriver = new ChromeDriver(options);
    47         }else if(drivertype==3){
    48             if(OS.startsWith("win")){
    49                 System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver.exe");
    50                 webDriver = new EdgeDriver();
    51             }else if(OS.contains("mac")){
    52                 System.setProperty("webdriver.edge.driver",drivenpath+"msedgedriver_mac");
    53                 webDriver = new EdgeDriver();
    54             }else{
    55                 LogUtil.APP.warn("当前操作系统无法进行Edge浏览器的Web UI测试,请选择火狐或是谷歌浏览器!");
    56             }
    57         }else if(drivertype==4){
    58             // 返回配置好的remote
    59             Properties properties = SysConfig.getConfiguration();
    60             String hubUrl = properties.getProperty("remote.webdriver.url");
    61             String browser = properties.getProperty("remote.webdriver.browser");
    62             LogUtil.APP.info("集群执行webUI:{},节点浏览器类型为:{}....",hubUrl,browser);
    63             switch (browser){
    64                 case "chrome":
    65                     webDriver = new RemoteWebDriver(new URL(hubUrl), DesiredCapabilities.chrome());break;
    66                 case "firefox":
    67                     webDriver = new RemoteWebDriver(new URL(hubUrl), DesiredCapabilities.firefox());break;
    68                 case "safari":
    69                     webDriver = new RemoteWebDriver(new URL(hubUrl), DesiredCapabilities.safari());break;
    70                 case "edge":
    71                     webDriver = new RemoteWebDriver(new URL(hubUrl), DesiredCapabilities.edge());break;
    72                 default:
    73                     LogUtil.APP.warn("集群中浏览器配置错误,默认使用chrome浏览器...",browser);
    74                     webDriver = new RemoteWebDriver(new URL(properties.getProperty("remote.webdriver.url")), DesiredCapabilities.chrome());break;
    75             }
    76         }else{
    77             LogUtil.APP.warn("浏览器类型标识:{},获取到的浏览器类型标识未定义,默认IE浏览器进行执行....",drivertype);
    78             System.setProperty("webdriver.ie.driver",drivenpath+"IEDriverServer.exe");
    79             webDriver = new InternetExplorerDriver();
    80         }
    81         
    82         //解决webdriver在unix环境中,最大化会出现异常的bug,unix最大化在options中单独设置
    83         if(OS.startsWith("win")){
    84             assert webDriver != null;
    85             webDriver.manage().window().maximize();
    86         }
    87 
    88         //设置页面加载最大时长30秒
    89         assert webDriver != null;
    90         webDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
    91         //设置元素出现最大时长30秒  
    92         webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    93         
    94         return webDriver;
    95     }
    View Code

    4、src/main/Resources/sys_config.properties配置中需要添加Remote webdriver的配置,告诉集群在哪儿&用哪种浏览器

    remote.webdriver.url=http://xx.xx.xx.xx:4444/wd/hub/
    remote.webdriver.browser=chrome

    url是操作第一步中selenium集群所在的地址,能够直接访问

    操作

    1、docker搭建selenium集群——不要问为啥用docker,问就是因为docker简单稳定;若想远程调试可以安装debug版本,使用VNC调试。

    # 创建docker网络
    docker network create grid
    # 以docker容器的形式启动hub并暴露4444端口
    docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hub:3.14.0-europium
    # 以docker容器的形式启动并挂载Chrome的Node
    docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome:3.14.0-europium
    # 以docker容器的形式启动并挂载Firefox的Node
    docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox:3.14.0-europium

    2、Jenkins部署客户端(都是构建maven项目,参考web端部署)

    创建maven项目流水线>源码管理填写client端git仓库及分支>前置脚本干掉进程>构建设置(同web端)>后置脚本启动程序

    后置脚本如下

    cp -r /home/jiayifei.1995/.jenkins/workspace/LuckyFrameClient/target/* /home/jiayifei.1995/deploy/LuckyFrameClient
    BUILD_ID=donKillMe
    cd /home/jiayifei.1995/deploy/LuckyFrameClient/classes/
    sh start_service.sh

    注意事项

    1、构建之后没有email_template目录咋整?  答:检查pom文件,看看是否将需要的目录放到<insides>标签里面了

                                    <resource>
                                        <directory>src/main/Resources</directory>
                                        <includes>
                                            <include>**/*.cmd</include>
                                            <include>**/*.bat</include>
                                            <include>**/*.exe</include>
                                            <include>**/*.conf</include>
                                            <include>**/*.sh</include>
                                            <include>**/*.txt</include>
                                            <include>**/*.properties</include>
                                            <include>**/email_template/*.ftl</include>
                                        </includes>
                                    </resource>

    2、我如何添加远程执行case呢?答:添加远程用例当然还得改下web端啦

    src/main/resources/templates/testexecution/taskScheduling这个目录下的add与edit都需要添加下,改动部分代码如下

                <div class="form-group" id="divBrowserType" style="display:none;">    
                    <label class="col-sm-3 control-label">浏览器类型:</label>
                    <div class="col-sm-8">
                        <label class="radio-box"> <input type="radio" name="browserType" value="0" th:checked="true"/> IE </label> 
                        <label class="radio-box"> <input type="radio" name="browserType" value="1" /> 火狐 </label> 
                        <label class="radio-box"> <input type="radio" name="browserType" value="2" /> 谷歌 </label>
                        <label class="radio-box"> <input type="radio" name="browserType" value="3" /> Edge </label>
                        <label class="radio-box"> <input type="radio" name="browserType" value="4" /> Remote </label>
                    </div>
                </div>    
  • 相关阅读:
    SLAM基础知识
    标准的机器学习问题
    LAS的数据格式
    Python中的多线程和多进程
    【go】log
    【亲密关系】3-吸引力
    【mysql】做 mariadb 的备库无法启动
    【zabbix-server】Supervising process xxxx which is not our child....exits
    【win10】添加程序自启动
    【Oralce】数据去重,限制某个字段的数据长度,替换空格符
  • 原文地址:https://www.cnblogs.com/ftxy/p/14465763.html
Copyright © 2020-2023  润新知