【问题标题】:XUnit.net capture the result of each test right after it runsXUnit.net 在运行后立即捕获每个测试的结果
【发布时间】:2015-04-21 16:51:04
【问题描述】:

我正在尝试使用 XUnit.net 作为自定义本地测试调度程序的替代品。自制调度程序的特点之一是,对于长时间运行的测试,它会在测试通过/后立即将测试结果(通过/失败,以及导致失败的异常)输出到数据库中。失败。

因为可能有大量长时间运行的测试,这对于查看运行过程中的测试进度很有用(不必等待完整的测试通过,直到看到所有结果,因为完整的测试通过可能需要一些时间)。

XUnit.net 源在这里:https://github.com/xunit/xunit

我看过BeforeAfterTestAttribute,但是“After”方法不能访问测试结果,只能访问测试方法。我想要类似的东西,但也可以访问测试结果,以便我可以立即向数据库报告结果(而不必等待完整的测试套件完成)。

似乎(来自源)唯一可以访问实际测试结果的是TestRunner,但据我所知,测试运行器没有可扩展性模型。

我想出的一种可能的解决方法如下:

[Fact]
TestMethod()
{
    //This method takes a lambda, handles exceptions, uploads to my
    //database, and then rethrows.
    RunTestWithExtraLogging(() => 
    {
        //Actual test goes here
    }
}

上述解决方案并不理想,因为它要求每个测试的作者调用“RunTestWithExtraLogging”方法。

PS:如果它支持这个,我愿意考虑一个不同的测试框架(除了 xUnit.net)......

【问题讨论】:

    标签: c# unit-testing xunit.net


    【解决方案1】:

    是的,我相信您需要创建自己的跑步者。下面提供了一个关于如何做到这一点的简单示例(您需要在 TestMethodRunnerCallback 方法中添加所需的逻辑:

    namespace MyTestRunner
    {
        using System;
        using System.Linq;
        using Xunit;        
    
        public class Program
        {
            public static int Main(string[] args)
            {
                var testAssembly = TestAssemblyBuilder.Build(
                    new ExecutorWrapper(args[0], null, false));
    
                var tests = testAssembly.EnumerateTestMethods(x =>  x
                    .DisplayName
                    .ToLowerInvariant();
    
                var testMethods = (args.Length > 1 && !string.IsNullOrEmpty(args[1])
                    ? tests.Contains(args[1].ToLowerInvariant())).ToList()
                    : tests.ToList();
    
                if (testMethods.Count == 0)
                    return 0;
    
                var runnerCallback = new TestMethodRunnerCallback();
                testAssembly.Run(testMethods, runnerCallback);
    
                return runnerCallback.FailedCount;
            }
    
            public class TestMethodRunnerCallback : ITestMethodRunnerCallback
            {
                public int FailedCount { get; private set; }
    
                public void AssemblyFinished(TestAssembly testAssembly, int total, int failed, int skipped, double time)
                {
                    FailedCount = failed;
                }
    
                public void AssemblyStart(TestAssembly testAssembly)
                {
                }
    
                public bool ClassFailed(TestClass testClass, string exceptionType, string message, string stackTrace)
                {
                    return true;
                }
    
                public void ExceptionThrown(TestAssembly testAssembly, Exception exception)
                {
                }
    
                public bool TestFinished(TestMethod testMethod)
                {
                    return true;
                }
    
                public bool TestStart(TestMethod testMethod)
                {
                    return true;
                }
            }
        }
    }
    

    编辑: 似乎在 xUnit.net 2.0 中 TestAssemblyBuilder 已被替换为 XunitFrontController。下面的代码显示了如何在测试运行时捕获测试通过的结果:

    public class Program
    {
        public static void Main(string[] args)
        {
            string assemblyPath = @"path";
            XunitFrontController controller = new XunitFrontController(
                assemblyPath);
    
            TestAssemblyConfiguration assemblyConfiguration = new TestAssemblyConfiguration();
    
            ITestFrameworkDiscoveryOptions discoveryOptions = TestFrameworkOptions.ForDiscovery(assemblyConfiguration);
            ITestFrameworkExecutionOptions executionOptions = TestFrameworkOptions.ForExecution(assemblyConfiguration);
    
            IMessageSink messageSink = new CustomTestMessageVisitor<ITestMessage>();
    
            Console.WriteLine("Running tests");
    
            controller.RunAll(
                messageSink: messageSink,
                discoveryOptions: discoveryOptions,
                executionOptions: executionOptions);
        }
    }
    
    public class CustomTestMessageVisitor<T> : TestMessageVisitor<T> where T : ITestMessage
    {
        protected override bool Visit(ITestFinished message)
        {
            Console.WriteLine("Test {0} finished.",
                message.Test.DisplayName);
            return true;
        }
    
        protected override bool Visit(ITestPassed message)
        {
            Console.WriteLine("Test {0} passed", message.Test.DisplayName);
            return true;
        }
    
        protected override bool Visit(ITestFailed message)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (string exceptionType in message.ExceptionTypes)
            {
                stringBuilder.AppendFormat("{0}, ", exceptionType);
            }
    
            Console.WriteLine("Test {0} failed with {1}", 
                message.Test.DisplayName, 
                stringBuilder.ToString());
            return true;
        }
    }
    

    【讨论】:

    • 你引用的是什么版本的 XUnit -- 当我尝试这个时,我无法解析 TestAssemblyBuilder。我似乎也无法在 GitHub 上找到该类:github.com/xunit/xunit/… 我也无法解析 ITestMethodRunnerCallback。这些接口/类是 XUnit NuGet 包的一部分吗?
    • 这使用xunit.runner.utility.dll,它曾经是xunitcontrib.codeplex.com 的一部分,现在显然已移至github.com/xunit/resharper-xunit
    • @Hydraxy 快速浏览一下当前的 github 存储库,似乎现在可能有另一种首选方法:实现 XmlTestExecutionVisitor 而不是 ITestMethodRunnerCallback。这用于例如在 Asp.Net 测试堆栈中,您可能想看看 github.com/aspnet/Testing
    • 从这个页面看起来好像 xunit.runner.utility 是应该包含 xunit.runner.utility.dll (xunit.github.io/docs/nuget-packages.html) 的包 - 但如果我拉下那个包我只获取不包含类型 TestAssemblyBuilder 的 xunit.runner.utility.desktop.dll。我能够在你最初在 1.9.1 版本中提到的位置找到 TestAssemblyBuilder 类型:(xunit.codeplex.com/releases/view/90058)...你知道新的 xunit.runner.utility.desktop 中是否有对应的等效类。 dll?
    • 看起来在新的 xunit.runner.utility.desktop.dll 中替换 TestAssemblyBuilder 的类型是 XunitFrontController。
    猜你喜欢
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    相关资源
    最近更新 更多