Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

For some reason when passing arguments to the test via TestCase attrubute, I get the following error message about the first argument, which in this case is an array:

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)

But when removing the last argument, from both the attribute and the method itself, it all works just fine.

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

What am I doing wrong? Preferably I would also define a tuple of int * int but it doesn't seem to work either.

like image 322
Nikita Ignatov Avatar asked Jan 18 '15 16:01

Nikita Ignatov


People also ask

What are parameterized tests?

Test parameterization is a type of data-driven testing that allows you to execute the same test, multiple times using different parameters. Xray Cloud has a parameterized tests feature, that executes the same test with different input values, multiple times, without ever having to clone or replicate it.

How do you do parameterized test cases?

There are five steps that you need to follow to create a parameterized test. Annotate test class with @RunWith(Parameterized. class). Create a public static method annotated with @Parameters that returns a Collection of Objects (as Array) as test data set.

What are parameterized tests used for in a unit?

One such feature is parameterized tests. This feature enables us to execute a single test method multiple times with different parameters.

What is parameterized test in JUnit 5?

Some times we may need to run same tests with different arguments or values, Junit 5 Jupiter Parameterized tests makes it possible to run a test multiple times with different arguments. They are declared just like regular @Test methods but use the @ParameterizedTest annotation instead of @Test annotation.


1 Answers

CLI has a restriction regarding kinds of attribute parameters:

  • primitive: bool, int, float, etc
  • enums
  • strings
  • type references: System.Type
  • 'kinda objects': boxed (if needed) representation of types from above
  • one dimensional array of one of types from above (ie. no nested arrays allowed)

So we can conclude at this point that you can not use tuple as an attribute parameter's type.

From here starts my speculations, so none of below can be true.

I played a bit with different attributes and found that F# compiler starts complain about an every array parameter, when attribute has variable number of arguments (params). For example, if I define the following attribute

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

and try to use it from F# code, I'll get an error:

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

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

I guess the compiler can consider params arguments as an array and therefore does not allow to define 'nested' array in it. But as I said, it is a pure speculation.

like image 64
ie. Avatar answered Sep 28 '22 09:09

ie.