f# 中的参数化测试 - 这不是有效的常量表达式

Parameterized tests in f# - This is not a valid constant expression

出于某种原因,当通过 TestCase 属性将参数传递给测试时,我收到以下关于第一个参数的错误消息,在本例中是一个数组:

This is not a valid constant expression or custom attribute value

module GameLogicTest = 
    open FsUnit
    open NUnit.Framework
    open GameLogic.Examle

    // This is not a valid constant expression or custom attribute value
    [<TestCase( [| 1; 2; 3 |], 3, 1,1)>]
    let ``let example.`` (a, m, h, c) = 
        a
        |> proof1 m
        |> should equal (h,c)

但是当从属性和方法本身中删除最后一个参数时,一切正常。

[<TestCase( [| 1; 2; 3 |], 3, 1)>]
let ``let example.`` (a, m, h) = 
    a
    |> proof1 m
    |> should equal (h,1)

我做错了什么?最好我也定义一个 int * int 的元组,但它似乎也不起作用。

CLI 对属性参数的种类有限制:

  • 原始类型:bool、int、float 等
  • 枚举
  • 字符串
  • 类型引用:System.Type
  • 'kinda objects':上述类型的盒装(如果需要)表示
  • 上述类型之一的一维数组(即不允许嵌套数组)

因此我们可以在这一点上得出结论,您不能将元组用作属性参数的类型。

从这里开始我的推测,所以下面的none可能是正确的。

我尝试了一些不同的属性,发现当属性具有可变数量的参数 (params) 时,F# 编译器开始抱怨每个数组参数。例如,如果我定义以下属性

public class ParamsAttribute : Attribute
{
    public ParamsAttribute(params object[] parameters)
    {}
}

并尝试在 F# 代码中使用它,我会得到一个错误:

[<Params(1, 2, 3)>] // here everything is OK
let x () = ()

[<Params([|1; 2; 3|])>] // the same error as you have
let y () = ()

我想编译器可以将 params 参数视为一个数组,因此不允许在其中定义 'nested' 数组。但正如我所说,这纯属猜测。

使用字符串参数代替数组参数。将所有术语连接到字符串中并传入。 使用String.Split将字符串参数转换为字符串数组 然后使用 Array.map 转换为选择的数组。

[<TestCase([|1, 2, 3|], 4, 5, 6)>]
let ``My Test``(param1: int[], param2: int, param3: int, param4: int) =
    // My test code

变成

[<TestCase("1|2|3", 4, 5, 6)>]
let ``My Test``(param1: string, param2: int, param3: int, param4: int) =
    let stringArray = param1.Split('|', SplitStringOptions.None)
    let intArray = Array.map int stringArray

    // My test code