【问题标题】:Reading an environment variable set by a test in Jenkins pipeline在 Jenkins 管道中读取由测试设置的环境变量
【发布时间】:2020-05-28 13:07:40
【问题描述】:

未找到对此特定问题的任何引用。

我正在寻找一种方法来在 Jenkins 管道中实现类似的目标,该管道使用 Protractor 和 Cucumber.js 运行我们的验收测试:

            steps {
                container('selenium') {
                    script {
                        try {
                             {
                                //run tests
                            }
                        }
                        catch (err) {
                            if (env.testFailed == 'true') {
                                println "A test failure exists - build status updated to failure"
                                currentBuild.result = 'FAILURE'
                                error "Test(s) have failed"
                            } 
                            else {
                                println "No test failures exist - build status updated to success"
                                currentBuild.result = 'SUCCESS'
                            }
                        }
                    }
                }
            }

如果 testFailed 的 env var 为“true”,这将导致构建失败。原因是我们遇到了 Protractor-Cucumber 框架的错误,如果失败的测试重试并通过,阶段的退出代码仍然是 1。

所以在每个测试的 After 钩子中,如果场景状态失败,我使用 node.js 将 env var 设置为 true:

  if (scenario.result.status === Status.FAILED) {
    process.env.testFailed = 'true';
  }
  if (scenario.result.status === Status.PASSED) {
    process.env.testFailed = 'false';
  }

我发现的问题是 Jenkins 管道无法读取 catch 部分的代码块中的 env var 值。它始终为空。

有什么想法吗?

【问题讨论】:

标签: node.js jenkins protractor jenkins-pipeline


【解决方案1】:

1) 更改 After 挂钩以将真/假标志同步写入文件。

2) 读取catch块中的文件

catch(err) {
   testFailed = sh(script:'cat result.flag.txt', returnStdout: true).trim()
   if(testFailed == 'true') {
      ...
   }

}

如果在 npm test 的输出中有总/通过/失败案例数的另一个选项

lines = []

try {
   lines = sh(script:'npm test', returnStdout: true).readLines();    
}
catch(err) {
   size = lines.size()

   // parse the last 20 lines to extract fail/pass/total number
   for(int i=size-20;i<size;i++) {
      line[i]
   } 
}

【讨论】:

  • 好主意,会试试这个
  • 所以还有一个问题。我们的测试并行运行!所以这个文件经常被覆盖。所以测试将失败并且文件更新。但是随后另一个测试将通过并覆盖该值,因此管道将错误地通过!知道如何克服这个问题吗?
  • 在 After 钩子中,只有当 test 写入标志文件失败时, test pass 才不会这样做。但是您提到失败的测试将被重试,所以我认为在 After hook 中标记测试结果不是一个好的选择,我认为从 catch 中的npm test 的输出中解析总/通过/失败的案例数更好.
【解决方案2】:

为什么现在不起作用?

我看到您正在容器中运行测试。当您设置环境变量时,它会反映在您的容器范围而不是 Jenkins 主服务器上

你可以尝试做什么

这实际上取决于您如何运行测试,但这应该是一个选项

// run tests here

// you should have a variable for your container
def exit_code = sh(script: "sudo docker inspect ${container.id} --format='{{.State.ExitCode}}'", returnStdout: true)

sh "exit ${exit_code}"

这实际上也取决于你如何在容器内启动测试, 因此,如果您使用此信息更新您的答案,我可以为您提供帮助

【讨论】:

  • 谢谢 Sergey,yong 的回答对我有用。所以我认为会使用它。这是很好的信息。我们通过 NPM 脚本命令开始测试。
猜你喜欢
  • 1970-01-01
  • 2017-08-09
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多