在XUnit中运行BenchmarkDotNet

38

我的项目中使用的是.NET Core 3.1(Web API,VS2019)和XUnit 2.4.1。最近,我考虑添加一些性能测试,然后我找到了这个库-BenchmarkDotNet。由于我已经在使用XUnit进行其他测试,所以我想从XUnit [Fact]中运行BenchmarkDotNet

我在这篇帖子中发现了解释,其中说明必须关闭xunit的程序集副本。所以我尝试了以下操作:

  1. 为了保持简单,我创建了一个全新的.net core 3.1控制台应用程序项目,并编写了要进行基准测试的示例方法:
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[MinColumn, MaxColumn, MedianColumn, KurtosisColumn]
[HtmlExporter]
public class TestScenarios
{
    [Params("test")]
    public string TextToHash { get; set; }

    [Benchmark]
    public string CalculateSha256()
    {
        var engine = SHA256.Create();
        var hash = engine.ComputeHash(Encoding.ASCII.GetBytes(TextToHash));
        return Encoding.ASCII.GetString(hash);
    }
}

然后在 Program.cs 文件中我有:


Translated text: "Then in Program.cs file, I have:"
class Program
{
    static void Main(string[] args)
    {
        BenchmarkRunner.Run<TestScenarios>();
    }
}

当在Release模式下编译和运行应用程序时,我验证了正确创建了包含日志和基准输出文件的BenchmarkDotNet.Artifacts文件夹。

  1. 我将XUnit项目添加到解决方案中,并创建了简单的[Fact]方法:
public class DotNetBenchmarkTest
{
    [Fact]
    public void TestMethod()
    {
        BenchmarkRunner.Run<TestScenarios>();
    }
}

同时在Release配置下建立并从测试资源管理器中运行此方法会在bin/Release/dotnetcoreapp3.1/目录下创建BenchmarkDotNet.Artifacts文件夹,但日志文件为空。

  1. 我还尝试将以下内容添加到我的XUnit项目的根目录中的xunit.runner.json文件中:
{
  "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
  "shadowCopy": false,
  "methodDisplay": "classAndMethod",
  "diagnosticMessages": true
}

但是似乎对行为没有影响 - 我验证了文件xunit.runner.json已复制到输出 bin 目录(属性 -> 复制到输出目录 -> 总是复制)。

  1. 我还安装了 xUnit.net Console Runner v2.4.1 并尝试从控制台运行测试:
xunit .\path\assembly-name.dll -noshadow

再次没有运气。我在这个 github 链接 找到了选项 -noshadow,看起来该选项在旧版本中可用,但在我的 xunit控制台运行器v2.4.1 的帮助输出中未列出,但我还是试了一下。

所以我的问题是是否可以让 DotNetBenchmarkTest 与 XUnit 共同工作,如果可以,您能指出我错在哪里吗?


2
你解决了这个问题吗?通过测试运行,我的基准测试方法只显示“N/A”。 - Rob McCabe
还要确保您正在 Release 模式下运行。至少这是我必须做的。dotnet test -c Release - Daniel Lidström
尝试检查BenchmarkDotNet.Artifacts文件夹中的日志文件,并处理其中的任何问题。我的问题是“定义基准引用xx的程序集xx;如果您拥有此依赖项,请在RELEASE中构建它。如果您没有,则可以使用'config.WithOptions(ConfigOptions.DisableOptimizationsValidator)'禁用此策略。”最终,我根据他们的文档使用了配置。 - Weihui Guo
2个回答

1
我创建了一个包装测试夹具,运行基准测试,收集输出并在最后打印摘要:
public class Benchmarks
{
    private readonly ITestOutputHelper output;

    public Benchmarks(ITestOutputHelper output)
    {
        this.output = output;
    }

    [Fact]
    public void Run_Benchmarks()
    {
        var logger = new AccumulationLogger();

        var config = ManualConfig.Create(DefaultConfig.Instance)
            .AddLogger(logger)
            .WithOptions(ConfigOptions.DisableOptimizationsValidator);

        BenchmarkRunner.Run<FooBenchmarks>(config);

        // write benchmark summary
        output.WriteLine(logger.GetLog());
    }
}

[MemoryDiagnoser]
public class FooBenchmarks
{
    [GlobalSetup]
    public void Setup()
    {
        ModuleInitializer.Initialize();
        ...
    }

    [Benchmark]
    public async Task ProcessRequest_Benchmark()
    {
        ...
    }
}

0

我正在 XUnit 测试中运行 BenchmarkDotNet 基准测试。

请确保您的项目引用了这些 NuGet 包。

  • xunit
  • xunit.runner.visualstudio
  • Microsoft.NET.Test.Sdk

然后你可以从Visual Studio或通过命令行使用dotnet test运行xunit测试,因为这是一个.NET Core项目。

xunit.console.runner能够运行.NET Framework项目。

点击这里这里了解更多解释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接