如何为 FsUnit 提供有用的断言失败消息?
How to have useful assertion-failure messages for FsUnit?
我使用的是 FsUnit 2.3.2,我对失败消息不满意。请参阅以下示例:
[<Test>]
let ``test 1``() =
[1; 3]
|> should equal [1;2]
... 给了我不太有用的信息:
Expected and actual are both
Microsoft.FSharp.Collections.FSharpList`1[System.Int32]
at FsUnit.TopLevelOperators.should[a,a](FSharpFunc`2 f, a x, Object y)
in d:\GitHub\FsUnit\src\FsUnit.NUnit\FsUnit.fs:line 44 at Program.test
1() in F:\work\playground\fsunit\fsunit\Program.fs:line 9
我发现的解决方法是使用数组而不是列表:
[<Test>]
let ``test 2``() =
[|1; 4|]
|> should equal [|1;2|]
...产生
Expected and actual are both System.Int32[2]
Values differ at index [1]
Expected: 2
But was: 4
第二个问题是我是否定义了 ADT
type MyT =
A of int
| B of string
[<Test>]
let ``test 4``() =
A 10
|> should equal (B "abc")
...给我消息:
Expected: Program+MyT+B
But was: Program+MyT+A
...我可以通过像这样为 MyT 实现 ToString 来解决这个问题:
override this.ToString() = match this with
| A i -> sprintf "A(%d)" i
| B s -> sprintf "B(%s)" s
...这将导致一条好消息:
Expected: B(abc)
But was: A(10)
...但我希望 fsunit 以 (sprintf "%A") 的方式呈现 MyT 值。
无论如何,必须执行这些变通办法是不行的。
如何在不使用数组的情况下为 F# 列表获取有用的消息?
如何获取对ADT有用的消息?
是否有解决上述问题的好办法,还是我应该放弃 FsUnit?
对于没有这些问题的 F# 单元测试库,您有更好的推荐吗?
几个竞争者:
[<Tests>]
let tests =
testList "test group" [
testCase "strings" <| fun _ ->
let subject = "Hello World"
Expect.equal subject "Hello world"
"The strings should be equal"
testCase "lists" <| fun _ ->
let expected = [1; 2]
Expect.equal expected [1; 3]
"The lists should be equal"
testCase "DUs" <| fun _ ->
let expected = A 10
Expect.equal expected (B "abc")
]
输出
[19:29:46 INF] EXPECTO? Running tests...
[19:29:46 ERR] test group/strings failed in 00:00:00.
The strings should be equal.
Expected string to equal:
"Hello world"
↑
The string differs at index 6.
"Hello World"
↑
String does not match at position 6. Expected char: 'w', but got 'W'.
[19:29:46 ERR] test group/lists failed in 00:00:00.
The lists should be equal. Actual value was [1; 2] but had expected it to be [1; 3].
[19:29:46 ERR] test group/DUs failed in 00:00:00.
The DUs should be equal. Actual value was A 10 but had expected it to be B "abc".
[19:29:46 INF] EXPECTO! 3 tests run in 00:00:00.0028417 – 0 passed, 0 ignored, 3 failed, 0 errored. ( ರ Ĺ̯ ರೃ )
val it : int = 1
[<Test>]
let ``The strings should be equal`` () =
let subject = "Hello World"
subject =! "Hello world"
Result Message:
"Hello World" = "Hello world"
false
[<Test>]
let ``The lists should be equal`` () =
let expected = [1; 2]
expected =! [1; 3]
Result Message:
[1; 2] = [1; 3]
false
[<Test>]
let ``The DUs should be equal`` () =
let expected = A 10
expected =! (B "abc")
Result Message:
A 10 = B "abc"
false
Unquote 的好处在于它 Quotations
,允许逐步失败消息。
[<Test>]
let ``The arrays should be equal`` () =
let expected = [|0 ; 2 ; 3 ; 4|]
test <@ (Array.map ((+) 1) [|0 .. 3|]) = expected @>
Result Message:
Array.map ((+) 1) [|0..3|] = [|0; 2; 3; 4|]
Array.map ((+) 1) [|0; 1; 2; 3|] = [|0; 2; 3; 4|]
[|1; 2; 3; 4|] = [|0; 2; 3; 4|]
false
我使用的是 FsUnit 2.3.2,我对失败消息不满意。请参阅以下示例:
[<Test>]
let ``test 1``() =
[1; 3]
|> should equal [1;2]
... 给了我不太有用的信息:
Expected and actual are both Microsoft.FSharp.Collections.FSharpList`1[System.Int32]
at FsUnit.TopLevelOperators.should[a,a](FSharpFunc`2 f, a x, Object y) in d:\GitHub\FsUnit\src\FsUnit.NUnit\FsUnit.fs:line 44 at Program.test 1() in F:\work\playground\fsunit\fsunit\Program.fs:line 9
我发现的解决方法是使用数组而不是列表:
[<Test>]
let ``test 2``() =
[|1; 4|]
|> should equal [|1;2|]
...产生
Expected and actual are both System.Int32[2]
Values differ at index [1]
Expected: 2
But was: 4
第二个问题是我是否定义了 ADT
type MyT =
A of int
| B of string
[<Test>]
let ``test 4``() =
A 10
|> should equal (B "abc")
...给我消息:
Expected: Program+MyT+B
But was: Program+MyT+A
...我可以通过像这样为 MyT 实现 ToString 来解决这个问题:
override this.ToString() = match this with
| A i -> sprintf "A(%d)" i
| B s -> sprintf "B(%s)" s
...这将导致一条好消息:
Expected: B(abc)
But was: A(10)
...但我希望 fsunit 以 (sprintf "%A") 的方式呈现 MyT 值。
无论如何,必须执行这些变通办法是不行的。
如何在不使用数组的情况下为 F# 列表获取有用的消息?
如何获取对ADT有用的消息?
是否有解决上述问题的好办法,还是我应该放弃 FsUnit?
对于没有这些问题的 F# 单元测试库,您有更好的推荐吗?
几个竞争者:
[<Tests>]
let tests =
testList "test group" [
testCase "strings" <| fun _ ->
let subject = "Hello World"
Expect.equal subject "Hello world"
"The strings should be equal"
testCase "lists" <| fun _ ->
let expected = [1; 2]
Expect.equal expected [1; 3]
"The lists should be equal"
testCase "DUs" <| fun _ ->
let expected = A 10
Expect.equal expected (B "abc")
]
输出
[19:29:46 INF] EXPECTO? Running tests... [19:29:46 ERR] test group/strings failed in 00:00:00. The strings should be equal. Expected string to equal: "Hello world" ↑ The string differs at index 6. "Hello World" ↑ String does not match at position 6. Expected char: 'w', but got 'W'. [19:29:46 ERR] test group/lists failed in 00:00:00. The lists should be equal. Actual value was [1; 2] but had expected it to be [1; 3]. [19:29:46 ERR] test group/DUs failed in 00:00:00. The DUs should be equal. Actual value was A 10 but had expected it to be B "abc". [19:29:46 INF] EXPECTO! 3 tests run in 00:00:00.0028417 – 0 passed, 0 ignored, 3 failed, 0 errored. ( ರ Ĺ̯ ರೃ ) val it : int = 1
[<Test>]
let ``The strings should be equal`` () =
let subject = "Hello World"
subject =! "Hello world"
Result Message: "Hello World" = "Hello world" false
[<Test>]
let ``The lists should be equal`` () =
let expected = [1; 2]
expected =! [1; 3]
Result Message: [1; 2] = [1; 3] false
[<Test>]
let ``The DUs should be equal`` () =
let expected = A 10
expected =! (B "abc")
Result Message: A 10 = B "abc" false
Unquote 的好处在于它 Quotations
,允许逐步失败消息。
[<Test>]
let ``The arrays should be equal`` () =
let expected = [|0 ; 2 ; 3 ; 4|]
test <@ (Array.map ((+) 1) [|0 .. 3|]) = expected @>
Result Message: Array.map ((+) 1) [|0..3|] = [|0; 2; 3; 4|] Array.map ((+) 1) [|0; 1; 2; 3|] = [|0; 2; 3; 4|] [|1; 2; 3; 4|] = [|0; 2; 3; 4|] false