当测试类型覆盖ToString时,无法运行TestCaseSource测试

时间:2015-08-14 16:15:19

标签: unit-testing f# nunit fsunit testcasesource

首先,让我在F#中展示测试设置(在NUnit上使用FsUnit):

type SimpleRecord = { A: int; B: int } 
                    override x.ToString() = x.A.ToString()

[<TestFixture>]
type ``Simple Test Cases``() =     
    static member SimpleDataSource =
        [|
            [|{ A = 1; B = 2} ,3|]
        |]

    [<TestCaseSource("SimpleDataSource")>]
    member x.``SimpleTest`` (testData: SimpleRecord * int) =
        let data, expected = testData
        data.A + data.B
        |> should equal expected

此测试将按预期运行并通过。但是,更改ToString覆盖以包含对Guid.ToString()的调用将阻止测试运行:

type SimpleRecord = { A: int; B: int } 
                    override x.ToString() = x.A.ToString() + Guid.NewGuid().ToString()

通过上述更改,测试仍显示在测试资源管理器中,但不会运行。即使右键单击它并选择Run Selected Tests也不会执行测试。没有报告构建错误。

我还尝试使用DateTime.ToString()代替Guid.ToString(),但这也拒绝运行:

type SimpleRecord = { A: int; B: int } 
                    override x.ToString() = x.A.ToString() + DateTime.Now.ToString()

为什么在Guid.ToString()覆盖正在测试的类型中调用DateTime.ToString()ToString导致测试未运行?

1 个答案:

答案 0 :(得分:2)

Charlie Poole解释了根本原因:

  

当使用NUnit控制台或gui跑步者运行测试时,它们是   首先加载(发现)然后执行。在运行时   适配器,测试加载两次,一次在发现阶段和   再次在执行阶段的开始。这是结果   VS测试窗口的工作方式:运行发现和执行   由VS创建的单独进程。

     

在大多数情况下,这不会导致问题。测试已加载   两次,这意味着创建任何测试数据的代码运行两次。   通常,两次都会生成相同的数据。

     

然而,当使用随机数据时,已知不同的数据会   在每个阶段生成。最初显示的测试   当“未知”测试运行时,发现似乎消失了。

     

在您的情况下,guid会生成两次。第一个用作   因此,测试名称的一部分消失了   执行阶段。

以下是演示解决方法的示例:

type ProblemRecord = { A: int; B: int } 
                     override x.ToString() = Guid.NewGuid().ToString()

[<TestFixture>]
type ``Test Cases``() =     
    // Using TestCaseData and explicitly setting a name will resolve the problem
    member x.SolutionDataSource =
        [
            TestCaseData(({ A = 1; B = 2} : ProblemRecord), 3)
                .SetName("Workaround")
        ]

    // This test case will be run by Test Explorer
    [<TestCaseSource("SolutionDataSource")>]
    member x.``SolutionTest`` (data: ProblemRecord, expected: int) =
        data.A + data.B
        |> should equal expected