Click here to Skip to main content
15,867,889 members
Articles / Microsoft

Using Pex and Microsoft Code Digger to Better Understand and Test Your Code

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
25 Apr 2013CPOL7 min read 34.3K   6   5
Using Pex and Microsoft Code Digger to better understand and test your code

This article appears in the Third Party Products and Tools section. Articles in this section are for the members only and must not be used to promote or advertise products in any way, shape or form. Please report any spam or advertising.

Code is a bit like an animal.

If a great deal of effort is placed into training the animal (through proper design practices, testing methodologies and reviews), then the code can easily be “domesticated” by an experienced developer and can do just about any trick that its owner desires. In contrast, an untrained, untested and poorly written piece of code is the kind that you worry about when you leave the house and it proceeds to tear apart all of the nice things that you own.

This is why testing is such a crucial part of software development and why it can often help to have any many tools as possible to help you train the animal within your code so it doesn’t harbor bugs.

Microsoft Research’s Pex team recently released the Microsoft Code Digger, which is a handy extension for Visual Studio 2012 that will allow you to analyze all of the possible execution paths that a particular snippet of code could take. This can be extremely helpful when dealing with areas of complex code and to help better understand the code, discover why it behaves in a certain way and to uncover any bugs lurking within it.

About Pex

Pex Logo

Pex – Automated Unit Testing for .NET

Pex is one of the many wonderful things going on at Microsoft Research and it is intended to be a tool to assist with automating white-box and unit-testing. It can help with generating all kinds of different inputs that can be thrown at a specific set of code and will display each of these execution branches along with the corresponding output of the function. It can provide an easy way for those that aren’t crazy about writing unit tests (or just aren’t very good at it) to simply test their code by letting the Pex Engine run through it.

Pex can provide an excellent way for you to find those small edge-cases that can so often plague software and the fact that the process is completely automated makes it even easier!

Let’s Get Digging

To get started using the Code Digger, you’ll just need to go and download the extension from the following site:

After installing it, you should be good to go and ready to get started!

A minor caveat; Code Digger was very recently released and as a result currently only works for Visual Studio 2012 and can only target code that is contained within Portable Class Libraries. But fear not, as there are still numerous other ways that you can use Pex even outside of Visual Studio 2012, which will be covered later within this post. (Not to mention that you know the folks at Microsoft are no doubt working to take this magical code and use it on a larger-scale.)

Getting Started and Swimming with Sharks

Let’s take a look at the Code Digger in action, which can help provide a much better explanation of what is going on behind-the-scenes and what makes Pex so magical!

Firstly, we will create a simple Portable Class Library file that we can use to create a very simple function and get an idea of how the Code Digger works.

Creating a Portable Class Library

Create a new Portable Class Library Project that can be used with Microsoft Code Digger.

(You’ll be prompted to select which environments you want the code to be compatible with after. Since this is for demonstration purposes, just click OK.)

Then, we will need to create a very simple function to begin with, such as summing an array of integers:

C#
//Simple method to sum an array of integers
public static int Sum(int[] values)
{
     return values.Sum();
}

To actually put the Code Digger to work, all you will need to do is simply right-click on your function and select the “Generate Inputs / Outputs Table” option.

Generate Inputs / Outputs Table

Simply right-clicking your method and selecting “Generate Inputs / Outputs Table” option will display the generated data.

As you can see, the Code Digger provided the following valuable inputs that the function might receive as well as the different behaviors that it might exhibit. This information can be very useful in finding weaknesses and avoiding exceptions within our code as well as finding edge cases that may remain unseen.

Generated Output for our array-summing method.

Generated Output for our array-summing method.

Adding a Bit More Complexity

Now that we know it will work for simple integer values, let’s try passing in a more complex model and see what kind of results it provides:

C#
//More Complex Example
public static decimal CalculateCandyPricePerServing(IEnumerable<BagOfCandy> bagsOfCandy)
{
       return bagsOfCandy.Average(p => p.Servings / p.Price);
}
//A Bag of Candy
public class BagOfCandy
{
       public int Servings { get; set; }
       public decimal Price { get; set; }
       public BagOfCandy(){}
}

which yields the following:

Example Bags of Candy Output

An example of how adding additional complexity typically results in additional testing.

So – we will need to add the necessary checks within this statement to fix up some of these problems, which should be able to be done through a few simple logic checks:

C#
//A simple method to calculate the average price per piece of candy given several bags of candy
public static decimal CalculateCandyPricePerServing(IEnumerable<BagOfCandy> bagsOfCandy)
{
       //Rough attempt to fix several more of the issues apparent in the first table
       if(bagsOfCandy == null || !bagsOfCandy.Any(p => p != null && p.Price != 0 && p.Servings != 0))
       {
             //Return -1 for invalid results
             return -1;
       }
       else
       {
             //Attempt to average the values otherwise
             return bagsOfCandy.Average(p => p.Servings / p.Price);
       }
}

And now after running it, let’s see what our results look like:

Slightly Less Red Inputs Outputs Table

Although those checks handled some of the data that was coming in – it helped reveal other possible flaws.

and a little more tinkering with it could help get rid of those few remaining red errors:

C#
public static decimal CalculateCandyPricePerServing(IEnumerable<BagOfCandy> bagsOfCandy)
{
       //If the bags of candy are not null and contain any bags that are not null
       if(bagsOfCandy != null && bagsOfCandy.Any(b => b != null))
       {
             //Gather the unempty bags with valid prices
             var unemptyBags = bagsOfCandy.Where(b => b != null && b.Price > 0);
             //If there are any of these bags - output the average, otherwise -1
             return (unemptyBags.Any()) ? unemptyBags.Average(p => p.Servings/p.Price) : -1;
       }
       else
       {
             //Otherwise return -1
             return -1;
       }
}

which yields:

Many less red error icons

Continually attempting to use the input and output information can help you strengthen your methods and prepare them for the “real-world”

As you can see, Pex is great and continually challenging your possible inputs to help you avoid errors. This also functions as a great method to teach yourself or others about unit-testing and how to properly develop methods (and hopefully develop solid habits so that you won’t have to do this for every one of your methods).

Don’t Have Visual Studio 2012? No Problem!

Although the Microsoft Code Digger is the most recent tool released by the Pex Team, it isn’t the only one out there. The team has previously released two of the components of the engine as Add-Ins for Visual Studio 2008 and Visual Studio 2010, which can be downloaded below:

Pex consists of the following tools and functions:

  • Pex command line (Visual Studio not required)
  • Pex Visual Studio Add-in, for Visual Studio 2008 and Visual Studio 2010
  • API reference, tutorials and documentation
  • Samples and Behaviors

and Moles has the following features:

  • Lightweight test stubs and detours for .NET
  • API reference, tutorials and documentation
  • Samples and Behaviors

These tools should be everything that you need to begin exploring, experimenting and hopefully more easily testing your code.

(Note: In Visual Studio 2012 – Moles has been replaced by the Fakes Framework. You can read more about handling and isolating your code using the Fakes Framework here)

Try It Out Yourself Online!

If you aren’t sure if the Code Digger, Pex or Moles are something that you would be interesting in, you should give it a try… online!

Pex For Fun Logo

Pex for Fun is a simplified version of the Pex engine that has been designed to function as a puzzle game and learning tool.

Pex for Fun was an learning tool / puzzle game designed using the basic premise of Pex. It features a very simplified version of Pex, which analyzes a given function and provides you information about the output and challenges you to place the appropriate logic within the function to solve the puzzle.

For example, you initial puzzle might look like this:

C#
using System;
public class Program {
     public static int Puzzle(int x) {
         return x;
     }
}

with the following output:

Pex for Fun Example Output

This is a basic example of how Pex for Fun output appears.

So you might think “Well since I know the output, I’ll just use a switch statement”:

C#
using System;
public class Program {
 public static int Puzzle(int x) {
      switch(x)
      {
           case 0:
           case 1:
           default:
                return x;
           case 2:
                return x + 1;
           case 3:
                return x * 2;
           case 7:
                return x * x + x;
     } 
 }
}

Nope! (If you have ever been in a programming competition, you will know this feeling.)

Pex for Fun Result with Errors

It’ll take more than a series of switch statements to foil one of these puzzles.

If you enjoy puzzles like these, you’ll figure out that the actual answer uses our friend recursion:

C#
using System;
public class Program {

    public static int Puzzle(int x) {
         if(x <= 1)
         {
              return x;
         }
         else
         {
              return Puzzle(x-1) + ((Puzzle(x-1) - Puzzle(x-2)) + (Puzzle(x-2) - Puzzle(x-3)));
         } 
    }
}

and reap all of the glorious rewards:

Pex for Fun Reward Image

A pixelated medal isn’t much – but you earned it!

More than Pixelated Golden Medals

The Pex for Fun example as mentioned earlier displays the most very basic features of the Pex Engine and is really meant more for recreational and educational purposes. The features and functionality that exists there however are quite powerful and if leveraged correctly could dramatically change the way that unit-testing is done (or it could at least act as a great supplement). I encourage you to try downloading any of the Pex packages mentioned throughout this post and try it out yourself. If you want to access the same examples used within this post, you can download them from Github.

Perhaps with the incredible continuing progress of the Pex Team and the rest of the folks over at Microsoft Research, unit-testing can and will become more like a game and less like a chore.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
An experienced Software Developer and Graphic Designer with an extensive knowledge of object-oriented programming, software architecture, design methodologies and database design principles. Specializing in Microsoft Technologies and focused on leveraging a strong technical background and a creative skill-set to create meaningful and successful applications.

Well versed in all aspects of the software development life-cycle and passionate about embracing emerging development technologies and standards, building intuitive interfaces and providing clean, maintainable solutions for even the most complex of problems.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Johannes van Tonder21-Aug-13 11:00
Johannes van Tonder21-Aug-13 11:00 
Great stuff! Can't wait for version that supports non-portable libraries.
QuestionVisual Studio 2012 - is it a problem? Pin
Michael Freidgeim16-Jun-13 3:41
Michael Freidgeim16-Jun-13 3:41 
AnswerRe: Visual Studio 2012 - is it a problem? Pin
Johannes van Tonder21-Aug-13 11:12
Johannes van Tonder21-Aug-13 11:12 
AnswerRe: Visual Studio 2012 - is it a problem? Pin
AdamWhitehat13-Feb-22 22:26
professionalAdamWhitehat13-Feb-22 22:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.