问题描述
我们需要在 Jenkins Pipeline 中使用 Selenium 自动化测试,该笔记将记录实现 Jenkins + Selenium 自动化测试的方法。
解决方法
我们所面对的问题,以及对应的解决方案已经在 #1 中说明,以下是我们最终的解决方案(有些无奈):
1)脱离 Jenkins 而实现自己的自动化脚本,通过退出状态反映自动化测试结果;
2)在 Jenkins Pipeline 中使用 sh 执行脚本,并获取退出状态;
3)通过自动化脚本的退出状态,判断自动化测试是否成功,并执行后续的操作及任务;
代码参考(我们只记录关键步骤):
pipeline { agent any stages { stage('build') { steps { script { def statusCode = sh returnStatus: true, script: "groovy selenium.groovy" if (statusCode != 0) { // 执行失败 } } } } } }
关于 sh 的用法可以参考 Shell Command 笔记,或者官方 Pipeline: Nodes and Processes/sh 文档。
常见问题汇总
java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
java - NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;J)V - Stack Overflow
Maven Repository: org.seleniumhq.selenium » selenium-java » 3.141.59
问题描述:
在 Jenkins Pipeline 中,使用 Selenium Java 类库,在执行自动化测试程序时,返回错误:
// 程序代码 @Grab(group='org.seleniumhq.selenium', module='selenium-java', version='3.141.59') ... WebDriver webDriver = new RemoteWebDriver(new URL(seleniumHub), desiredCapabilities); ... // 错误信息 java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V at com.google.common.reflect.TypeCapture.capture(TypeCapture.java:32) at com.google.common.reflect.TypeToken.<init>(TypeToken.java:125) at org.openqa.selenium.json.Json$1.<init>(Json.java:33) at org.openqa.selenium.json.Json.<clinit>(Json.java:33) at org.openqa.selenium.remote.NewSessionPayload.create(NewSessionPayload.java:100) at org.openqa.selenium.remote.NewSessionPayload.create(NewSessionPayload.java:94) at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:68) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:213) at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:131) at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:144) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83) at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235) at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.constructorCall(DefaultInvoker.java:25) ...
问题原因:
1)Selenium Java 3.141.59 需要使用 com.google.guava.guava 25.0-jre 类库
2)但是 Jenkins 2.241 也使用该类库,但是在 Jenkins 中该类库的版本非常旧(com.google.guava/guava/11.0.1)
3)因此导致 Selenium Java 调用旧版本的 Guava 类库,程序无法正常执行
解决办法:
# 不可行 # 最开始我们在编辑器中开发自动化测试程序(Selenium Java),现在要集成到 Jenkins 中(即代码复制到 Pipeline 中执行)才出现这个问题。我们无法强制指定 com.google.guava/guava/11.0.1 类库,因为该类库在 Jenkins 中已经加载,因此即使使用 @Grab 指定也不会成功。我们不会也不想使用那些奇技淫巧,比如改变类加载方式,这只会给以后带来麻烦。
# 不可行 # 也无法通过 Docker 节点运行,因为节点执行 Pipeline 也要载入 Jenkins 运行环境,依旧会出现同样的问题。
# 不可行 # 那在 Jenkins 中有没有 Selenium 插件呢?现有 Selenium 插件,该插件只是使 Jenkins 集群中增加 Selenium 集群,并且在 Jenkins 中增加 Selenium 管理界面。并不能解决我们的问题。
# 方案一 # 我们开始在网上寻找解决方法,很多做法大同小异,常见的做法是 maven test 执行自动化测试,本质上将就是脱离 Jenkins 而在命令行执行自动化测试脚本。最后我们也采用了这种做法:使用 Groovy 脚本,然后在 Jenkins 中执行 groovy 命令
我们只能选择# 方案一 #,因为只有# 方案一 #是 我们唯一能想到的 且 可行的 方案。
相关文章
「Jenkins Pipeline」- 接受构建通知,并拉取代码
「Jenkins Pipeline」- 在构建过程中,提示用户输入
「Jenkins Pipeline」- 发送 IRC 消息
「Jenkins Pipeline」- 文件、目录操作(复制、删除、重命名)
「Jenkins Pipeline」- 发送 Slack 通知
参考文献
Integration of Jenkins with Selenium WebDriver: Step-by-Step Tutorial
Maven & Jenkins Integration with Selenium: Complete Tutorial
How to Setup and Run Selenium Tests in Jenkins Using Maven and JUnit | BlazeMeter