在Jenkins中产生CTest结果(xUnit>;=1.58)

在Jenkins中产生CTest结果(xUnit>;=1.58),jenkins,cmake,ctest,Jenkins,Cmake,Ctest,在jenkins中集成CMake+CTest似乎很容易。该插件非常容易配置(只需设置源代码树和构建树,完成!)。然而,我不明白如何调用CTest步骤 根据main,由于版本1.58,CTest的XML输出是受支持的,请参阅 这就是我能找到的所有文档。当我在google或stackoverflow上搜索时,我只能找到需要手动操作的非常旧的文档 我想知道如何使用xUnit(1.81)设置最近的jenkins(1.532.1)。我应该创建“添加构建步骤”吗?我应该创建“构建后操作”吗?要运行CTest

在jenkins中集成CMake+CTest似乎很容易。该插件非常容易配置(只需设置源代码树和构建树,完成!)。然而,我不明白如何调用CTest步骤

根据main,由于版本1.58,CTest的XML输出是受支持的,请参阅

这就是我能找到的所有文档。当我在google或stackoverflow上搜索时,我只能找到需要手动操作的非常旧的文档


我想知道如何使用xUnit(1.81)设置最近的jenkins(1.532.1)。我应该创建“添加构建步骤”吗?我应该创建“构建后操作”吗?要运行CTest并生成正确的XML文件,以便jenkins能够集成它们,我需要填写什么?

下面是一个小示例,演示如何让xUnit获取CTest生成的XML测试结果文件。该示例由单个C++源文件<代码> Meal.CPP < /C> < /P>组成。
#include <cstdlib>
int main() {
    std::exit(-1);
}
CMake列表文件生成一个可执行文件
main
,并通过两个CMake测试运行该可执行文件,出于演示目的,其中一个将始终失败,另一个将始终成功

使用Jenkins,设置新作业并添加新的cmakebuilder构建步骤。将CMake源目录指向本地计算机上包含示例项目的文件夹。CMake生成目录应设置为
build
。这将使Jenkins在作业的工作区目录中创建一个CMake构建文件夹。设置
Clean Build
标志使作业始终以干净状态开始是个好主意

然后,假设您正在运行Unix,添加一个
执行shell
作业步骤,并在
命令
框中输入以下shell脚本:

cd build
/usr/local/bin/ctest --no-compress-output -T Test || /usr/bin/true
使用选项
-T Test
运行
ctest
将使ctest在生成文件夹内的子文件夹
Testing
中生成一个XML输出文件,该文件可由
xUnit
插件在生成后操作中获取。
| |/usr/bin/true
对于防止Jenkins在某些测试失败时过早中止构建(不运行xUnit插件)是必要的

如果您使用的是Windows,请设置类似的
执行Windows批处理命令
作业步骤:

cd build
"C:\Program Files (x86)\CMake 2.8\bin\ctest.exe" --no-compress-output -T Test || verify > NUL
最后,必须按照以下方式配置
xUnit
插件:


添加
发布xUnit测试结果报告
生成后操作,然后使用插件的
添加
按钮创建
测试版本
测试结果报告。在
CTest版本(默认)模式中
输入文件模式
build/Testing/**/Test.xml

对于那些想要在Jenkins声明性管道中解析CTest输出的人,现在可以使用非常容易地完成这项工作,因为它可以直接解析CTest输出

Jenkinsfile
中添加一个stage以在build目录中运行ctest,并添加一个
post
stage以使用xUnit处理输出。下面是一个骨架示例:

pipeline {
  agent any
  stages {
    stage('Configure') {
      steps {
        dir('build') {
          sh 'cmake ../'
        }
      }
    }
    stage('Build') {
      steps {
        dir('build') {
          sh 'cmake --build .'
        }
      }
    }  
    stage('Test') {
      steps {
        dir('build') {
          sh 'ctest -T test --no-compress-output'
        }
      }
    }
  }
  post {
    always {
      // Archive the CTest xml output
      archiveArtifacts (
        artifacts: 'build/Testing/**/*.xml',
        fingerprint: true
      )

      // Process the CTest xml output with the xUnit plugin
      xunit (
        testTimeMargin: '3000',
        thresholdMode: 1,
        thresholds: [
          skipped(failureThreshold: '0'),
          failed(failureThreshold: '0')
        ],
      tools: [CTest(
          pattern: 'build/Testing/**/*.xml',
          deleteOutputFiles: true,
          failIfNotNew: false,
          skipNoTestFiles: true,
          stopProcessingIfError: true
        )]
      )

      // Clear the source and build dirs before next run
      deleteDir()
    }
  }
}

有关如何在声明性管道中配置
xUnit
插件的示例,是非常有用的资源。

两条注释,1。缺少--CTest执行没有压缩输出。如果没有这个标志,你将得到2。为了简化操作,我确实为CTest注册了一个bug来控制返回值:@malat感谢
--无压缩输出的提示。我已经更新了答案。这就是为什么我如此喜欢Stackoverflow。非常感谢,帮了大忙!在Ubuntu 14.04上,shell命令应该是
/usr/bin/ctest--no compress output-T Test | |/bin/true
,因为二进制文件的位置不同。您是否尝试设置了xUnit的“如果测试结果未更新,则生成失败”标志?
pipeline {
  agent any
  stages {
    stage('Configure') {
      steps {
        dir('build') {
          sh 'cmake ../'
        }
      }
    }
    stage('Build') {
      steps {
        dir('build') {
          sh 'cmake --build .'
        }
      }
    }  
    stage('Test') {
      steps {
        dir('build') {
          sh 'ctest -T test --no-compress-output'
        }
      }
    }
  }
  post {
    always {
      // Archive the CTest xml output
      archiveArtifacts (
        artifacts: 'build/Testing/**/*.xml',
        fingerprint: true
      )

      // Process the CTest xml output with the xUnit plugin
      xunit (
        testTimeMargin: '3000',
        thresholdMode: 1,
        thresholds: [
          skipped(failureThreshold: '0'),
          failed(failureThreshold: '0')
        ],
      tools: [CTest(
          pattern: 'build/Testing/**/*.xml',
          deleteOutputFiles: true,
          failIfNotNew: false,
          skipNoTestFiles: true,
          stopProcessingIfError: true
        )]
      )

      // Clear the source and build dirs before next run
      deleteDir()
    }
  }
}