2

The following test fails:

open FsCheck
open FsCheck.NUnit
open NUnit.Framework

let ``Property: double negation equals no negation`` list =
    list = List.rev (List.rev list)

[<Test>]
let ``reversing list two times is equal to not reversing list at all`` list = 
    Check.Quick ``Property: double negation equals no negation``

Error:

Message: No arguments were provided

I thought FsCheck would provide the argument for me on each test iteration.

I am referencing the following documentation.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118
  • 1
    Unrelated to this question. The students from McGill are dumping [assignment 4](http://www.cs.mcgill.ca/~prakash/Courses/Comp302/Assignments/Hw4/hw4.pdf) questions here, but they have learned to delete the question after getting an answer. Please be aware of this. – Guy Coder Mar 21 '16 at 14:24
  • What version of NUnit are you using? Nunit 3.x was a major change from 2.x with breaking changes; so much so that I had to spend a day learning how to use it. – Guy Coder Mar 21 '16 at 14:28
  • My unit tests still pass. It's just my attempt at a property-based test that fails. I guess I can mess with the FsCheck.NUnit version. It's currently set to latest, v2.24 – Scott Nimrod Mar 21 '16 at 14:31
  • I tried different versions of FsCheck.NUnit without any success. – Scott Nimrod Mar 21 '16 at 14:33
  • Are you willing to move to NUnit 3.x? If so I will spend some time on it for your question. – Guy Coder Mar 21 '16 at 14:36
  • Thx Guy Coder. At the moment, I just wanted to get something working. – Scott Nimrod Mar 21 '16 at 14:39
  • I know the tag nunit-2.5 is not exactly correct, but there is not NUnit-2.x tag and I didn't want to add one more tag to the already many NUnit-xyz tags. – Guy Coder Mar 21 '16 at 15:13

2 Answers2

5

Here's a version for xUnit.net that sort of works:

open FsCheck
open Xunit

let ``Property: double negation equals no negation`` list =
    list = List.rev (List.rev list)

[<Fact>]
let ``reversing list two times is equal to not reversing list at all`` () = 
    Check.Quick ``Property: double negation equals no negation``

When you use it that way, the first function is the property, and it can take arguments.

The [<Fact>]-annotated function takes no argument.

The problem with that approach is that Check.Quick doesn't cause the test to fail if the property doesn't hold. It only outputs that the property was falsified. If you want the test to fail if the property is falsified, you should use Check.QuickThrowOnFailure:

open FsCheck
open Xunit

let ``Property: double negation equals no negation`` list =
    list = List.rev (List.rev list)

[<Fact>]
let ``reversing list two times is equal to not reversing list at all`` () = 
    Check.QuickThrowOnFailure ``Property: double negation equals no negation``

Another issue is that there's no reason to write this in such a verbose fashion. Here's a more compact way to write the same property:

open FsCheck
open Xunit

[<Fact>]
let ``reversing list two times is equal to not reversing list at all`` () = 
    Check.QuickThrowOnFailure <| fun (l : int list) ->
        l = List.rev (List.rev l)
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Hmmm... I just realized that this specific test type isn't even being discovered. I thought it was resolved because my other unit tests ran and I saw a green bar. – Scott Nimrod Mar 21 '16 at 21:11
  • I guess I need an XUnit test adapter? – Scott Nimrod Mar 21 '16 at 21:12
  • When writing my answer, I deliberately avoided NUnit 2.x, because there are so many problems with it. That said, the test above is just a normal test; you'll notice that I *didn't* import `FsCheck.Xunit`. All examples I've seen of NUnit 2.x tests, though, have test methods in classes, and the class annotated with a `[TestFixture]` attribute. Does NUnit 2.x even work within F# modules? All of this may be better in NUnit 3, but I'm not too familiar with that version. – Mark Seemann Mar 22 '16 at 06:13
1

Mark's answer is great, but just to clarify the NUnit situation.

FsCheck.NUnit provides the PropertyAttribute to adorn test methods that take an argument. It does not hook into the normal NUnit TestAttribute. So in other words your example has a normal NUnit test that takes an argument - NUnit cannot cope with this. Tests that take an argument that you want FsCheck to generate values for look like this:

[<Property>]
let ``Property: double negation equals no negation`` list =
    list = List.rev (List.rev list)

The other option - if you don't want to wrestle with NUnit and FsCheck.NUnit, as Mark says it can be quite brittle mostly due to NUnit 2's quite annoying plugin model - is to not use FsCheck.NUnit at all, and instead use normal NUnit tests. Use QuickCheckThrowOnFailure to signal test failures from FsCheck to NUnit via an exception:

[<Test>]
let ``reversing list two times is equal to not reversing list at all`` () = 
    Check.QuickThrowOnFailure ``Property: double negation equals no negation``

Your example somehow mixed these two options.

Kurt Schelfthout
  • 8,880
  • 1
  • 30
  • 48