有没有合并 NUnit 结果文件的工具?

发布于 2024-08-07 00:53:30 字数 308 浏览 3 评论 0原文

由于不清楚的原因,我的 Nunit 测试装置无法在单次运行中执行,因此我被迫在单独的运行中执行一些测试。然而,这意味着测试结果被分割到多个输出文件中。

是否有可用的工具可以将 NUnit 结果 XML 文件合并到单个 XML 文件中?

我尝试过使用现有的 Nunit-summary 工具,但这只是按顺序解析带有给定 XSL 文件的 XML 文件,并将结果连接为一个大文件。

相反,我希望它首先将测试用例的结果合并/分组到正确的命名空间/测试装置中,然后将其提供给 XSLT 处理器。这样,所有测试结果都应该通过夹具显示,即使它们不是在单次运行中收集的。

For unclear reasons my Nunit test fixture cannot be executed in a single run, so I'm forced to execute a few tests in separate runs. However this means that the test results are splitted over multiple output files.

Is there a tool available which can merge NUnit result XML files into a single XML file?

I've tried using the existing Nunit-summary tool, but this simply sequentially parses the XML files with the given XSL file and concatenates the result as one big file.

Instead I would like it to merge/group the results for the test cases into the right namespaces/testfixtures first and then feed it to the XSLT processor. This way all test results should be displayed by fixture even though they're not gathered in a single run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哭泣的笑容 2024-08-14 00:53:30

这可能已经太晚了,无法帮助您,但我们最近遇到了类似的问题,并编写了一个小型开源工具来帮助您: https://github.com/15below/NUnitMerger

从自述文件中:

在 MSBuild 中使用

加载任务:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
             ToolsVersion="4.0"
             DefaultTargets="Build">
  <UsingTask AssemblyFile="$(MSBuildProjectDirectory)\..\Tools\MSBuild\15below.NUnitMerger.dll" TaskName="FifteenBelow.NUnitMerger.MSBuild.NUnitMergeTask" />
  ...

在目标中为其提供文件数组:

  <Target Name="UnitTest" DependsOnTargets="OtherThings">
    ... Generate the individual files here in $(TestResultsDir) ...

    <ItemGroup>
      <ResultsFiles Include="$(TestResultsDir)\*.xml" />
    </ItemGroup> 

    <NUnitMergeTask FilesToBeMerged="@(ResultsFiles)" OutputPath="$(MSBuildProjectDirectory)\TestResult.xml" />
  </Target>

在 OutputPath 中查找生成的组合结果。

在 F# 中使用

创建一个 F# 控制台应用程序并添加 15below.NUnitMerger.dll、System.Xml 和 System.Xml.Linq 作为引用。

open FifteenBelow.NUnitMerger.Core
open System.IO
open System.Xml.Linq

// All my files are in one directory
WriteMergedNunitResults (@"..\testdir", "*.xml", "myMergedResults.xml")

// I want files from all over the place
let myFiles = ... some filenames as a Seq

myFiles
|> Seq.map (fun fileName -> XDocument.Parse(File.ReadAllText(fileName)))
|> FoldDocs
|> CreateMerged
|> fun x -> File.WriteAllText("myOtherMergedResults.xml", x.ToString())

This is probably too late to help you, but we recently encountered a similar issue and wrote a small open source tool to help out: https://github.com/15below/NUnitMerger

From the readme:

Using in MSBuild

Load the task:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
             ToolsVersion="4.0"
             DefaultTargets="Build">
  <UsingTask AssemblyFile="$(MSBuildProjectDirectory)\..\Tools\MSBuild\15below.NUnitMerger.dll" TaskName="FifteenBelow.NUnitMerger.MSBuild.NUnitMergeTask" />
  ...

