在 Azure DevOps 中发布测试结果时如何包含 NUnit 测试输出?
How to include NUnit test output when publishing test results in Azure DevOps?
我有一个 vNext 构建,其中 运行 进行了一些 NUnit 测试并发布了结果。然而,测试产生的输出没有发布,即使它在相应的 XML 文件中找到。
例如:
但是,如果我检查相应的 XML 文件 - 它就在那里:
注意 <output>
元素。
我非常希望看到此输出与测试结果一起发布。我该怎么做?
P.S.
发布还有一个问题。 运行 持续时间在顶部窗格中报告为 4h 59m,但在底部详细信息窗格中它是正确的 10:48.176 分钟。 4h 59m 看起来非常像 5h,这是 EST 和 UTC 之间的时差。这些测试是 运行 在 Octopus 服务器上进行的,由 vNext 构建获取。也许某处时区混乱。
编辑 1
我们有本地 TFS
编辑 2
检查 Publish Test Results
任务的源代码表明它使用 Microsoft.TeamFoundation.TestClient.PublishTestResults
程序集来解析 NUnit XML 测试结果。具体来说,下面的 C# 代码用于解析 test-case
元素 (NUnit3ResultsXmlReader.cs):
if (testCaseResultNode.Attributes["result"] != null)
{
testCaseResultData.TestCaseResult.Outcome = !string.Equals(testCaseResultNode.Attributes["result"].Value, "Passed", StringComparison.OrdinalIgnoreCase) ? (!string.Equals(testCaseResultNode.Attributes["result"].Value, "Failed", StringComparison.OrdinalIgnoreCase) ? (!string.Equals(testCaseResultNode.Attributes["result"].Value, "Skipped", StringComparison.OrdinalIgnoreCase) ? TestOutcome.Inconclusive.ToString() : TestOutcome.NotExecuted.ToString()) : TestOutcome.Failed.ToString()) : TestOutcome.Passed.ToString();
XmlNode xmlNode1 = testCaseResultNode.SelectSingleNode("failure");
if (xmlNode1 != null)
{
XmlNode xmlNode2 = xmlNode1.SelectSingleNode("message");
XmlNode xmlNode3 = xmlNode1.SelectSingleNode("stack-trace");
testCaseResultData.TestCaseResult.ErrorMessage = xmlNode2 != null ? xmlNode2.InnerText : (string) null;
testCaseResultData.TestCaseResult.StackTrace = xmlNode3 != null ? xmlNode3.InnerText : (string) null;
XmlNode xmlNode4 = testCaseResultNode.SelectSingleNode("output");
if (!string.IsNullOrWhiteSpace(xmlNode4 != null ? xmlNode4.InnerText : (string) null))
testCaseResultData.ConsoleLog = xmlNode4.InnerText;
}
}
由此可见,程序集作者认为测试输出仅在相关测试用例失败时才有用。这是一个不幸的决定,因为输出什么时候有用不是由他们决定的。如果它在测试结果中 XML,那么它应该被发布。
打开了一个新问题https://github.com/Microsoft/azure-pipelines-tasks/issues/8979
打开了 Azure DevOps 功能请求 - https://developercommunity.visualstudio.com/idea/432166/the-publish-tests-azure-devops-plugin-should-publi.html
我对这种强加给我们的不幸行为的解决方案是在将 XML 测试结果交给发布测试结果任务之前对其进行处理。
以下 powershell 代码可以解决问题:
$Modified = $false
$xml = [xml](cat $OriginalTestResultsXmlFile -Raw)
$xml.SelectNodes('//test-case') |? { !$_.failure -and $_.output } |% {
$Modified = $true
$_.InnerXml = @"
<!-- Workaround the issue https://github.com/Microsoft/azure-pipelines-tasks/issues/8979. No real failure here -->
<failure/>
$($_.InnerXml)
"@
}
if ($Modified)
{
$xml.Save($TestResultsXmlFile)
}
else
{
move $OriginalTestResultsXmlFile $TestResultsXmlFile
$OriginalTestResultsXmlFile = $TestResultsXmlFile
}
我们必须通过在 output
元素之外创建一个虚拟 failure
元素来欺骗任务执行我们需要的逻辑。
瞧瞧:
我有一个 vNext 构建,其中 运行 进行了一些 NUnit 测试并发布了结果。然而,测试产生的输出没有发布,即使它在相应的 XML 文件中找到。
例如:
但是,如果我检查相应的 XML 文件 - 它就在那里:
注意 <output>
元素。
我非常希望看到此输出与测试结果一起发布。我该怎么做?
P.S.
发布还有一个问题。 运行 持续时间在顶部窗格中报告为 4h 59m,但在底部详细信息窗格中它是正确的 10:48.176 分钟。 4h 59m 看起来非常像 5h,这是 EST 和 UTC 之间的时差。这些测试是 运行 在 Octopus 服务器上进行的,由 vNext 构建获取。也许某处时区混乱。
编辑 1
我们有本地 TFS
编辑 2
检查 Publish Test Results
任务的源代码表明它使用 Microsoft.TeamFoundation.TestClient.PublishTestResults
程序集来解析 NUnit XML 测试结果。具体来说,下面的 C# 代码用于解析 test-case
元素 (NUnit3ResultsXmlReader.cs):
if (testCaseResultNode.Attributes["result"] != null)
{
testCaseResultData.TestCaseResult.Outcome = !string.Equals(testCaseResultNode.Attributes["result"].Value, "Passed", StringComparison.OrdinalIgnoreCase) ? (!string.Equals(testCaseResultNode.Attributes["result"].Value, "Failed", StringComparison.OrdinalIgnoreCase) ? (!string.Equals(testCaseResultNode.Attributes["result"].Value, "Skipped", StringComparison.OrdinalIgnoreCase) ? TestOutcome.Inconclusive.ToString() : TestOutcome.NotExecuted.ToString()) : TestOutcome.Failed.ToString()) : TestOutcome.Passed.ToString();
XmlNode xmlNode1 = testCaseResultNode.SelectSingleNode("failure");
if (xmlNode1 != null)
{
XmlNode xmlNode2 = xmlNode1.SelectSingleNode("message");
XmlNode xmlNode3 = xmlNode1.SelectSingleNode("stack-trace");
testCaseResultData.TestCaseResult.ErrorMessage = xmlNode2 != null ? xmlNode2.InnerText : (string) null;
testCaseResultData.TestCaseResult.StackTrace = xmlNode3 != null ? xmlNode3.InnerText : (string) null;
XmlNode xmlNode4 = testCaseResultNode.SelectSingleNode("output");
if (!string.IsNullOrWhiteSpace(xmlNode4 != null ? xmlNode4.InnerText : (string) null))
testCaseResultData.ConsoleLog = xmlNode4.InnerText;
}
}
由此可见,程序集作者认为测试输出仅在相关测试用例失败时才有用。这是一个不幸的决定,因为输出什么时候有用不是由他们决定的。如果它在测试结果中 XML,那么它应该被发布。
打开了一个新问题https://github.com/Microsoft/azure-pipelines-tasks/issues/8979
打开了 Azure DevOps 功能请求 - https://developercommunity.visualstudio.com/idea/432166/the-publish-tests-azure-devops-plugin-should-publi.html
我对这种强加给我们的不幸行为的解决方案是在将 XML 测试结果交给发布测试结果任务之前对其进行处理。
以下 powershell 代码可以解决问题:
$Modified = $false
$xml = [xml](cat $OriginalTestResultsXmlFile -Raw)
$xml.SelectNodes('//test-case') |? { !$_.failure -and $_.output } |% {
$Modified = $true
$_.InnerXml = @"
<!-- Workaround the issue https://github.com/Microsoft/azure-pipelines-tasks/issues/8979. No real failure here -->
<failure/>
$($_.InnerXml)
"@
}
if ($Modified)
{
$xml.Save($TestResultsXmlFile)
}
else
{
move $OriginalTestResultsXmlFile $TestResultsXmlFile
$OriginalTestResultsXmlFile = $TestResultsXmlFile
}
我们必须通过在 output
元素之外创建一个虚拟 failure
元素来欺骗任务执行我们需要的逻辑。
瞧瞧: