Skip to content

Instantly share code, notes, and snippets.

@wwwlicious
Last active November 14, 2018 08:17
Show Gist options
  • Save wwwlicious/f13db34c3ff23a614a98 to your computer and use it in GitHub Desktop.
Save wwwlicious/f13db34c3ff23a614a98 to your computer and use it in GitHub Desktop.
UPDATE: Now part of the powerpack. Get the latest version https://github.com/JetBrains/meta-runner-power-pack/tree/master/xUnit.net-dotCover. Provides dotCover functionality for your xunit tests in TeamCity. Supports local or remote nuget feeds, different runners per teamcity buildconfig, supports .net legacy activation, xunit traits and custom …
<?xml version="1.0" encoding="UTF-8"?>
<meta-runner name="xUnit.net + dotCover 💕">
<description>Run xUnit.net tests with dotCover coverage: http://www.wwwlicious.com/2015/09/25/teamcity-dotcover-xunit-at-last/</description>
<settings>
<parameters>
<param name="xUnitNet.nugetSource" value="http://www.nuget.org/api/v2/" spec="text description='The nuget source url for the xunit runner' display='normal' label='Xunit Runner Nuget Source'" />
<param name="xUnitNet.executable" value="xunit.console.exe" spec="text description='The xunit runner executable to use in the nuget package' display='normal' label='Xunit Runner Executable'" />
<param name="xUnitNet.executable.args" value="" spec="text description='Custom xunit runner arguments' display='normal' label='Xunit Runner Executable additional arguments'" />
<param name="xUnitNet.executable.legacymode" value="false" spec="checkbox checkedValue='true' description='For mixed mode assemblies, enables xunit runner to use legacy activiation' uncheckedValue='false' label='Enable .Net V2 Legacy Activation' display='normal'" />
<param name="xUnitNet.assembliesPath" value="*/bin/*tests.dll" spec="text description='The assemblies to test; relative to the working directory. Asterix wildcard (*) is supported here' display='normal' label='Assemblies to test:'" />
<param name="xUnitNet.trait" value="" spec="text description='only run tests with matching name/value traits, one name=value per line (e.x. name=value)' validationMode='any' label='Include Traits' display='normal'" />
<param name="xUnitNet.notrait" value="Category=Integration" spec="text description='do not run tests with matching name/value traits, one name=value per line (e.x. name=value)' validationMode='any' label='Exclude Traits' display='normal'" />
<param name="xUnitNet.dotCover.Filters" spec="text description='Specifies coverage filters using the config format. Documentation http://www.jetbrains.com/dotcover/help/dotCover__Console_Runner_Commands.html' label='dotCover Filters' validationMode='any' display='normal'"><![CDATA[<!-- Coverage filters. It's possible to use asterisks as wildcard symbols. -->
<Filters>
<IncludeFilters>
<FilterEntry>
<ModuleMask>*</ModuleMask>
<ClassMask>*</ClassMask>
<FunctionMask>*</FunctionMask>
</FilterEntry>
</IncludeFilters>
<ExcludeFilters>
<FilterEntry>
<ModuleMask>*Tests</ModuleMask>
</FilterEntry>
</ExcludeFilters>
</Filters>]]></param>
<param name="xUnitNet.dotCover.AttributeFilters" spec="text description='Specifies attribute filters using the config format. Documentation http://www.jetbrains.com/dotcover/help/dotCover__Console_Runner_Commands.html' validationMode='any' label='dotCover AttributeFilters' display='normal'"><![CDATA[<!-- Attribute filters. It's possible to use asterisks as wildcard symbols. -->
<AttributeFilters>
<AttributeFilterEntry>System.CodeDom.Compiler.GeneratedCodeAttribute</AttributeFilterEntry>
<AttributeFilterEntry>System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute</AttributeFilterEntry>
<AttributeFilterEntry>System.ObsoleteAttribute</AttributeFilterEntry>
</AttributeFilters>]]></param>
</parameters>
<build-runners>
<runner name="Install Test runner, Create config, Run tests, Update coverage" type="jetbrains_powershell">
<parameters>
<param name="jetbrains_powershell_execution" value="PS1" />
<param name="jetbrains_powershell_noprofile" value="true" />
<param name="jetbrains_powershell_errorToError" value="error" />
<param name="jetbrains_powershell_script_mode" value="CODE" />
<param name="jetbrains_powershell_bitness" value="x86" />
<param name="teamcity.step.mode" value="default" />
<param name="jetbrains_powershell_script_code"><![CDATA[[CmdletBinding()]
Param (
[string] $workingDir = "%teamcity.build.workingDir%",
[string] $nugetExe = "%teamcity.tool.NuGet.CommandLine.DEFAULT.nupkg%\tools\nuget.exe",
[string] $xUnitNuget = "%xUnitNet.nugetSource%",
[string] $xUnitExe = "%xUnitNet.executable%",
[string] $dotCoverExecutable = "%teamcity.tool.dotCover%",
[boolean] $xunitLegacy = [boolean]"%xUnitNet.executable.legacymode%",
[string] $assemblyFilter = "%xUnitNet.assembliesPath%",
[string] $traits = "%xUnitNet.trait%",
[string] $notraits = "%xUnitNet.notrait%",
[string] $dotCoverFilter = "%xUnitNet.dotCover.Filters%",
[string] $dotCoverAttributeFilter = "%xUnitNet.dotCover.AttributeFilters%",
[string] $xunitArgs = "%xUnitNet.executable.args%"
)
$ErrorActionPreference = "Stop"
try {
## get xunit runner from nuget package feed
iex "$nugetExe install xunit.runner.console -source $xUnitNuget"
$xunit = Join-Path $workingDir "xunit.runner.console.*\tools\$xUnitExe" | Resolve-Path
## modify runner config if legacy v2 runtime activation mode required
If($xunitLegacy) {
$config = [string]$xunit + ".config"
$doc = (Get-Content $config) -as [Xml]
$doc.configuration.startup.SetAttribute("useLegacyV2RuntimeActivationPolicy", "true")
$doc.Save($config)
}
## Search for the assemblies using wildcard pattern
$assemblies = (Get-ChildItem $assemblyFilter -Recurse | select -ExpandProperty FullName)
Write-Host "Found test assemblies: " $assemblies
## create single-line correctly formatted xunit argument
# split multi-line xunit args into single line and correctly format
$assemblyArg = $assemblies.Trim() -Join " "
If($traits.Length -gt 0) {
$traitArg = ($traits.Trim().Split("`r`n") | where {$_ -ne ""} | % { "-trait """+$_+""""}) -join " "
}
If($notraits.Length -gt 0) {
$notraitArg = ($notraits.Trim().Split("`r`n") | where {$_ -ne ""} | % { "-notrait """+$_+""""}) -join " "
}
$xunitArg = $assemblyArg, $traitArg, $notraitArg, $xunitArgs -join " "
## filenames
$outputFile = "xunitcoverage.dcvr"
$settingsFileName = "coverage_settings.xml"
$coverageLogFileName = "dotCoverXunitLog.txt"
## genrate coverage settings file
$settingsXml = @"
<?xml version="1.0" encoding="utf-8"?>
<CoverageParams>
<TargetExecutable>$xunit</TargetExecutable>
<TargetArguments>$xunitArg</TargetArguments>
<TargetWorkingDir>$workingDir</TargetWorkingDir>
<Output>$outputFile</Output>
$dotCoverFilter
$dotCoverAttributeFilter
</CoverageParams>
"@
# Avoid BOM http://stackoverflow.com/questions/5596982/using-powershell-to-write-a-file-in-utf-8-without-the-bom
$settingsXml | Out-File $settingsFileName -Encoding ASCII
## Run coverage
$dotCover = Join-Path $dotCoverExecutable "dotCover.exe"
$dotCoverArgs = " cover " + $settingsFileName + " /LogFile=$coverageLogFileName /ReturnTargetExitCode"
Write-Host "##teamcity[message text='dotCoverExecutable: $dotCoverExecutable']"
Write-Host "##teamcity[message text='dotCoverArgs: $dotCoverArgs']"
$command = $dotCover + $dotCoverArgs
iex $command
## Report coverage results and output build artifacts
write-host "##teamcity[importData type='dotNetCoverage' tool='dotcover' path='$outputFile']"
write-host "##teamcity[publishArtifacts '$settingsFileName']"
write-host "##teamcity[publishArtifacts '$coverageLogFileName']"
write-host "##teamcity[publishArtifacts '$outputFile']"
}
catch {
Write-Host "##teamcity[buildStatus text='$_' status='FAILURE']"
Write-Host "##teamcity[message text='$_' status='ERROR']"
exit 1
}]]></param>
</parameters>
</runner>
</build-runners>
<requirements />
</settings>
</meta-runner>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment