10 October 2011

What is Pex and Moles?

UPDATE
Please be aware the Moles Framework has been productized and released as Microsoft Fakes Framework, in the Visual Studio 2012 Ultimate and Premium (with Update 2) SKUs. Pex seems to have evaporated -- I hear no news regarding Pex, from the internals of Microsoft. This information is intended for historical reference for developers that still use or encounter these technologies.


This is the first post in a series. Please visit the new Testing wih Pex and Moles page, for an index to all related posts.

Microsoft Pex and Moles are a set of automated white box unit testing utilities, developed by Microsoft Research in Software (RiSE) group.  As of writing this post, the Pex and Moles package is version 0.94.51023.0, and has been in development for several years.  The first public release of Pex was released in mid 2008.  Moles debuted as a host type, in late 2009.  These both matured greatly, until October 2010.  Since that time, no subsequent releases have been issued.  This could mean the technologies are being polished up for release, or waiting for an opportunity for release with another project like Visual Studio 11.  There are still some seemingly obvious features that are missing, so the case could also be that it is simply put on the back burner for a while.  However, the late addition of MSBuild support suggests otherwise.


UPDATE (21 OCT 2011):
I suspected that something was going on with Pex and Moles, since the releases are running out of beta numbers (0.92.xxx), and nothing new has been released for a year.  This typically indicates the project has been handed off to another team for integration in to a release product.

I asked a very respectable member of the Microsoft Visual Studio development team, if Pex/Moles or some other dependency isolation mechanism will be introduced in Visual Studio 11. In traditional Microsoft "I will nether confirm nor deny" fashion, this individual told me, "Dependency isolation will be taken care of, in Visual Studio 11."  It appears Pex and Moles are finally being rolled into Visual Studio!  The current VS11 preview does not yet include dependency isolation features.  Hopefully, this information I have blogged will become obsolete!

Note, this VS11 download is a PREVIEW, not a BETA, or even an ALPHA.  Many more features are still cooking.  Stability is OK, but use it at your own risk!


What is Pex?
Pex performs code explorations on existing code, making it ideal for use with legacy code.  Pex profiles logical branches in the code, such as conditionals, loop conditions, jump statements, and regular expressions.  Pex repeatedly runs tests on the code under test, to generate a list of input parameters that extend into as many logical blocks as possible.  Pex is run in development time, and generated test code for complation.

These values may are used to generate a common parameterized method used for testing.  A series of test methods, each submitting one of the generated values for testing.  Pex explorations may be run again, at any time, to evaluate changes made to the target code.  The value tests are automatically regenerated.  Therefore, Pex acts as a dynamic test generator.  Because it is dynamic, generated Pex tests are only capable of probing the logical makeup of code, and are often useless as data manipulation validation tests.  This does not discount the utility provided by Pex, and its ability to highlight logical problems in code.

It is possible to write static tests that call the parameterized test, created by Pex.  These tests should be written in a separate file, to avoid losing them when the Pex value tests are regenerated.  These static tests are where output validation should take place.  Because code often interacts with external data resources, such as databases and file systems, it is important to ensure that unit tests always receive the same data from these dependencies.  If only there were some way to isolate and/or inject dependencies...

What is Moles?

Moles is a dependency isolation, mocking, and stubbing framework, used by Pex, and may be used to create static tests.  Unlike Pex, Moles executes in runtime, and has its own host type.  Host type is a feature of the Visual Studio Test Framework that provides an environmental context that reproduces the production environment, when executing unit tests.  For example, the ASP.NET host provides an HTTPRequest, HTTPSessionState, and other ASP.NET specific contexts.

Because much of the documentation and videos were produced before the most recent release of Moles, information about how it functions is no longer entirely accurate. Moles works by creating a sort of wrapper assembly for the assembly under test.  A wrapper class is created for each target class, and these contain a Func<,> typed property for every method and property.  The wrapper, or "moled" assembly is generated by the compiler, when the test project is built.

When executed, calls from the test methods are routed through the moled assembly.  By default, every Func<,> points to the original object in the target assembly, transparently passing the call though.  However, the mole type property may be pointed to another target, detouring the call away from the original target, often an anonymous method defined by a lambda expression in the calling unit test method.

Moles is described in documentation as an instrumentation, but with these recent changes to a more wrapper-based detour model, this appears to be less true.  The wrapper method does not alter the target code in any way, and does not capture or return any information.

Moles generates two types in the moled assembly: Mole and Stub types.  Stub types are created for classes that implement an interface.  As described above, specific portions of the stub type may be detoured, to return predefined (mock) values.  This allows the test to use the original stub type as a test stub, without the pains of having to build and maintain an entire test stub, and/or set of stubs.  Stub types may only be used in the same situations as interface implementation: non-static, non sealed classes.

Mole types provide the same detouring capabilities, for all other types, including internal, sealed, and static.  Mole types are excellent for isolating dependencies, such as third party APIs and .NET Framework types. For example, calls to System.IO.File.Exists may be detoured, to always return a true value, or only in specific situations.

Needless to say, Moles is an extremely useful part of this package.  I have yet to meet a developer who didn't immediately want to get their hands on Moles, and start playing with it!

Unlike earlier releases of Moles, version 0.94.51023.0 is considerably more lightweight, and includes pre-compiled mscorlib wrappers for the entire .NET framework.  The new wrapper model compiles much faster and appears to be less intrusive.

When writing new code and in Test Driven Design (TDD), stubs should be used as much as possible, for performance and future compatibility reasons.  When working with legacy code, Mole types can be very useful, especially when refactoring the target code is not an option.

NOTE: Until January 2010, these Moles Framework was known as the Stubbing Framework, and Moles Host type was named the Pex Host Type.

Where Can I Learn More About Pex and Moles?

The Pex and moles Documentation site is the best source for information, at this time.  Please be aware the Microsoft forum for Pex and Moles was archived, in April 2011.  Questions regarding Pex and Moles should be posted to StackOverflow.com.  You are also free to send questions to me or Pex and Moles experts.

Because I make mistakes, please feel free to post corrections.  I learn something new every day, too!

2 comments:

  1. The article is outdated. Moles was replaced with MS Fakes framework

    ReplyDelete
    Replies
    1. Yes, it is. However, there are still many users of Moles and Pex. I am certain the eminent release of Visual Studio 2012 Update 2 will change this. The update brings the Fakes Framework to the Premium SKU of VS2012.

      Delete

Please provide details, when posting technical comments. If you find an error in sample code or have found bad information/misinformation in a post, please e-mail me details, so I can make corrections as quickly as possible.