Git Product home page Git Product logo

fscheck's Introduction

What is FsCheck?

FsCheck is a tool for testing .NET programs automatically. The programmer provides a specification of the program, in the form of properties that functions, methods or objects should satisfy, and FsCheck then tests that the properties hold in a large number of randomly generated cases. While writing the properties, you are writing a testable specification of your program. Specifications are expressed in F#, C# or VB, using combinators defined in the FsCheck library. FsCheck provides combinators to define properties, observe the distribution of test data, and define test data generators. When a property fails, FsCheck automatically displays a minimal counter-example.

FsCheck is a port of Haskell's QuickCheck. Important parts of the manual for using FsCheck are almost literally adapted from the QuickCheck manual. Any errors and omissions are entirely my responsibility.

Since v0.5, scalacheck has influenced FsCheck as well. Scalacheck is itself a port of QuickCheck to Scala.

FsCheck's generator combinators can be used in any testing framework to easily generate random values for many types, and FsCheck itself integrates nicely with existing unit testing frameworks such as NUnit, xUnit, MSTest and MbUnit.

Releases on Nuget

FsCheck follows Semantic Versioning 2.0.0, except for the API exposed in FsCheck.Experimental which is subject to change at any time.

All AppVeyor builds are available using the NuGet feed: https://ci.appveyor.com/nuget/fscheck

If using Paket, add the source at the top of paket.dependencies.

source https://www.nuget.org/api/v2
source https://ci.appveyor.com/nuget/fscheck

See the build history for a list of available versions: https://ci.appveyor.com/project/kurtschelfthout/fscheck/history

Here are some options for specifying the dependency:

nuget FsCheck
nuget FsCheck prerelease
nuget FsCheck 2.0.4
nuget FsCheck 2.0.5-b247

Documentation

Contributing

Pull requests are very welcome!

Check out the issues marked "good first issue" and "help wanted" if you need any inspiration.

We rarely reject PRs. If you intend to make a bigger change, it's better to open an issue first to discuss.

Development

FsCheck uses standard .NET package management via NuGet and is built, tested and packaged via typical usage of dotnet.

To get started, check out the repository and run dotnet build to build. Use dotnet test .\tests\FsCheck.Test\ to run the tests. If that passes after you've changed some code, you are ready to send a Pull Request!

For Visual Studio/MonoDevelop/Xamarin Studio/VsCode: open (the folder that contains) FsCheck.sln and start coding. Building and running tests in IDEs should work out of the box.

FsCheck uses a build script inspired by FAKE. Run build.[cmd|sh] -t <Target> (or dotnet fsi build.fsx -t <Target>) to do something. Important targets are:

  • Build: cleanly builds in Release mode.
  • Tests: builds and runs the tests.
  • Docs: builds and generates documentation. FsCheck uses FSharp.Formatting, so literate fsx files in the docs folder.
  • WatchDocs: convenient when developing documentation - starts a local webserver and watches for changes in the docs folder.
  • NuGetPack: Creates NuGet packages.
  • CI: Target that is run on AppVeyor, basically all of the above.

CI

AppVeyor Build status

fscheck's People

Contributors

adj123 avatar alex-bogomaz avatar andrea avatar carstenkoenig avatar dungpa avatar enricosada avatar erikschierboom avatar farlee2121 avatar forki avatar gab-km avatar giacomociti avatar jack-pappas avatar jackfoxy avatar jhamm avatar kharacternyk avatar kos59125 avatar kurtschelfthout avatar mausch avatar moodmosaic avatar mrakgr avatar mrange avatar mstyura avatar pblasucci avatar ploeh avatar rattenkrieg avatar ronnieholm avatar sideeffffect avatar silviomarcovic avatar smaug123 avatar stijnmoreels avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fscheck's Issues

Registering Arbitrary instances for type abbreviations is ignored before the first running Check.Quick*

I am using a type abbreviation for an existing type like following:

type Money = int

Then, I define a default generator and shrinker for the type abbreviation, and register arbitrary instances:

let money =  Gen.oneof [
                        Gen.choose(0, 1); Gen.choose(2, 4); Gen.choose(5, 9)
                        Gen.choose(10, 49); Gen.choose(50, 99); Gen.choose(100, 499)
                        Gen.choose(500, 999); Gen.choose(1000, 1999)
                        Gen.choose(2000, 4999); Gen.choose(5000, 9999)
                        ]
type MoneyGenerators =
    static member Money() =
        { new Arbitrary<Money>() with
            override self.Generator = money
            override self.Shrinker = Seq.empty
        }
Arb.register<MoneyGenerators>() |> ignore

I define a property which is expected to succeed:

let moneyProp (m: Money) =
    0 <= m && m < 10000

and run Check.Quick <property>, but my test fails:

> Check.Quick moneyProp;;
Falsifiable, after 5 tests (1 shrink) (StdGen (229455208,295898168)):
-1
val it : unit = ()

-1 is not the input I expected. I think Arb.register<MoneyGenerators>() is just ignored.
Registering again makes the test succeed.

I found that registering arbitraries doesn't perform before running Check.Quick or Check.QuickAll just once.

Does the behaviour work as required?

Location of tooling projects [ was: Move to fsprojects? ]

Hi @kurtschelfthout

With the FSSF becoming legally established, it probably makes sense to have http://github.com/fsharp be very strictly only those repositories related to points 1 and 2 of the mission statement of the FSSF - e.g. fsharp/fsharp, fsharp/FSharp.Compiler.Service, the editor bindings and so on.

As a result, would it be ok to move this repository to http://github.com/fsprojects? There are some highly respected and successful projects in that collection now, so you'd be amongst good company :)

There's a related discussion here: fsharp/fsharp.github.io#19

Please let us know what you think.

Thanks
Don

Examples of using NonNull<_>

I cannot figure out how to use the NonNull<'t> and Arb.Default.NonNull<'t> added in #31. I rewrote

(Arb.from<string> |> Arb.filter (fun s -> s <> null)).Generator

as

(Arb.Default.NonNull<string>() |> Arb.convert (fun (NonNull s) -> s) NonNull).Generator

but it did not make it more readable or clear. Am I doing it wrong? Examples would be helpful, but I could not find any.

Revamp C#/VB.NET API

This is a spin off of issue #61. I've gathered my thoughts on what I think is wrong with the existing C# API and what I'd like to see changed. This issue is very much up for grabs, but I would be very supportive of anyone tackling this project; unfortunately I will not be doing this myself.

I think the idea of having a fluent API for generator building (and a little integration with LINQ) is sound. I am a little bit less sure about the same approach for properties. But haven't really thought it through.

Overall this API could at least use some maintenance and spring cleaning. It is still mostly in the same state since I first committed it.

Some things that bother me:

  • the names of functions in both APIs are completely different. I mostly use the F# API, occassionally using the C# API. I get confused. (and I'm the author of this thing, so I'm not surprised folks are complaining). There is little reason for this; they should be harmonized.
  • The C# API pre-dates the major refactoring of the F# API; there is no concept of Arbitrary for example. This can be limiting.
  • There are no tests or documentation, hence bugs. E.g. see #5.
  • It is not complete; some things like the model based checking for example I haven't tried to do from C#. May be possible but likely there is some ugliness.
  • I don't think the integration with Xunit and NUnit works that well; again the API predates that integration so I think you probably have to jump through some hoops. It should just run any method that returns a Spec, I suppose, although without type inference that makes the return type look a bit ugly.
  • If we keep the Spec approach, we should have some code generation so we can generate the thing for higher arities.

Overall, I would like the whole thing revamped and think it's worth breaking all users of the C# API to do the revamp. I would very much appreciate a dedicated volunteer to work on this with me.

not building on mono

Hi,
the nuget package does not run on (my) mono/linux install as it is right now (some issues with missing Attribute classes or something).

I was able to build it from source to but as it is right now - I had to remove several projects from the solution (everything msbuild for example) and had to "steal" some scripts and initial files for FAKE from the FAKE repo here.

If you like I could try to give you a pull-request for a mono branch - this would include a special nuget-package for mono I guess.

In case you want to know: this is the exception you get when trying to run the current nuget-version with mono-3.4.0:

Missing method .ctor in assembly (path-to-app)/bin/Debug/FsCheck.dll, type Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute
Can't find custom attr constructor image: (path-to-app)/bin/Debug/FsCheck.dll mtoken: 0x0a000001
* Assertion at class.c:5600, condition `!mono_loader_get_last_error ()' not met

Limitation of ICommand model-based checking

Learning from the example of @kurtschelfthout for model-based testing of Deque<'T>, I moved forward to implement this approach using model-based checking for testing Vector<Vector<'T>> (see https://github.com/fsharp/fsharpx/blob/master/tests/FSharpx.Collections.Tests/VectorTest.fs). However using this approach I found 2 limitations of ICommand model-based checking.

First issue:

Using Vector<'T> (or any other 1-dimensional linear structure) to model Vector<Vector<'T>> I could only manipulate the last inner Vector<'T> of actual because otherwise there is not enough information available in RunModel to keep the model in sync. The solution is to make the parameter to RunModel a tuple of actual and model, so any information available to RunActual is also available to RunModel.

Second issue:

...and this is also an issue in the Deque<'T> test example. Failing a test of multiple invariants during the Post phase provides no information on which invariant failed. The solution is for Post to emit a Property instead of a bool.

The Solution:

All of this of course would be a breaking change to Commands, so I created a new module, Transitions. (Maybe you can think of a better name. I tried to avoid a name with "state" in it.) My proposed addition to FsCheck functionality can be found in the "foxy" branch at https://github.com/jackfoxy/FsCheck/tree/foxy.

Demonstration:

https://github.com/jackfoxy/TestSandbox project FsCheckVectorTest is essentially my original Vector<Vector<'T>> test from FSharpx, and uses the current release of FsCheck. The project ExperimentalVectorTest requires the "foxy" branch, with the generators "appendInnerMulti" and "shrinkInner" modified to operate on a random inner Vector<'T> rather than only operate on the last populated inner Vector<'T>. (Sorry, TestSandbox will not build "out of the box" but requires manual wiring to the "foxy" branch.)

Comment:

I was at first surprised, but I see now Vector<Vector<'T>> (allowing a jagged Vector) provides a useful higher dimension of complexity for purposes of developing a testing system. Providing full information in all the ITransition member bindings through (actual, model) allows FsCheck to generate more complex test scenarios. And returning failure information from multi-invariant Post makes each Transition more efficient in that we can efficiently test multiple invariants in each generation, and each generation can do a more complex manipulation to both actual and model.

Update reference docs

The reference docs as they are are pretty reasonable, most functions have been documented. Most types have not however, so this could definitely use a review and an update.

Support NUnit 3

Currrently NUnit v3 is in Beta. I have the updates to support it in the my branch jhamm/FsCheck in the support-nunit3 branch.

The FsCheck.NUnit.Addins project was not needed to support NUnit 3, so I removed it.

The branch is not ready to be merged into the main branch because it is still in beta and not all of the related projects, like NUnit.Runners, support NUnit 3 yet. For testing, I built and changed the references to pointed the references to the local copies of the dll's.

Implement "discard"

QuickCheck has (since 2.7) a data type Discard that forces the test case to be discarded when the property returns it. This is useful because as the hackage doc says "Normally you should use ==>, but if for some reason this isn't possible (e.g. you are deep inside a generator), use discard instead.".

QuickCheck has both a Testable Discard instance and a discard function that throws an exception.

Now, FsCheck already has a Testable instance for Result, which seems like it would cover this in principle, but returning a Result is atypical and seems rather cumbersome unless there are some simplified constructors that I'm missing.

Also Testables are restricted in C# to unit and boolean AFAICT, but I guess that should be addressed in #63 .

In summary: what do you think would be the best way to implement this?

Opaque error message?

Trying to use FsCheck with this code:

  let [<Fact>] ``serialising any`` () =
    let CanSerialiseAnyUnion (a : A) =
      let serialised = JsonConvert.SerializeObject(a, Formatting.Indented, List.toArray converters)
      let deserialised = JsonConvert.DeserializeObject(serialised, List.toArray converters)
      deserialised = a
    FsCheck.Check.Quick CanSerialiseAnyUnion

Where A is a discriminated union.

And I'm getting a strange error message:

Intelliplan.JsonNet.Tests.UnionConverterTests.serialising any [FAIL]
   System.InvalidCastException : Unable to cast object of type 'Arrow@204-2[Intelliplan.JsonNet.Tests.UnionConverterTests+A,System.Boolean]' to type 'Testable`1[Microsoft.FSharp.Core.FSharpFunc`2[Intelliplan.JsonNet.Tests.UnionConverterTests+A,System.Boolean]]'.
   Stack Trace:
      at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)
      at FsCheck.Runner.check[a](Config config, a p)

Can you help me interpret it?

NUnit does not shink test data

Hi,

I'm using FsCheck 2.0.0 with FsCheck.NUnit 2.0.0, C# API.

No matter what I do, the data is not shrunk.

Simple example:

[FsCheck.NUnit.Property]
public void Prop()
{
    Spec.ForAny((List<int> list) => Assert.Less(list.Sum(), 20))
        .QuickCheckThrowOnFailure();
}

Running this in VS gives the following:

System.Exception : Falsifiable, after 25 tests (0 shrinks) (StdGen (1661770773,296011564)):
seq [-4; -1; -20; -10; ...]

The example might not be so great, but I have double-checked that this happens every time even if there is a possibility to falsify property with a sublist.
This also happens with types for which I have provided my own Shrink implementation.

I'm quite new to the library and would be glad to hear if I'm just missing something :)

Purpose of 'size' parameter in Gen.sample

These examples produce similar results, even though size is completely different on each example:

let sample' = sample 0 11 // Size = 0
let actual = sample' <| choose (0, 9)

Results to:

Length = 11
    [0]: 4
    [1]: 0
    [2]: 4
    [3]: 0
    [4]: 3
    [5]: 9
    [6]: 3
    [7]: 9
    [8]: 2
    [9]: 8
    [10]: 2
let sample' = sample 1000 11 // Size = 1000
let actual = sample' <| choose (0, 9)

Results to something similar:

Length = 11
    [0]: 8
    [1]: 6
    [2]: 2
    [3]: 3
    [4]: 7
    [5]: 3
    [6]: 1
    [7]: 2
    [8]: 6
    [9]: 2
    [10]: 0

Given that sample is currently defined as below, is it really necessary to parameterize the size?

[<CompiledName("Sample")>]
let sample size n gn  = 
    let rec sample i seed samples =
        if i = 0 then samples
        else sample (i-1) (Random.stdSplit seed |> snd) (eval size seed gn :: samples)
    sample n (Random.newSeed()) []

Arbitrary<Culture> shrink sometimes fails on appveyor

FsCheck.Test.Arbitrary.Culture shrinks [FAIL]
Falsifiable, after 66 tests (0 shrinks) (StdGen (959882488,295868421)):
ca-ES-valencia

Unfortunately can't reproduce because I don't have the culture locally, should probably try to install that culture then try.

Bit odd though. @mausch is this something you've seen before?

Support for running async tests in parallel?

I would like to test timing properties of concurrent code. The tests take very little CPU time, but lots of wall-clock time if you run them sequentially. The tests are such that it should be possible to run tens of thousands of testsโ€”several orders of magnitude more than the number of coresโ€”in parallel without problems. Have there been attempts to allow FsCheck to run async tests in parallel?

Use Paket for internal dependencies management

Paket is a tool that works on top of nuget that AFAIU

  • manages internal packages. If two packages reference conflicting versions of a package, NuGet will silently take the latest version (read more). You have no control over this process.
  • faster because it caches packages
  • can download from github
  • can use files from github ( a la Simple.Json)
  • easy to see dependecies

At the moment may not be a pain point but I like that it's faster and the fact that you wouldn't have multiple versions of the same project hanging around in your dependencies .

I am sure there is more that I just don't know, maybe @forki can add to this :D

Japanese documentation has some bugs

FsCheck Japanese documentation is released, but some user found bugs for the documentation.

ex)

  • the "API references" link in index.html is broken.
  • all output of snipets in Japanese documentations shows "No output has been produced."

Docs - Translation to spanish

Hi there

As I mentioned in commit a9575a5 I have started a translation of the docs to spanish.
I am a little confused about the FSharp.Formating usage, I had a look at docs/content and I only see the English version in the fsx files, and the japanese at the root of /docs. So basically I have not idea where to put the spanish files :D
Also I assume that I should create files with formatting similar to the fsx files inside /docs/content right?

Cheers

Nuget v0.9.4 throws TypeInitializationException where 0.9.3 does not

To reproduce:

  1. use git to checkout v0.9.4 tag.
  2. open solution in Visual Studio
  3. open FsCheck.CSharpExamples
  4. remove the project reference to FsCheck
  5. run Install-Package FsCheck -Version 0.9.4.0
  6. Run the console application

Note the error as included below

Test the regression

  1. run Uninstall-Package FsCheck
  2. run Install-Package FsCheck -Version 0.9.3.0
  3. Run the console application, and all works.

Exception included

System.TypeInitializationException was unhandled
  HResult=-2146233036
  Message=The type initializer for 'FsCheck.Fluent.Spec' threw an exception.
  Source=FsCheck
  TypeName=FsCheck.Fluent.Spec
  StackTrace:
       at FsCheck.Fluent.Spec.ForAny[a](Func`2 assertion)
       at FsCheck.CSharpExamples.Program.Main(String[] args) in \\psf\home\src\EchoX\FsCheck\FsCheck.CSharpExamples\Program.cs:line 54
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.TypeInitializationException
       HResult=-2146233036
       Message=The type initializer for '<StartupCode$FsCheck>.$Fluent' threw an exception.
       Source=FsCheck
       TypeName=<StartupCode$FsCheck>.$Fluent
       StackTrace:
            at FsCheck.Fluent.Spec..cctor()
       InnerException: System.TypeInitializationException
            HResult=-2146233036
            Message=The type initializer for '<StartupCode$FsCheck>.$Runner' threw an exception.
            Source=FsCheck
            TypeName=<StartupCode$FsCheck>.$Runner
            StackTrace:
                 at FsCheck.Runner.get_init()
                 at <StartupCode$FsCheck>.$Fluent..cctor()
            InnerException: System.IO.FileNotFoundException
                 HResult=-2147024894
                 Message=Could not load file or assembly 'FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
                 Source=FsCheck
                 FileName=FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
                 FusionLog==== Pre-bind state information ===
LOG: DisplayName = FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 (Fully-specified)
LOG: Appbase = file://psf/Home/src/EchoX/FsCheck/FsCheck.CSharpExamples/bin/Release/
LOG: Initial PrivatePath = NULL
Calling assembly : FsCheck, Version=0.9.4.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: \\psf\Home\src\EchoX\FsCheck\FsCheck.CSharpExamples\bin\Release\FsCheck.CSharpExamples.vshost.exe.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: Attempting download of new URL file://psf/Home/src/EchoX/FsCheck/FsCheck.CSharpExamples/bin/Release/FSharp.Core.DLL.
LOG: Attempting download of new URL file://psf/Home/src/EchoX/FsCheck/FsCheck.CSharpExamples/bin/Release/FSharp.Core/FSharp.Core.DLL.
LOG: Attempting download of new URL file://psf/Home/src/EchoX/FsCheck/FsCheck.CSharpExamples/bin/Release/FSharp.Core.EXE.
LOG: Attempting download of new URL file://psf/Home/src/EchoX/FsCheck/FsCheck.CSharpExamples/bin/Release/FSharp.Core/FSharp.Core.EXE.

                 StackTrace:
                      at <StartupCode$FsCheck>.$Runner..cctor()
                 InnerException: 

Convert Japanese documentation to FSharp.Formatting

cc @Gab-km @kos59125 (not sure you have the time...)

It would be awesome if the existing translation could be updated to use FSharp.Formatting, like I just did for the English translation. If you're interested, let's use this to discuss how to organize that.

My suggestion would be to create subfolders in a docs/content, say

docs/content/en
docs/content/ja

Each containing the index.fsx and all the other files in that language.

Some points to discuss:

  • You guys are probably more experienced with an organisation that works well, so definitely make a counter-proposal if you think this won't work.
  • I am going to make a couple of changes to the documentation #34. Probably this can wait until after I've done that, we can agree on the setup first.

Update documentation

Now we have the shiny new FSharp.Formatting docs, it's time for a long overdue spring cleaning.

  • Quick Start definitely needs to be improved - emphasize the different ways of running tests (FsCheck standalone or xunit, or NUnit if it gets released, or just Check.QuickThrowOnFailure if all else fails)
  • Properties again could use some examples with existing test frameworks
  • Test Data is probably alright. Maybe more docs about Arb.
  • StatefulTesting could use some expansion, but not so urgent
  • TipsAndTricks definitely needs cleanup.

I'd also like to add references to other projects related to FsCheck on the homepage (Fuchu, AutoFixture).

Documentation not available in C# and/or VB.net

Though the documentation indicates it should be possible to write specifications in C# and/or VB, all documentation assumes F# throughout, making it difficult to work with for people with little or no experience with F#.

Arb.generate throws in interactive till any check is run

