5

我是 F# 的新手,我正在玩 FParsec。我会使用 FParsec 来生成 AST。我想使用 FsUnit 围绕解析器的各个部分编写一些测试,以确保正确运行。

我在语法上遇到了一些问题(抱歉,确切的代码正在工作,我可以稍后发布一个具体示例)那么究竟如何比较两个有区别的联合(一个是预期的,另一个是实际结果)?有人可以提供一个使用 FsUnit(或 NUnit)的小代码示例吗?

判别联合的例子(很简单)

type AST = 
    | Variable of string
    | Class of string
    | Number of int
4

2 回答 2

6

正如 Brian 指出的那样,由于 F# 联合具有结构平等,因此使用您喜欢的任何单元测试框架都很容易。

FsUnit 是构建在 NUnit 之上的 F# 特定库。我个人最喜欢的 F# 特定单元测试库是Unquote,;),它与框架无关,可以很好地与 NUnit、xUnit.net、MbUnit……甚至在 FSI 中工作。您可能会对与 FsUnit 的比较感兴趣

那么,你将如何使用 NUnit + Unquote 做到这一点?这是一个完整的工作示例:

module UnitTests

open NUnit.Framework
open Swensen.Unquote

type AST = 
    | Variable of string
    | Class of string
    | Number of int

let mockFParsec_parseVariable input = Variable(input)

[<Test>]
let ``test variable parse, passing example`` () =
    test <@ mockFParsec_parseVariable "x" = Variable("x") @>

[<Test>]
let ``test variable parse, failing example`` () =
    test <@ mockFParsec_parseVariable "y" = Variable("x") @>

然后使用 TestDriven.NET 运行测试,输出如下:

------ Test started: Assembly: xxx.exe ------

Test 'UnitTests.test variable parse, failing example' failed: 

UnitTests.mockFParsec_parseVariable "y" = Variable("x")
Variable "y" = Variable("x")
false
    C:\xxx\UnitTests.fs(19,0): at UnitTests.test variable parse, failing example()

1 passed, 1 failed, 0 skipped, took 0.80 seconds (NUnit 2.5.10).
于 2011-09-15T03:02:21.237 回答
2

一个例子 - 如果你想检查类型而不是内容

let matched x= 
    match x with
    |Variable(_) -> true
    | _ -> false

请注意,您需要为可区分联合的每个元素使用不同的函数

如果你想比较平等,你可以用标准的方式来做,比如

Assert.AreEqual(Variable("hello"),result)

或者

if result = Variable("hello") then stuff()
于 2011-09-15T00:02:24.853 回答