博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jenkins高级篇之Pipeline实践篇-6-Selenium和Jenkins持续集成-pipeline参数化构建selenium自动化测试
阅读量:4302 次
发布时间:2019-05-27

本文共 14584 字,大约阅读时间需要 48 分钟。

       这篇来思考下如何写一个方法,可以修改config.properties文件里面的属性。加入这个方法可以根据key修改value,那么我们就可以通过jenkins上变量,让用户输入,来修改config.properties文件里面的值。例如测试服务器地址和浏览器类型的名称。如果用户在Jenkins界面填写浏览器是chrome,那么我们就修改config.properties里面的browser=chrome,如果用户填写的是firefox,那么我们就在启动selenium测试之前去修改browser=firefox。这样,灵活的控制参数,就达到了我们第一个需求。

1.根据Java的方法

我们知道grooy是可以无缝执行java代码,我也写了一个java的代码,放在pipleline/selenium.groovy文件里,结果我在测试的时候,报了一个错误,这个需要jenkins管理员去approve这个脚本的执行,但是我的jenkins环境上没有这个approve的相关的script,很神奇。

import hudson.model.*;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;def setKeyValue(key, value, file_path) {    Properties prop = new Properties()    try {        prop.load(new FileInputStream(file_path))    }catch (FileNotFoundException e){        e.printStackTrace()    }catch (IOException e) {        e.printStackTrace()    }        // write into file     try {        prop.setProperty(key, value)	    FileOutputStream fos = new FileOutputStream(file_path)        prop.store(fos, null)        fos.close()    }catch (FileNotFoundException e){        e.printStackTrace()    }catch (IOException e) {        e.printStackTrace()    }}return this;

结果测试下,报了一个沙箱错误:

ERROR: Error met:org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.util.Properties

其实,这个类似错误,我在工作中也遇到过,一般来说管理员去点击批准这个脚本执行就可以。我的环境,在升级一个script security相关的插件之后,连脚本批准入口都不显示了,很神奇。只好换一种思路去写代码了。

2.Pipeline自带的readFile和writeFile

我的思路是这样的,先通过readFile方法获取到原来文件的内容,返回是一个字符串对象。然后根据换行符把字符串对象给切片,拿到一个list对象,遍历这个list,用if判断,根据Key找到这行,然后改写这行。由于这我们只是在内存改写,所以需要提前定义一个list对象来把改写和没有改写的都给add到新list,然后定义一个空字符串,遍历新list,每次拼接一个list元素都加上换行符。这样得到字符串就是一个完整内容,然后把这个内容利用writeFile方法写回到原来的config文件。

具体代码是这样的。

selenium_jenkins.groovy文件

import hudson.model.*;pipeline{    agent any    parameters {        string(name: 'BROWSER_TYPE', defaultValue: 'chrome', description: 'Type a browser type, should be chrome/firefox')        string(name: 'TEST_SERVER_URL', defaultValue: '', description: 'Type the test server url')        string(name: 'NODE', defaultValue: 'win-anthony-demo', description: 'Please choose a windows node to execute this job.')    }    	stages{	    stage("Initialization"){	        steps{	            script{	                browser = BROWSER_TYPE?.trim()	                test_url = TEST_SERVER_URL?.trim()	                win_node = NODE?.trim()	            }	        }	    }	    stage("Git Checkout"){	        steps{	            script{	                node(win_node) {	                     checkout([$class: 'GitSCM', branches: [[name: '*/master']],						    userRemoteConfigs: [[credentialsId: '6f4fa66c-eb02-46dc-a4b3-3a232be5ef6e', 							url: 'https://github.com/QAAutomationLearn/JavaAutomationFramework.git']]])	                }	            }	        }	    }	            stage("Set key value"){	        steps{	            script{	                node(win_node){	                    selenium_test = load env.WORKSPACE + "\\pipeline\\selenium.groovy"	                    config_file = env.WORKSPACE + "\\Configs\\config.properties"	                    try{	                        selenium_test.setKeyValue2("browser", "abc123", config_file)	                        file_content = readFile config_file                            println file_content	                    }catch (Exception e) {	                        error("Error met:" + e)	                    }	                }	            }	        }	    }	    	    stage("Run Selenium Test"){	        steps{	            script{	                node(win_node){	                    println "Here will start to run selenium test."	                }	            }	        }	    }	}}

selenium.groovy文件

import hudson.model.*;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;def setKeyValue(key, value, file_path) {    Properties prop = new Properties()    try {        prop.load(new FileInputStream(file_path))    }catch (FileNotFoundException e){        e.printStackTrace()    }catch (IOException e) {        e.printStackTrace()    }        // write into file     try {        prop.setProperty(key, value)	    FileOutputStream fos = new FileOutputStream(file_path)        prop.store(fos, null)        fos.close()    }catch (FileNotFoundException e){        e.printStackTrace()    }catch (IOException e) {        e.printStackTrace()    }}def setKeyValue2(key, value, file_path) {    // read file, get string object    file_content_old = readFile file_path    println file_content_old    //遍历每一行,判断,然后替换字符串    lines = file_content_old.tokenize("\n")    new_lines = []    lines.each { line ->        if(line.trim().startsWith(key)) {            line = key + "=" + value            new_lines.add(line)        }else {            new_lines.add(line)        }    }    // write into file    file_content_new = ""    new_lines.each{line ->        file_content_new += line + "\n"    }    writeFile file: file_path, text: file_content_new, encoding: "UTF-8"}return this;

这里看第二个方法是我的思路,虽然比较啰嗦,但是实现了这个修改文件的需求。

测试结果看看是否把browser = chrome 改成browser = abc123

[Pipeline] readFile[Pipeline] echobaseURL=http://demo.guru99.com/v4/index.php# https://www.utest.com  backup websiteuserName=mngr169501password=sYhYtUd# browser driver pathfirefoxpath=./Drivers\\geckodriver.exechromepath=./Drivers\\chromedriver.exe# browser instance# the browser vlaue will only be firefox or chrome herebrowser=chrome[Pipeline] writeFile[Pipeline] readFile[Pipeline] echobaseURL=http://demo.guru99.com/v4/index.php# https://www.utest.com  backup websiteuserName=mngr169501password=sYhYtUd# browser driver pathfirefoxpath=./Drivers\\geckodriver.exechromepath=./Drivers\\chromedriver.exe# browser instance# the browser vlaue will only be firefox or chrome herebrowser=abc123[Pipeline] }[Pipeline] // node

你如果对日志不放心,你可以去你拉取之后代码路径去看看是否修改了,修改的对不对。

接下来,我把github里面config.properties 中browser的值改成firefox,然后我通过pipeline代码去改成chrome,来跑一个集成测试,看看行不行,测试环境URL就无法改,这个没有第二套同样产品的地址,这个就留个你们自己项目上的测试环境和生产环境,自己试一下。

提交之后,两个文件代码如下

import hudson.model.*;pipeline{    agent any    parameters {        string(name: 'BROWSER_TYPE', defaultValue: 'chrome', description: 'Type a browser type, should be chrome/firefox')        string(name: 'TEST_SERVER_URL', defaultValue: '', description: 'Type the test server url')        string(name: 'NODE', defaultValue: 'win-anthony-demo', description: 'Please choose a windows node to execute this job.')    }    	stages{	    stage("Initialization"){	        steps{	            script{	                browser_type = BROWSER_TYPE?.trim()	                test_url = TEST_SERVER_URL?.trim()	                win_node = NODE?.trim()	            }	        }	    }	    stage("Git Checkout"){	        steps{	            script{	                node(win_node) {	                     checkout([$class: 'GitSCM', branches: [[name: '*/master']],						    userRemoteConfigs: [[credentialsId: '6f4fa66c-eb02-46dc-a4b3-3a232be5ef6e', 							url: 'https://github.com/QAAutomationLearn/JavaAutomationFramework.git']]])	                }	            }	        }	    }	            stage("Set key value"){	        steps{	            script{	                node(win_node){	                    selenium_test = load env.WORKSPACE + "\\pipeline\\selenium.groovy"	                    config_file = env.WORKSPACE + "\\Configs\\config.properties"	                    try{	                        selenium_test.setKeyValue2("browser", browser_type, config_file)	                        //test_url 你自己替代	                        file_content = readFile config_file                            println file_content	                    }catch (Exception e) {	                        error("Error met:" + e)	                    }	                }	            }	        }	    }	    	    stage("Run Selenium Test"){	        steps{	            script{	                node(win_node){	                    run_bat = env.WORKSPACE + "\\run.bat"	                    bat (run_bat)	                }	            }	        }	    }	}}
import hudson.model.*;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Properties;def setKeyValue(key, value, file_path) {    // read file, get string object    file_content_old = readFile file_path    println file_content_old    //遍历每一行,判断,然后替换字符串    lines = file_content_old.tokenize("\n")    new_lines = []    lines.each { line ->        if(line.trim().startsWith(key)) {            line = key + "=" + value            new_lines.add(line)        }else {            new_lines.add(line)        }    }    // write into file    file_content_new = ""    new_lines.each{line ->        file_content_new += line + "\n"    }    writeFile file: file_path, text: file_content_new, encoding: "UTF-8"}return this;

测试结果:

主要日志如下:

[Pipeline] nodeRunning on win-anthony-demo in C:\JenkinsNode\workspace\selenium-pipeline-demo[Pipeline] {[Pipeline] load[Pipeline] { (C:\JenkinsNode\workspace\selenium-pipeline-demo\pipeline\selenium.groovy)[Pipeline] }[Pipeline] // load[Pipeline] readFile[Pipeline] echobaseURL=http://demo.guru99.com/v4/index.php# https://www.utest.com  backup websiteuserName=mngr169501password=sYhYtUd# browser driver pathfirefoxpath=./Drivers\\geckodriver.exechromepath=./Drivers\\chromedriver.exe# browser instance# the browser vlaue will only be firefox or chrome herebrowser=chrome[Pipeline] writeFile[Pipeline] readFile[Pipeline] echobaseURL=http://demo.guru99.com/v4/index.php# https://www.utest.com  backup websiteuserName=mngr169501password=sYhYtUd# browser driver pathfirefoxpath=./Drivers\\geckodriver.exechromepath=./Drivers\\chromedriver.exe# browser instance# the browser vlaue will only be firefox or chrome herebrowser=chrome[Pipeline] }[Pipeline] // node[Pipeline] }[Pipeline] // script[Pipeline] }[Pipeline] // stage[Pipeline] stage[Pipeline] { (Run Selenium Test)[Pipeline] script[Pipeline] {[Pipeline] nodeRunning on win-anthony-demo in C:\JenkinsNode\workspace\selenium-pipeline-demo[Pipeline] {[Pipeline] bat[selenium-pipeline-demo] Running batch scriptC:\JenkinsNode\workspace\selenium-pipeline-demo>C:\JenkinsNode\workspace\selenium-pipeline-demo\run.batC:\JenkinsNode\workspace\selenium-pipeline-demo>cd C:\Users\Anthont\git\AnthonyWebAutoDemo C:\Users\Anthont\git\AnthonyWebAutoDemo>mvn clean install [INFO] Scanning for projects...[WARNING] [WARNING] Some problems were encountered while building the effective model for AnthonyAutoV10:AnthonyAutoV10:jar:0.0.1-SNAPSHOT[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 19, column 15[WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.[WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects.[WARNING] [INFO] [INFO] -------------------< AnthonyAutoV10:AnthonyAutoV10 >--------------------[INFO] Building AnthonyAutoV10 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[WARNING] The POM for com.beust:jcommander:jar:1.66 is missing, no dependency information available[INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ AnthonyAutoV10 ---[INFO] Deleting C:\Users\Anthont\git\AnthonyWebAutoDemo\target[INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ AnthonyAutoV10 ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory C:\Users\Anthont\git\AnthonyWebAutoDemo\src\main\resources[INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ AnthonyAutoV10 ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ AnthonyAutoV10 ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory C:\Users\Anthont\git\AnthonyWebAutoDemo\src\test\resources[INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ AnthonyAutoV10 ---[INFO] Changes detected - recompiling the module![INFO] Compiling 11 source files to C:\Users\Anthont\git\AnthonyWebAutoDemo\target\test-classes[INFO] [INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ AnthonyAutoV10 ---[INFO] Surefire report directory: C:\Users\Anthont\git\AnthonyWebAutoDemo\target\surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Running TestSuiteStarting ChromeDriver 2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab) on port 1780Only local connections are allowed.Dec 23, 2018 9:52:43 PM org.openqa.selenium.remote.ProtocolHandshake createSessionINFO: Detected dialect: OSS INFO [main] (TC_NewCustomer_004.java:22)- Login is completed INFO [main] (TC_NewCustomer_004.java:28)- Proving customer details............. INFO [main] (TC_NewCustomer_004.java:46)- Validating adding new customer..............Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 166.426 sec - in TestSuiteResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ AnthonyAutoV10 ---[WARNING] JAR will be empty - no content was marked for inclusion![INFO] Building jar: C:\Users\Anthont\git\AnthonyWebAutoDemo\target\AnthonyAutoV10-0.0.1-SNAPSHOT.jar[INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ AnthonyAutoV10 ---[INFO] Installing C:\Users\Anthont\git\AnthonyWebAutoDemo\target\AnthonyAutoV10-0.0.1-SNAPSHOT.jar to C:\Users\Anthont\.m2\repository\AnthonyAutoV10\AnthonyAutoV10\0.0.1-SNAPSHOT\AnthonyAutoV10-0.0.1-SNAPSHOT.jar[INFO] Installing C:\Users\Anthont\git\AnthonyWebAutoDemo\pom.xml to C:\Users\Anthont\.m2\repository\AnthonyAutoV10\AnthonyAutoV10\0.0.1-SNAPSHOT\AnthonyAutoV10-0.0.1-SNAPSHOT.pom[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  03:05 min[INFO] Finished at: 2018-12-23T21:55:24+08:00[INFO] ------------------------------------------------------------------------[Pipeline] }[Pipeline] // node[Pipeline] }[Pipeline] // script[Pipeline] }[Pipeline] // stage[Pipeline] }[Pipeline] // withEnv[Pipeline] }[Pipeline] // node[Pipeline] End of PipelineFinished: SUCCESS

这里灵活的参数,我们实现了需求。

下一篇文章,我们来思考下如何把测试过程的日志和报告文件给放到Jenkins上,点击链接可以预览。这个我之前也没有做过,先研究下,有知道的同学可以告诉我哈。

 

转载地址:http://kzows.baihongyu.com/

你可能感兴趣的文章
MFC中动态获取/设置按钮的文字
查看>>
MFC中CString和int的转换
查看>>
退出MFC应用程序的方法集
查看>>
C/C++中如何获取数组的长度?
查看>>
VS2010 MFC中控件、对话框等背景颜色动态修改的方法
查看>>
MFC启动和关闭线程
查看>>
MFC绘制动态曲线,用双缓冲绘图技术防闪烁
查看>>
MFC SetWindowPos
查看>>
C++虚函数表,虚表指针,内存分布
查看>>
c++中.dll与.lib文件的生成与使用的详解
查看>>
CyAPI.lib(CyAPI.obj) : error LNK2019: 无法解析的外部符号...
查看>>
在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include &quot;StdAfx.h&quot;”?
查看>>
DeleteDC() 与 ReleaseDC() 的区别 [转]
查看>>
WinHand.cpp Line 199 错误 WinHand.cpp Line 218 错误
查看>>
GDI对象和CDC的使用方法(防止资源泄漏)
查看>>
MFC中的DC,CDC和HDC
查看>>
MFC 自定义消息四步曲与在参数中传递变量
查看>>
MFC多线程各种线程用法 .
查看>>
安全终止MFC线程全
查看>>
C++框架_之Qt的信号和槽的详解
查看>>