Feed it an array of files with in a target:

  <Target Name="UnitTest" DependsOnTargets="OtherThings">
    ... Generate the individual files here in $(TestResultsDir) ...

    <ItemGroup>
      <ResultsFiles Include="$(TestResultsDir)\*.xml" />
    </ItemGroup> 

    <NUnitMergeTask FilesToBeMerged="@(ResultsFiles)" OutputPath="$(MSBuildProjectDirectory)\TestResult.xml" />
  </Target>

Find the resulting combined results at OutputPath.

Using in F#

Create an F# console app and add 15below.NUnitMerger.dll, System.Xml and System.Xml.Linq as references.

open FifteenBelow.NUnitMerger.Core
open System.IO
open System.Xml.Linq

// All my files are in one directory
WriteMergedNunitResults (@"..\testdir", "*.xml", "myMergedResults.xml")

// I want files from all over the place
let myFiles = ... some filenames as a Seq

myFiles
|> Seq.map (fun fileName -> XDocument.Parse(File.ReadAllText(fileName)))
|> FoldDocs
|> CreateMerged
|> fun x -> File.WriteAllText("myOtherMergedResults.xml", x.ToString())
云胡 2024-08-14 00:53:30

我使用上面的 15below NUnitMerger 一段时间,但想扩展它,由于我的 F# 技能还不够好,所以我检查了它们的机制并在 C# 中实现了以下类来实现同样的事情。这是我的起始代码,它可能会帮助任何也想在 C# 中进行此类操作的人:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;

namespace RunNUnitTests
{
    public static class NUnitMerger
    {
        public static bool MergeFiles(IEnumerable<string> files, string output)
        {
            XElement environment = null;
            XElement culture = null;
            var suites = new List<XElement>();

            bool finalSuccess = true;
            string finalResult = "";
            double totalTime = 0;
            int total = 0, errors = 0, failures = 0, notrun = 0, inconclusive = 0, ignored = 0, skipped = 0, invalid = 0;
            foreach (var file in files)
            {
                var doc = XDocument.Load(file);
                var tr = doc.Element("test-results");

                if (environment == null)
                    environment = tr.Element("environment");
                if (culture == null)
                    culture = tr.Element("culture-info");

                total += Convert.ToInt32(tr.Attribute("total").Value);
                errors += Convert.ToInt32(tr.Attribute("errors").Value);
                failures += Convert.ToInt32(tr.Attribute("failures").Value);
                notrun += Convert.ToInt32(tr.Attribute("not-run").Value);
                inconclusive += Convert.ToInt32(tr.Attribute("inconclusive").Value);
                ignored += Convert.ToInt32(tr.Attribute("ignored").Value);
                skipped += Convert.ToInt32(tr.Attribute("skipped").Value);
                invalid += Convert.ToInt32(tr.Attribute("invalid").Value);

                var ts = tr.Element("test-suite");
                string result = ts.Attribute("result").Value;

                if (!Convert.ToBoolean(ts.Attribute("success").Value))
                    finalSuccess = false;

                totalTime += Convert.ToDouble(ts.Attribute("time").Value);

                if (finalResult != "Failure" && (String.IsNullOrEmpty(finalResult) || result == "Failure" || finalResult == "Success"))
                    finalResult = result;

                suites.Add(ts);
            }

            if (String.IsNullOrEmpty(finalResult))
            {
                finalSuccess = false;
                finalResult = "Inconclusive";
            }

            var project = XElement.Parse(String.Format("<test-suite type=\"Test Project\" name=\"\" executed=\"True\" result=\"{0}\" success=\"{1}\" time=\"{2}\" asserts=\"0\" />", finalResult, finalSuccess ? "True" : "False", totalTime));
            var results = XElement.Parse("<results/>");
            results.Add(suites.ToArray());
            project.Add(results);

            var now = DateTime.Now;
            var trfinal = XElement.Parse(String.Format("<test-results name=\"Merged results\" total=\"{0}\" errors=\"{1}\" failures=\"{2}\" not-run=\"{3}\" inconclusive=\"{4}\" ignored=\"{5}\" skipped=\"{6}\" invalid=\"{7}\" date=\"{8}\" time=\"{9}\" />", total, errors, failures, notrun, inconclusive, ignored, skipped, invalid, now.ToString("yyyy-MM-dd"), now.ToString("HH:mm:ss")));
            trfinal.Add(new[] { environment, culture, project });
            trfinal.Save(output);

            return finalSuccess;
        }

    }
}