when playing with FsCheck in interactive, just after opening the FsCheck module, call to Arb.generate<string> throws "System.Exception: No instances of class FsCheck.Arbitrary1[a] for type System.String with arguments set []". After calling Check.Quickfor any property,Arb.generate` works fine.

License question

I'd like to port this lib to Microsoft Dynamics NAV (in C/AL) and I'm unsure if the license allows this. I think it would be for internal use in our company and maybe open sourced later. We currently have no intentions to sell it.

Gen<a> should be Covariant

Hello!

I just absolutely love this library, thank you SO much for providing it.

Is it possible to make Gen covariant? I want to build up more general generators from smaller pieces. In my specific case, that involves having a generator for each class which derives from Event, and then an EventGenerator defined as Any.GeneratorIn(smaller generators). I can't do this right now because Gen can't be assigned to type Gen. Is there some technical limitation to making the Gen covariant on its type parameter?

Release NUnit addin (even though it doesn't work with VS Adapter due to NUnit bug)

This is a summary of what is discussed here:

The FsCheck.NUnit.Addin currently does not work with the NUnit VIsual Studio test adapter. It works fine with the standalone NUnit runner, although the addin does not show up in the addin window (this is expected in NUnit if the addin is built using .NET 3.5).

@CarstenKoenig put in a workaround to make the FsCheck NUnit examples work, as well as some documentation (https://github.com/fsharp/FsCheck/blob/master/Docs/Documentation.md#temporary-fix-to-get-the-nunit-addin-working-for-your-test) . This workaround however involves adding the addin classes to the test project itself, which is not maintainable (and besides, it's easier to add an NUnit custom runner, or use Quick.ThrowOnFailure in these cases).

Pending a fix in NUNit for this bug (it's reported), or a better addin story in NUnit 3.0, we are not releasing a NuGet package for FsCheck.NUnit.

`True` conflict when both FsUnit and FsCheck are open

Not sure if this is something that can or should be fixed, but these 2 frameworks are likely to be used together in testing F# code, so it may make sense to think out a fix.

In this code piece

open FsUnit (* 1 *)
open FsCheck (* 2 *)
open NUnit.Framework

[<Test>]
let ``Minimal abstract grammar`` () =
   false |> should be True

True is construed as a True constructor of the FsCheck.Outcome union type. A workaround is to swap the two open directives (1) and (2), but I am not sure how far this would get me. But writing something like

   r.Export |> should be (FsUnit.TopLevelOperators.True)

indeed goes against the grain of FsUnit.

F# 3.0 compatibility?

Hey guys,

I tried using this DLL on a project where I currently can't use F# 3.1 but 3.0.
I get exceptions in Check.Quick with an as simple function as fun () -> true.

It disappeared when targeting F# 3.1.
Is that expected?

Thanks
Denis

Exceptions when writing AST generators: "Geneflect: type not handled Microsoft.FSharp.Compiler.Range+range"

I'm experimenting with generating F# compiler ASTs in order to test compiler tools. I'm hitting the following exception:

Fantomas.Tests.FormattingPropertyTests.running formatting ASTs twice should produce the same results: System.Exception : Geneflect: type not handled Microsoft.FSharp.Compiler.Range+range

Stacktrace:

at [email protected](String message) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 102
at FsCheck.Common.f@1[a,b](IDictionary2 memo, FSharpFunc2 f, a n, Unit _arg1) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Common.fs:line 24
at FsCheck.Common.memoizeWith[a,b](IDictionary2 memo, FSharpFunc2 f, a n) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Common.fs:line 19
at FsCheck.ReflectArbitrary.reflectGen[a](FSharpFunc2 getGenerator) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 107 at FsCheck.Arbitrary1.FsCheck-IArbitrary-get_GeneratorObj() in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 42
at [email protected](IEnumerable1& next) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 96 at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl()
at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable1 source) at FsCheck.ReflectArbitrary.reflectObj$cont@50(FSharpFunc2 getGenerator, FSharpFunc2 containedTypes, Type t, Unit unitVar) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 93 at FsCheck.Common.f@1[a,b](IDictionary2 memo, FSharpFunc2 f, a n, Unit _arg1) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Common.fs:line 24 at FsCheck.Common.memoizeWith[a,b](IDictionary2 memo, FSharpFunc2 f, a n) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Common.fs:line 19 at FsCheck.ReflectArbitrary.reflectGen[a](FSharpFunc2 getGenerator) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 107
at FsCheck.Arbitrary1.FsCheck-IArbitrary-get_GeneratorObj() in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 42 at [email protected](IEnumerable1& next) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 66
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl() at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable1 source)
at FsCheck.ReflectArbitrary.productGen@65(FSharpFunc2 getGenerator, FSharpList1 ts) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 66
at FsCheck.ReflectArbitrary.unionGen@64[a](FSharpFunc2 getGenerator, FSharpFunc2 create, FSharpList1 ts) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 69 at System.Lazy1.CreateValue()
at System.Lazy1.LazyInitValue() at [email protected](IEnumerable1& next) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 75
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl() at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable1 source)
at [email protected](Int32 size) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\ReflectArbitrary.fs:line 78
at [email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 106
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at FsCheck.Gen.go@193[b](FSharpList1 gs, FSharpList1 acc, Int32 size, StdGen r0) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 198
at [email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 200
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at FsCheck.Gen.go@193[b](FSharpList1 gs, FSharpList1 acc, Int32 size, StdGen r0) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 198
at [email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 200
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at <StartupCode$FsCheck>.$[email protected](Int32 n, StdGen r) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 23
at [email protected](Int32 n, StdGen r0) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Gen.fs:line 52
at [email protected](IEnumerable1& next) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Runner.fs:line 110 at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl()
at Microsoft.FSharp.Collections.SeqModule.TakeWhile@1483.GenerateNext(IEnumerable1& next) at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl()
at Microsoft.FSharp.Collections.SeqModule.Fold[T,TState](FSharpFunc2 folder, TState state, IEnumerable1 source)
at FsCheck.Runner.runner[a](Config config, a prop) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Runner.fs:line 157
at FsCheck.Runner.check[a](Config config, a p) in C:\Users\Kurt\Projects\FsCheck\fsharp\src\FsCheck\Runner.fs:line 264
at Fantomas.Tests.FormattingPropertyTests.running formatting ASTs twice should produce the same results() in C:\Users\s094745\Documents\GitHub\fantomas\src\Fantomas.Tests\FormattingPropertyTests.fs:line 80

FYI, range is a struct type defined at https://github.com/fsharp/FSharp.Compiler.Service/blob/f3e5a7cc181e921115e91944ad17d9cc54cefb6f/src/fsharp/range.fs#L144.

The code snippet can be found at https://github.com/dungpa/fantomas/blob/fbd1b0efeb977f050fb82f128b8f969f5061702e/src/Fantomas.Tests/FormattingPropertyTests.fs#L12-L80.

I'm new to FsCheck generators so I might make some mistakes. I appreciate any help in resolving this.

If you would like to reproduce the issue, I put up the tests at https://github.com/dungpa/fantomas/tree/fscheck-bug branch.

I have a strange issue with the current XUnit Testrunner for VS - most likely no FsCheck bug

using this simple (failing) property:

let ``should fail with property throwing exception``(p : PositiveInt) =
    let willFail _ = failwith "failing on purpose"
    willFail p.Get = p.Get

will throw a TargetInvocationException due to a NullReferenceException in Xunit.Sdk.ExecutorCallback in the runtime - you will see it, when you look at ouput/test - the test itself will just hang the VS-testrunner :( .

I tried to debug this but it does not seem to be a problem with FsChecks code (everything works as expected and there is no null in the result of the TestCommand implementation).

Any thoughts on that?
Shall I try to report this bug to the Xunit-plugin guys?

Create strong named packages

In dotnet/fsharp#361 we need a strong named package. I wonder if FsCheck could strong name all its packages with an open key just to work around this.
It should be doable during the build / release process.

xUnit integration: Automatically discover Arbitraries from parameter types

In my C# land of doom, I find myself following this pattern rather frequently: have my tests accept a data structure as "input", and have that data structure come with its own generator (see code sample below).

To do this, I have to always specify PropertyAttribute.Arbitrary with C#'s clunky array + typeof syntax, which gets annoying. And it gets even more annoying when I start reusing these data structures in multiple tests.

At the same time, it's relatively easy to just have the PropertyAttribute automatically pick up types of method parameters and treat them as if they were added to PropertyAttribute.Arbitrary.

I have a working solution (complete with a unit test) which I can push, provided you consider this new addition worthy. Let me know.

[Property( Arbitrary = new[] { typeof(Args) } )]
public void Sould_do_awesome_things( Args args ) {
   ...
}

class Args {
   public int X;
   public string Y;

   public static Arbitrary<Args> GenArgs() {
      return (
         from x in Gen.Choose( 42, 1024 )
         from y in Arb.Generate<string>()
         select new Args { X = x, Y = y } )
         .ToArbitrary();
   }
}

P.S. It would be nice to have FsCheck derive the whole Args for me, same way it does for F# native structures, but that's a story for next time.

Any with Where extension

found another issue with using Any.ofType together with .Where to create a generator for Spec.Any:

let's say I use ofType with where to filter for even number - this is no issue.
But when the check fails the default shrinker will kick in running me into a unevennumber that in most cases of course will fail to (I wanted only evens for some reason) - so after all the testoutput will give me a meaningless uneven sample

I do not know how to fix this other then giving Spec.Any an arbitrary instance instead of a generator or just using none shrinker at all.

Any thoughts?

null string not generated by default

Consider the following:

let longEnough (s:string) = s.Length > 10
let check (s:string) =
s.Length <= 10 ==> (longEnough s = false)
Check.Quick check

let (bad:string) = null
longEnough (bad)

I would have expected FsCheck to propose a null string as a counter-example. Would love to hear if this is by design (and why), or by accident.

Q: generate non-empty string-keyed maps?

This doesn't seem to work:

open Fuchu
open FsCheck

type Arbs =
  static member SafeString () =
    Arb.Default.String () |> Arb.filter (fun str -> str <> null && not (str = ""))

  static member NonEmptyStringMaps () =
    Arb.Default.Map () |> Arb.filter (fun m -> m |> Map.toList |> List.forall (fun (k,v) -> k <> "" && k <> null))

let fsCheckConfig = { Config.Default with Arbitrary = [ typeof<Arbs> ] }

// ----
testPropertyWithConfig fsCheckConfig "can roundtrip" <| fun (evt : Evt) ->
 Assert.Equal("roundtrip", evt, roundTrip evt)

[<Property>] throws during test discovery

FsCheck 0.9.4
FsCheck.Xunit 0.4.1
XUnit.net 1.9.2
Visual Studio Premium 2013

Error message:
------ Discover test started ------
[xUnit.net 00:00:00.4260987] Exception discovering tests from Library1.dll: System.MissingMethodException: Method not found: 'Microsoft.FSharp.Core.FSharpOption1<StdGen> FsCheck.Config.get_Replay()'. at FsCheck.Xunit.PropertyAttribute..ctor() at System.RuntimeTypeHandle.CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor) at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent) at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit) at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit) at Xunit.Sdk.Reflector.ReflectionMethodInfo.<GetCustomAttributes>d__0.MoveNext() at Xunit.Sdk.Executor.EnumerateTests..ctor(Executor executor, Object _handler)$$RethrowMarker$$ at ExceptionExtensions.RethrowWithNoStackTraceLoss(Exception ex) at Xunit.RemoteAppDomainManager.CreateObject[TObject](String assemblyName, String typeName, Object[] args) at Xunit.Xunit1Executor.EnumerateTests(ICallbackEventHandler handler) at Xunit.Xunit1.Find(Predicate1 filter, Boolean includeSourceInformation, IMessageSink messageSink)
at Xunit.Xunit1.Xunit.Abstractions.ITestFrameworkDiscoverer.Find(Boolean includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options)
at Xunit.XunitFrontController.Find(Boolean includeSourceInformation, IMessageSink messageSink, ITestFrameworkOptions options)
at Xunit.Runner.VisualStudio.TestAdapter.VsTestRunner.DiscoverTests[TVisitor](IEnumerable1 sources, IMessageLogger logger, XunitVisualStudioSettings settings, Func3 visitorFactory, Action`3 visitComplete, Stopwatch stopwatch)
========== Discover test finished: 0 found (0:00:00,4820275) ==========

Code:
namespace Library1

open Xunit
open FsCheck
open FsCheck.Xunit

module Library1 =
[]
let Reverse of reverse of a list is the original list aa(xs:list) =
List.rev(List.rev xs) = xs

Problem appears both in VisualStudio's test explorer and in Resharper.
TE does not find test and shows error in output.
Resharper see test but hangs forever during execution (in pending state).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.