如何使用 XUnit 2.0 和 FSharp 样式测试捕获输出
How to capture output with XUnit 2.0 and FSharp style tests
通常我用 F# 编写单元测试
open Swensen.Unquote
open Xunit
module MyTests =
[<Fact>]
let ``SomeFunction should return 10`` () =
let a = SomeFunction()
test <@ a = 10 @>
[<Fact>]
let ``SomeOtherFunction should return 11`` () =
let a = SomeFunction()
test <@ a = 11 @>
如果我想从 xunit 登录到控制台(根据 http://xunit.github.io/docs/capturing-output.html ),需要编写一个构造函数,该构造函数采用 ITestOutputHelper 然后使用它代替Console.WriteLine 和家人。
using Xunit;
using Xunit.Abstractions;
public class MyTestClass
{
private readonly ITestOutputHelper output;
public MyTestClass(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public void MyTest()
{
var temp = "my class!";
output.WriteLine("This is output from {0}", temp);
}
}
然而 fsharp 模块是静态的 类 并且测试是静态方法。没有构造函数来注入输出助手。
有没有办法访问当前测试的当前输出助手。我知道我可以将我的 fsharp 测试重写为非静态 类 但这是不希望的。
查看 XUnit 源代码后。
我很确定这是一个被忽视的案例。没有将 helper 注入静态 类。
如果 xUnit 没有任何替代机制来注入参数,那么我想唯一的选择是将测试定义为 F# 对象类型中的方法。我也更喜欢使用 let
将测试编写为函数,但以下简单对象类型看起来还不错:
open Swensen.Unquote
open Xunit
open Xunit.Abstractions
type MyTests(output:ITestOutputHelper) =
[<Fact>]
member __.``SomeFunction should return 10`` () =
let a = SomeFunction()
output.WriteLine("Some function returned {0}", a)
test <@ a = 10 @>
如果 xUnit 支持一些其他选项,那就太好了 - 我怀疑他们可能会接受建议,如果它不会太尴尬(也许使用方法参数?)
但除非 xUnit 添加对某些其他方法的支持,否则我认为您将需要使用 F# 对象和方法。
现在这个解决方案似乎也适用于 let 绑定:
module Tests
open System
open System.Text.Json
open System.Text.Json.Serialization
open Xunit
open Xunit.Abstractions
open Core.DomainModel.OnboardingModel
type SerializationTests(output: ITestOutputHelper) =
let options = JsonSerializerOptions()
do
JsonFSharpConverter(
unionEncoding = JsonUnionEncoding.InternalTag,
unionTagName = "type",
allowOverride = true
)
|> options.Converters.Add
[<Fact>]
let ``CanSerializeDiscriminatedUnion using Fsharp.SystemTextJson`` () =
let onboardingStep = InformName "test"
let serialization = JsonSerializer.Serialize(onboardingStep, options)
output.WriteLine serialization
执行此命令时,结果将显示在控制台上:
dotnet test --logger:"console;verbosity=detailed"
结果:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.1)
[xUnit.net 00:00:00.44] Discovering: Core.DomainModel.Tests
[xUnit.net 00:00:00.47] Discovered: Core.DomainModel.Tests
[xUnit.net 00:00:00.47] Starting: Core.DomainModel.Tests
[xUnit.net 00:00:00.58] Finished: Core.DomainModel.Tests
Passed Tests+SerializationTests.CanSerializeDiscriminatedUnion using Fsharp.SystemTextJson [58 ms]
Standard Output Messages:
["InformName","test"]
Test Run Successful.
Total tests: 1
Passed: 1
Total time: 1.1842 Seconds
通常我用 F# 编写单元测试
open Swensen.Unquote
open Xunit
module MyTests =
[<Fact>]
let ``SomeFunction should return 10`` () =
let a = SomeFunction()
test <@ a = 10 @>
[<Fact>]
let ``SomeOtherFunction should return 11`` () =
let a = SomeFunction()
test <@ a = 11 @>
如果我想从 xunit 登录到控制台(根据 http://xunit.github.io/docs/capturing-output.html ),需要编写一个构造函数,该构造函数采用 ITestOutputHelper 然后使用它代替Console.WriteLine 和家人。
using Xunit;
using Xunit.Abstractions;
public class MyTestClass
{
private readonly ITestOutputHelper output;
public MyTestClass(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public void MyTest()
{
var temp = "my class!";
output.WriteLine("This is output from {0}", temp);
}
}
然而 fsharp 模块是静态的 类 并且测试是静态方法。没有构造函数来注入输出助手。
有没有办法访问当前测试的当前输出助手。我知道我可以将我的 fsharp 测试重写为非静态 类 但这是不希望的。
查看 XUnit 源代码后。
我很确定这是一个被忽视的案例。没有将 helper 注入静态 类。
如果 xUnit 没有任何替代机制来注入参数,那么我想唯一的选择是将测试定义为 F# 对象类型中的方法。我也更喜欢使用 let
将测试编写为函数,但以下简单对象类型看起来还不错:
open Swensen.Unquote
open Xunit
open Xunit.Abstractions
type MyTests(output:ITestOutputHelper) =
[<Fact>]
member __.``SomeFunction should return 10`` () =
let a = SomeFunction()
output.WriteLine("Some function returned {0}", a)
test <@ a = 10 @>
如果 xUnit 支持一些其他选项,那就太好了 - 我怀疑他们可能会接受建议,如果它不会太尴尬(也许使用方法参数?)
但除非 xUnit 添加对某些其他方法的支持,否则我认为您将需要使用 F# 对象和方法。
现在这个解决方案似乎也适用于 let 绑定:
module Tests
open System
open System.Text.Json
open System.Text.Json.Serialization
open Xunit
open Xunit.Abstractions
open Core.DomainModel.OnboardingModel
type SerializationTests(output: ITestOutputHelper) =
let options = JsonSerializerOptions()
do
JsonFSharpConverter(
unionEncoding = JsonUnionEncoding.InternalTag,
unionTagName = "type",
allowOverride = true
)
|> options.Converters.Add
[<Fact>]
let ``CanSerializeDiscriminatedUnion using Fsharp.SystemTextJson`` () =
let onboardingStep = InformName "test"
let serialization = JsonSerializer.Serialize(onboardingStep, options)
output.WriteLine serialization
执行此命令时,结果将显示在控制台上:
dotnet test --logger:"console;verbosity=detailed"
结果:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 6.0.1)
[xUnit.net 00:00:00.44] Discovering: Core.DomainModel.Tests
[xUnit.net 00:00:00.47] Discovered: Core.DomainModel.Tests
[xUnit.net 00:00:00.47] Starting: Core.DomainModel.Tests
[xUnit.net 00:00:00.58] Finished: Core.DomainModel.Tests
Passed Tests+SerializationTests.CanSerializeDiscriminatedUnion using Fsharp.SystemTextJson [58 ms]
Standard Output Messages:
["InformName","test"]
Test Run Successful.
Total tests: 1
Passed: 1
Total time: 1.1842 Seconds