I was using the 15below NUnitMerger above for a while, but wanted to extend it and since my F# skills are not good enough to do it there, I inspected their mechanism and implemented the following class in C# to achieve the same thing. Here is my starting code which might help anyone who also want to do this kind of manipulation in C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;

namespace RunNUnitTests
{
    public static class NUnitMerger
    {
        public static bool MergeFiles(IEnumerable<string> files, string output)
        {
            XElement environment = null;
            XElement culture = null;
            var suites = new List<XElement>();

            bool finalSuccess = true;
            string finalResult = "";
            double totalTime = 0;
            int total = 0, errors = 0, failures = 0, notrun = 0, inconclusive = 0, ignored = 0, skipped = 0, invalid = 0;
            foreach (var file in files)
            {
                var doc = XDocument.Load(file);
                var tr = doc.Element("test-results");

                if (environment == null)
                    environment = tr.Element("environment");
                if (culture == null)
                    culture = tr.Element("culture-info");

                total += Convert.ToInt32(tr.Attribute("total").Value);
                errors += Convert.ToInt32(tr.Attribute("errors").Value);
                failures += Convert.ToInt32(tr.Attribute("failures").Value);
                notrun += Convert.ToInt32(tr.Attribute("not-run").Value);
                inconclusive += Convert.ToInt32(tr.Attribute("inconclusive").Value);
                ignored += Convert.ToInt32(tr.Attribute("ignored").Value);
                skipped += Convert.ToInt32(tr.Attribute("skipped").Value);
                invalid += Convert.ToInt32(tr.Attribute("invalid").Value);

                var ts = tr.Element("test-suite");
                string result = ts.Attribute("result").Value;

                if (!Convert.ToBoolean(ts.Attribute("success").Value))
                    finalSuccess = false;

                totalTime += Convert.ToDouble(ts.Attribute("time").Value);

                if (finalResult != "Failure" && (String.IsNullOrEmpty(finalResult) || result == "Failure" || finalResult == "Success"))
                    finalResult = result;

                suites.Add(ts);
            }

            if (String.IsNullOrEmpty(finalResult))
            {
                finalSuccess = false;
                finalResult = "Inconclusive";
            }

            var project = XElement.Parse(String.Format("<test-suite type=\"Test Project\" name=\"\" executed=\"True\" result=\"{0}\" success=\"{1}\" time=\"{2}\" asserts=\"0\" />", finalResult, finalSuccess ? "True" : "False", totalTime));
            var results = XElement.Parse("<results/>");
            results.Add(suites.ToArray());
            project.Add(results);

            var now = DateTime.Now;
            var trfinal = XElement.Parse(String.Format("<test-results name=\"Merged results\" total=\"{0}\" errors=\"{1}\" failures=\"{2}\" not-run=\"{3}\" inconclusive=\"{4}\" ignored=\"{5}\" skipped=\"{6}\" invalid=\"{7}\" date=\"{8}\" time=\"{9}\" />", total, errors, failures, notrun, inconclusive, ignored, skipped, invalid, now.ToString("yyyy-MM-dd"), now.ToString("HH:mm:ss")));
            trfinal.Add(new[] { environment, culture, project });
            trfinal.Save(output);

            return finalSuccess;
        }

    }
}
任性一次 2024-08-14 00:53:30

我在网上读到 Nunit 结果文件是 XML,所以我想你可以使用普通的合并软件(如 WinMerge)合并该文件

I read on the web that Nunit result files are XML so i guess you can merge the file with an ordinary merge software as WinMerge

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文