你如何从 Jenkins 运行 NUnit 测试?

Posted

技术标签:

【中文标题】你如何从 Jenkins 运行 NUnit 测试?【英文标题】:How do you run NUnit tests from Jenkins? 【发布时间】:2012-02-25 15:18:19 【问题描述】:

我希望在每晚和每次提交到 svn 时为 C# 应用程序运行自动化 NUnit 测试。

这是 Jenkins-CI 可以做到的吗? 是否有在线教程或操作说明文档,其中记录了我可以查看的类似设置?

【问题讨论】:

你还有什么要找的吗? 我正在寻找具有类似设置的教程或操作指南文档。 您是否让 NUnit 从命令行按照您的需要运行测试?如果没有,那就是第 1 步 【参考方案1】:

对于 .Net Core,只需使用以下脚本添加“执行 shell”构建步骤:

#!bash -x

cd $my_project_dir
rm -rf TestResults   # Remove old test results.
dotnet test -l trx

之后添加“发布 MSTest 测试结果报告”构建后操作以使测试结果可见。

默认测试报告路径应为**/*.trx,并将发布所有生成的.trx 文件。

【讨论】:

【参考方案2】:

Nunit 3 或以上农工:

    构建步骤(Windows 命令行) "c:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe" c:\AutomationTraining\CSharpSelenium\bin\Debug\test.dll --result=TestR.xml;format=nunit2

    Nunit 报告发布的 Post 步骤,它仅显示 Jenkins 工作区目录中的测试结果文件,而不是您的项目中: TestR.xml

我们需要以 nunit2 格式制作测试结果,因为现在 Jenkins Nunit 插件无法识别 Nunit3 结果格式。 选项字符串格式也不同: --result=TestR.xml;format=nunit2 不是 /xml=nunit-result.xml

【讨论】:

【参考方案3】:

这是我在 Jenkins 中使用 vstest 运行 OpenCover 的解决方案:

param(
[string] $sourceDirectory = $env:WORKSPACE
, $includedFiles = @("*Test.dll")
, $excludedFiles = @("*.IGNORE.dll")
, [string]$filterFolder = "*\bin\Debug*"
)

# Executables
$openCoverExecutable = "C:\Users\tfsbuild\AppData\Local\Apps\OpenCover\OpenCover.Console.exe"
$unitExecutable = "F:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"

# Logs
$openCoverReport = Join-Path $sourceDirectory "opencover.xml"
$openCoverFilter = "+[*]* -[*Test]*"

Write-Host "`r`n==== Configuration for executing tests ===="
Write-Host "Source: `"$sourceDirectory`""
Write-Host "Included files: `"$includedFiles`""
Write-Host "Excluded files: `"$excludedFiles`""
Write-Host "Folder filter: `"$filterFolder`""
Write-Host ""
Write-Host "OpenCover Report: `"$openCoverReport`""
Write-Host "OpenCover filter: `"$openCoverFilter`""

# look through all subdirectories of the source folder and get any unit test assemblies. To avoid duplicates, only use the assemblies in the Debug folder
[array]$files = get-childitem $sourceDirectory -include $includedFiles -exclude $excludedFiles -recurse | select -expand FullName | where $_ -like $filterFolder | Resolve-Path -Relative

$exitCode = 0
$failedTestDlls = ""

foreach ($file in $files)

    Write-Host "`r`nCurrent test dll: $file"

    # set all arguments and execute OpenCover
    $argumentList = @("-target:`"$unitExecutable`"", "-targetargs:`"$file /UseVsixExtensions:false /Logger:trx`"", "-register:user -filter:`"$openCoverFilter`" -mergeoutput -mergebyhash -skipautoprops -returntargetcode -output:`"$openCoverReport`"")

    $unitTestProcess = start-process -filepath $openCoverExecutable -argumentlist $argumentList -wait -nonewwindow -passthru -WorkingDirectory $sourceDirectory

    if ($unitTestProcess.ExitCode -ne 0)
    
        $failedTestDlls = $failedTestDlls + $file + "`r`n"
        $exitCode = $unitTestProcess.ExitCode
    


if ($exitCode -ne 0)

    Write-Host "`r`n==== Executing tests in following dlls failed ===="
    Write-Host "$failedTestDlls"


exit $exitCode

每个测试 dll 都在自己的进程中执行,因为我们在单个进程中执行所有测试 dll 时遇到了麻烦(与程序集加载有关的问题)。

【讨论】:

【参考方案4】:

我需要做你所做的,这是我设置 Jenkins 的方法:

    将 NUnit 插件添加到 Jenkins 在您的项目中,转到 Configure -> Build -> 添加构建步骤 在下拉菜单中向下滚动到 -> 执行 Windows 批处理命令 确保将此步骤放在您的 MSBuild 步骤之后 添加以下内容,替换变量:

单个 dll 测试:

[PathToNUnit]\bin\nunit-console.exe [PathToTestDll]\Selenium.Tests.dll /xml=nunit-result.xml

使用NUnit test projects进行多个dll测试:

[PathToNUnit]\bin\nunit-console.exe [PathToTests]\Selenium.Tests.nunit /xml=nunit-result.xml

    构建后操作下,勾选发布 NUnit 测试结果报告 对于文本框 Test report XMLs,输入 nunit-result.xml

一旦您的项目构建完成,NUUnit 将立即运行,并且可以在仪表板(如果您将鼠标悬停在天气报告图标上)或项目页面上的 上次测试结果 下查看结果.

您还可以在 Visual Studio 中运行该命令,或者作为本地构建过程的一部分。

这是我用来参考的两篇博文。我没有找到完全符合我要求的:1-Hour Guide to Continuous Integration Setup: Jenkins meets .Net (2011)Guide to building .NET projects using Hudson (2008)

【讨论】:

我真的不明白这怎么够。只有一个(或几个)测试 dll 是否正常?我们有很多它们,它们经常被创建和删除。难道不应该有一种方法可以做到这一点,而不必将测试硬编码到 jenkins 中吗? 将构建步骤指向在源代码控制下使用 .bat 或 .cmd 文件,这将启动您的 NUnit 命令。现在,您可以在不更改 Jenkins 的情况下修改将尽可能频繁地运行的测试。您还应该查看 NUnit 测试项目,因为这也可能对您有所帮助。关键是告诉 Jenkins 使用哪个 xml 文件来做测试报告。 只需使用您的 *.nunit 文件作为参数而不是 DLL 文件,例如"C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe" UnitTests/UnitTests.nunit。非常适合我。 你可以使用*.sln文件代替DLL,见documentation 啊。我的逻辑谬误是 NUnit 插件创建了一个新的“构建任务”类型。它的神奇巫术是 Post-Build 事件。 (而一个只是使用常规命令行来生成 .xml )【参考方案5】:

如果您不想对单元测试项目进行硬编码,最好编写一个脚本来获取所有单元测试项目的 dll。我们使用 Powershell 并遵循特定约定来命名我们的单元测试项目。以下是运行我们的单元测试的 powershell 文件的内容:

param(
[string] $sourceDirectory = $env:WORKSPACE
, $fileFilters = @("*.UnitTests.dll", "*_UnitTests.dll", "*UnitTests.dll")
, [string]$filterText = "*\bin\Debug*"
)

#script that executes all unit tests available.
$nUnitLog = Join-Path $sourceDirectory "UnitTestResults.txt"
$nUnitErrorLog = Join-Path $sourceDirectory "UnitTestErrors.txt"

Write-Host "Source: $sourceDirectory"
Write-Host "NUnit Results: $nUnitLog"
Write-Host "NUnit Error Log: $nUnitErrorLog"
Write-Host "File Filters: $fileFilters"
Write-Host "Filter Text: $filterText"

$cFiles = ""
$nUnitExecutable = "C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe"

# look through all subdirectories of the source folder and get any unit test assemblies. To avoid duplicates, only use the assemblies in the Debug folder
[array]$files = get-childitem $sourceDirectory -include $fileFilters -recurse | select -expand FullName | where $_ -like $filterText

foreach ($file in $files)

    $cFiles = $cFiles + $file + " "


# set all arguments and execute the unit console
$argumentList = @("$cFiles", "/framework:net-4.5", "/xml=UnitTestResults.xml")

$unitTestProcess = start-process -filepath $nUnitExecutable -argumentlist $argumentList -wait -nonewwindow -passthru -RedirectStandardOutput $nUnitLog -RedirectStandardError $nUnitErrorLog

if ($unitTestProcess.ExitCode -ne 0)

    "Unit Test Process Exit Code: " + $unitTestProcess.ExitCode
    "See $nUnitLog for more information or $nUnitErrorLog for any possible errors."
    "Errors from NUnit Log File ($nUnitLog):"
    Get-Content $nUnitLog | Write-Host


$exitCode = $unitTestProcess.ExitCode

exit $exitCode

该脚本足够健壮,可以重复用于我们所有的构建作业。如果您不喜欢 NUnit 控制台的完整路径,您可以始终将该位置放在您的 PATH 环境变量中。

然后我们将 RunUnitTests.ps1 文件放在我们的构建服务器上并使用这个批处理命令:

powershell.exe -file "full-path-to-script-direcory\RunUnitTests.ps1"

【讨论】:

运行良好,但我遇到了两个问题。首先是源目录。我必须将 sourcedirectory 更改为 [string] $sourceDirectory = $(get-location),对于带有空格的路径,我必须将程序集传递到 nUnit 更改为 $cFiles = $cFiles + '"' + $file + '"' + " " 如果我们有测试,我们正在通过测试播放列表执行。我们可以使用 .dll 为 Jenkins 执行这个测试播放列表吗?【参考方案6】:

我认为最好在构建未通过时失败,这样您就不要部署它。做这样的事情:

C:\YourNUnitDir\nunit-console.exe C:\YourOutDir\YourLib.dll /noshadow
if defined ERRORLEVEL if %ERRORLEVEL% neq 0 goto fail_build

:: any other command

: fail_build
endlocal
exit %ERRORLEVEL%

参考:http://www.greengingerwine.com/index.php/2013/01/tip-check-errorlevel-in-your-post-build-steps-when-using-nunit/

【讨论】:

这是否比仅第一行所做的更多?我不这么认为。如果 nunit-console.exe 返回 != 0 如果测试失败,则构建无论如何都会失败。 我忘了说我在 Jenkins 工作中调用 nunit-console.exe 后有一些命令。 Jenkins 只考虑最后一个命令 ERRORLEVEL 所以它对我不起作用。 这会妨碍发布步骤的好处吗?我希望插件在失败的测试配置中具有简单的标记构建为“”。【参考方案7】:

Ralph Willgoss 的解决方案运行良好,但我更改了 2 点以使其变得更好:

a) 我直接使用 NUnit 项目而不是 DLL 文件。这使得在 NUnit GUI 中添加更多程序集或配置测试变得更加容易。

b) 我在批处理中添加了一行,以防止测试失败时构建失败:

[PathToNUnit]\bin\nunit-console.exe [PathToTestProject]\UnitTests.nunit /xml=nunit-result.xm
exit 0

提到的 NUnit 插件会自动标记构建UNSTABLE,这正是我想要的,每当测试失败时。它以黄点显示。

【讨论】:

如果单元测试失败,您为什么希望构建失败?失败的测试不应该表明您不想继续部署吗? 我还用 jenkins 构建了我的 nightlies,如果它们编译,我不希望它们失败,所以我可以测试其他所有内容。 “不稳定”状态给了我一个提示,并非一切都按预期运行。不稳定。如果发布版本不稳定,我不会部署它。【参考方案8】:

这很好用,我以前设置过。

配置 NUnit 以将结果输出到 XML 文件并配置 NUnit Jenkins Plugin 以使用此 XML 文件。结果将显示在仪表板上。

现在,如何调用 NUnit 取决于您。我们这样做的方式是: Jenkins 作业执行 NAnt 目标执行 NUnit 测试套件。

您可以将 Jenkins 作业配置为在提交时运行和/或在特定时间安排。

【讨论】:

这几乎是我想要的,但我无法让 NUnit 插件从管道/工作流中工作。我改用 XUnit 插件,效果很好。【参考方案9】:

Jenkins 确实有支持它的插件。确切的配置将在很大程度上取决于您的项目设置。有针对 nUnit、MSBuild、nAnt 等的特定插件。首先查看插件页面,但应该不难弄清楚。

【讨论】:

以上是关于你如何从 Jenkins 运行 NUnit 测试?的主要内容,如果未能解决你的问题,请参考以下文章

问题在Jenkins上运行NUnit测试

如何与Jenkins集成.NET项目

如何从 Visual Studio 以调试模式运行 NUnit?

NUnit 有时以“无法定位夹具”结尾

NUnit3 测试不在 TFS 构建上运行

运行 vstest.console.exe 时如何过滤 NUnit 测试