如何检测我的测试是否在 Jenkins 环境中运行?

我有一个JUnit测试,用于跳过测试,如果开发人员的计算机没有运行它的先决条件软件。尽管是“junit”,但这是一个集成测试。像这样:Assumption

int isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor();
Assume.assumeThat("Software not present", isSoftwarePresent, is(equalTo(0)));

但是,由于这种假设,我一度意识到测试已经停止在Jenkins上的自动构建上运行,最终引入了回归,测试应该停止。

换句话说,Jenkins 从属环境中缺少所需的软件,这导致测试被跳过。

自动化测试由 maven 使用 FailSafe 插件在 Jenkins Pipeline 构建计划上运行。如何检测我的环境是 Jenkins,以便使假设条件更加严格?

也就是说,我希望条件是这样的:

boolean isJenkinsBuild = /* true if this is being run inside a Jenkins build, false otherwise */;
boolean isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor() == 0;
Assume.assumeTrue("Software not present", isSoftwarePresent || isJenkinsBuild);

甚至,

@Test
void testJenkinsEnvironment() {
    ...
    Assume.assumeTrue(isJenkinsBuild);
    Assert.assertTrue(isSoftwarePresent);
}

@Test
void testFeature() {
    ...
    Assume.assumeTrue(isSoftwarePresent);
    ...
}

答案 1

由于它们易于测试并传递给构建执行的每个程序,因此我选择基于环境变量进行检查。

虽然 rohit answer 显示了在 Jenkinsfile 上设置变量的一种方法,但我宁愿依赖 Jenkins 本身所做的操作,所以我检查了 Jenkins 作业上设置的环境变量,并且有很多选项可供选择:

一般詹金斯信息

这些在 Jenkins 实例上似乎是恒定的。

  • HUDSON_URL
  • JENKINS_URL

不是 Jenkins 特有的,但以下内容也很有用:

  • USER

我们的 Jenkins 在 user 下运行,因此测试该值也是一种可能性。jenkins

招聘信息

这些在相同作业的生成中具有恒定的值。

  • JOB_URL
  • JOB_NAME
  • JOB_BASE_NAME
  • JOB_DISPLAY_URL

构建信息

它们在同一版本中具有常量值(即,对于不同的调用)。sh

  • BUILD_URL
  • BUILD_TAG
  • RUN_CHANGES_DISPLAY
  • RUN_DISPLAY
  • BUILD_DISPLAY_NAME
  • BUILD_ID
  • BUILD_NUMBER

节点信息

这些与正在执行当前命令的节点相关。

  • JENKINS_HOME
  • JENKINS_NODE_COOKIE
  • NODE_LABELS
  • NODE_NAME

特殊

这个版本随着每个构建而变化,可能会因节点而异,甚至可能随 Jenkinsfile 配置而变化:

  • WORKSPACE

杂项

我不确定这些。他们肯定来自詹金斯,但我不知道他们的生命周期是什么。

  • HUDSON_SERVER_COOKIE
  • JENKINS_SERVER_COOKIE
  • HUDSON_COOKIE

最终注意事项

出于我自己的目的,我决定使用.这个名字非常特定于 Jenkins,它似乎比 .虽然这并不意味着构建是由 Jenkins 运行的,但在这种情况下,它将始终进行设置。我不介意误报,只要我没有得到假阴性。JENKINS_HOMEJENKINS_URL


答案 2

有几种方法可以实现这一目标:

  1. 您可以使应用程序接受参数,然后传递一个 TRUE/FALSE 值,指示它是否从 Jenkins 运行。

  2. 您还可以读取操作系统的系统属性

例如 System.getProperty(“os.arch”);

但是,如果您的 Jenkins 环境和工作区位于同一台计算机上,则此操作将不起作用。

  1. 您只需在管道中设置一个env变量(仅存在于管道中),在应用程序中,您可以读取该值

这样:

管道 - 选项1

     pipeline {
            environment {
                FROM_JENKINS= "TRUE" 
            } stage('test'){ 

                   sh "mvn test"
             }
        }

管道 - 选项2

     pipeline {
            stage('test'){ 

                    sh '''FROM_JENKINS="TRUE" // setting the env variable in the same shell where you are running mvn
                        mvn test'''
             }
        }

应用

boolean isJenkinsBuild = Boolean.valueOf(System.getenv("FROM_JENKINS"));
boolean isSoftwarePresent = new ProcessBuilder("check software presence").start().waitFor() == 0;
Assume.assumeTrue("Software not present", isSoftwarePresent || isJenkinsBuild);

希望它能帮助:)


推荐