Small update – some other generators have been hardened against the new null-generating string generator. Also, FsCheck is compiled against F# 3.1 now, FSharp.Core 4.3.1.0. As always, available on NuGet.
24 May 2014
09 May 2014
FsCheck 0.9.3 and FsCheck.Xunit 0.4.1 released
FsCheck and Fscheck.Xunit both have a new release on NuGet.
FsCheck has a breaking change – the string and object generates by default now generate and shrink nulls.
FsCheck.Xunit has a workaround for an Xunit bug, the bug itself is also fixed in a beta version of Xunit itself but I figured the workaround is worth it.
Posted by Kurt Schelfthout at 10:04 PM 0 comments
24 April 2014
NDepend to analyze F# code
Disclosure: Patrick Smacchia from NDepend kindly contacted me to offer an NDepend pro license for evaluation purposes.
If you’ve been active in the .NET world I’m pretty sure you’ve heard about NDepend before. It’s a pretty amazing code analysis tool that’s been kicking around for as long as I can remember – and I’m feeling pretty old today. It analyses IL code of one or more .NET assemblies and presents you with a very extensive range of metrics and graphics so you can “big data” the shit out of your code. If the predefined metrics are not enough for you, it also provides CQL (Code Query Language), which allows you to write custom analyses easily. Here’s an example:
warnif count > 0 from m in JustMyCode.Methods where m.NbLinesOfCode > 30 orderby m.NbLinesOfCode descending select new { m, m.NbLinesOfCode, m.NbILInstructions }
This checks for methods that have more than 30 lines of code and orders them by number of code. Pretty straightforward, NDepend even comes with an IDE that gives you intellisense on writing these queries.
All good and well, and I’ve had some fun over the years using NDepend off and on. In my experience, while using it you always learn something about your or your team’s code. But often tools that work well with C# code have trouble with the different style of IL generated by F#. So how does NDepend deal with F# code? Let’s find out.
By the way, here’ s another post about NDepend applied to the F# compiler in case you want a second opinion.
For an initial impression with F#, I preferred using it on a project I know very well and that is also in the public domain. That doesn’t leave too many choices, obvious choice is of course FsCheck.
After choosing the projects to analyse I was greeted with the following screen:
Sure it looks pretty intimidating, but there’s a lot of useful stuff there. And the UI really helps you out a lot with hints and popups.
In the bottom right for example there’s a bunch of predefined CQL queries that are generating warnings. Some of them are a nice reassuring green. Some of them have some read there, which means NDepend thinks they are “critical”.
The one’s that highlighted is methods with too many parameters. I’m not too bothered with that – about half of them seem to be closures anyway. It’s easy to change the CQL to exclude methods with names that contain @ – that reduces it to two methods. One of them is the constructor of a record type. Not really critical. Filtering that out generally seems a bit harder (though probably still doable), but I’ll move on.
In the “Dead code” category (dead code is one of my favourite low hanging fruits to improve a code base. So great to just delete code with impunity.) There were a lot of methods that are just being called by reflection because of FsCheck’s generator registration mechanism that’s based on type – all these are not concerning to me but NDepend is certainly fair in highlighting these. I also found a couple of closures again, I wasn’t so sure about these. Maybe the F# compiler is sometimes generating a closure class when it really isn’t needed?
One last area I’ll discuss is the Purity – Immutability – Side effects category. You’d hope that an F# project would not throw up too many issues there, and indeed FsCheck doesn’t. NDepend does find all the cases where I used an array (i.e. a mutable type) as part of an immutable record type. It flags those because such types give the false impression that the type is immutable while really the array is mutable. Of course I realized that when I used arrays, making a conscious decision to not mutate them anyway, but it’s a pretty powerful example of the kind of analysis that you can do in a handful of lines of CQL.
Conclusion
NDepend is a really powerful tool to analyse your code base. A short overview like this doesn’t really do it justice, and despite some of the smaller niggles I mentioned above it’s absolutely usable for F#. Really all of the analyses are built on CQL, giving you at once every opportunity to refine them to make them more applicable to your own code base, as well as a great set of examples to build your own.
Posted by Kurt Schelfthout at 8:51 PM 1 comments
19 June 2013
FsCheck 0.9 Released and moved to GitHub
FsCheck has a new home on GitHub. I wanted to move to GitHub for a while, because it’s where all the cool kids hang out, and @carstkoenig gave me the necessary push. I hope the barrier for contributions is now low enough to get you to chip in if you feel like it, and simplifies the life of existing contributors. (Not that I’m complaining. You’ve been great.)
As for the long overdue release - a significant portion of contributions didn’t come from me.
Here are the highlights of the change log:
- New generators for KeyValuePair, IList, ICollection, Action, Func, decimal (@mausch) and sbyte (@jackfoxy).
- Finally compiled against FSharp.Core 4.3 (no more binding redirect. Yay.)
- FsCheck.Xunit now allows you to replay a certain test by pasting in the seed from the output in the PropertyAttribute’s Replay property. This should help with debugging:
[<Property(Replay="54321,67584")>]
- FsCheck.Xunit also allows defining ArbitraryAttribute on an enclosing module or type now – the given Arbitrary instances are then available for all properties in the type or module. But you can still override them if you define one on a specific property.
[<Arbitrary(typeof<TestArbitrary2>)>] module ModuleWithArbitrary = [<Property>] let ``should use Arb instances from enclosing module``(underTest:float) = underTest <= 0.0 [<Property( Arbitrary=[| typeof<TestArbitrary1> |] )>] let ``should use Arb instance on method preferentially``(underTest:float) = underTest >= 0.0
Hope you enjoy.
Posted by Kurt Schelfthout at 3:36 AM 0 comments
26 August 2012
FsCheck 0.8.3 and FsCheck.Xunit 0.3
I’ve just uploaded new NuGet packages for FsCheck and FsCheck.Xunit.
The changes are minor:
- FsCheck.Xunit now works with instance methods. NCrunch, for example, reportedly only works with instance methods, so this means you can now use NCrunch for running FsCheck properties.
- Both NuGet packages now call Add-BindingRedirect on install. This will generate an app.config file in your test project if necessary, to spell out to the .NET loader that tests compiled with F#3.0 and so in all likelihood using FSharp.Core 4.3 should indeed use 4.3 instead of the older 4.0, which FsCheck is compiled with.
- Added symbols on symbolsource.org.
Note that running “Add-BindingRedirect <project name>” in the NuGet package manager console should resolve any problems you may have running FsCheck in VS2012. Also, since xunit is strongly signed, there are similar problems with FsCheck.Xunit – Add-BindingRedirect solves that one too.
If you’re not into NuGet, add the following lines to your app.config file:
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Share this post : | MSDN! | Technet! | Del.icio.us! | Digg! | Dotnetkicks! | Reddit! | Technorati! |
Posted by Kurt Schelfthout at 10:48 PM 1 comments
26 June 2012
FsCheck 0.8.1: The ecosystem release
Yesterday I’ve released a new version of FsCheck. There are some minor changes, additions and bug fixes to FsCheck itself. The most important part of this release is that FsCheck is now integrated with Xunit through the new FsCheck.Xunit assembly.
For the impatient: NuGet packages for FsCheck and FsCheck.Xunit
Here goes a more detailed overview.
Generators are now applicative. Or, without the general abstract nonsense: say you’ve got three generators
let ga,gb,gc :Gen<_> * Gen<_> * Gen<_>
And you have a function of three arguments that you’d like to map over those.
let f = fun a b c ->
No problem, you can use Gen.map3 – right? But how many instances of map do you need? FsCheck currently defines 6. But now that Gen is applicative, we can write:
let result = f <!> ga <*> gb <*> gc
Hey, doesn’t that almost read like function application? That’s the idea. The weird operators in between just make sure everything is applied properly. Besides being a bit nicer to use sometimes, you can also keep chaining this indefinitely, up to any arity.
And hey, if you still prefer map, FsCheck still has those.
New generators. Mauricio Scheffer contributed int64 and TimeSpan generators. I’ve also added an int16 generator, and DontSize wrappers for all of those – the default generators for int16, 32 and 64 will generate integers smaller than the test size, which is increased by FsCheck as the test progresses. The DontSize variants ignore the size and always pick from the whole range for the type.
Xunit integration. Xunit is a very nice framework – very simple to use and extend. FsCheck integrates with Xunit by adding a PropertyAtttribute. To use it, just use Property instead of Fact, and you can now give your test arguments. These are randomly generated by FsCheck. You can also use all of the normal property combinators in the Prop namespace. A couple of examples:
[<Property>]
let ``abs(v) % k equals abs(v % k)`` v (NonZeroInt k) =
(abs v) % k = abs(v % k)
[<Property>] let ``divMod should satisfy definition`` (x:int) (y:int) = y <> 0 ==> lazy (let (d,m) = divMod x y in d*y + m = x)
Note that Property test methods, as opposed to Fact, don’t need to return unit – they can return anything that’s testable with FsCheck, including bool. But since a test fails in FsCheck when it throws an exception, you can still use the Assert class if you like. You can also use FsUnit or Unquote or whatever to write your assertions. FsCheck does not care – it does the hard work of generating random values and shrinking them if the test fails and generally tries to get out of your way for the rest.
You can also set various configuration parameters using the Property attribute, which then apply to that method only. Most of these are trivial (e.g. the number of tests), but an interesting one is that you can override the random generation for certain types on one test method only:
type TestArbitrary1 = static member PositiveDouble() = Arb.Default.Float() |> Arb.mapFilter abs (fun t -> t >= 0.0) [<Property( Arbitrary=[| typeof<TestArbitrary1> |] )>] let ``should register Arbitrary instances from Config in last to first order``(underTest:float) = underTest >= 0.0
Here the generator for float is overridden to generate only positive floats.
Finally, a special thanks to @mausch for contributing, integrating FsCheck with Fuchu, and giving me a gentle nudge to get this release out the door at last!
Share this post : | MSDN! | Technet! | Del.icio.us! | Digg! | Dotnetkicks! | Reddit! | Technorati! |
Posted by Kurt Schelfthout at 3:06 AM 3 comments
26 May 2012
Accessibility modifiers on F# record types
In the note to self category.
type internal Internal = { Si : string }
means that the class Internal will be internal. The constructor and properties are technically public, but that is meaningless since the enclosing class is internal. However, if the Internal type implements public interfaces, then the public methods it implements are visible and usable by clients outside the assembly (provided they get hold of an instance, of course – they can’t construct one since they can’t see the name of the class).
type IGet = abstract Get : string type internal Internal = { Si : string } interface IGet with member x.Get = x.Si
If an instance gets out as an obj, clients can still call HashCode and Equals because those are exposed as public overrides from obj or as public interfaces, e.g. IComparable.
type Internal = internal { Si : string }
means that the class Internal is public, but the constructor and properties are internal.
Both can be combined, and private of course works too. Similar accessibility modifiers can be given to discriminated unions – it is not possible to give a different accessibility to individual union cases, just like it isn’t possible to give different modifiers to different fields of a record.
Share this post : |
Posted by Kurt Schelfthout at 2:57 AM 0 comments
Labels: F#