Post

Using Pex to test VB.NET code

In .NET, Tech/Hacks on December 2, 2008 by Sid Tagged: , , ,

In an ideal world one would write unit-tests before writing any new code following the tenants of TDD. In reality it is quite common to have to rely on a legacy library to do some heavy lifting. Pex is a great new tool available from Microsoft Research that can be used to generate unit-tests automatically. It is smart in that it runs the function you wish to test trying to exercise all possible code paths and ultimately generates unit-tests that can be used to test that function.

Using Pex is as easy as right-clicking on a function in Visual Studio and selecting “Run Pex Explorations”. Pex takes a little while running your function and then displays a table with various values that can be used to test your function.

However if your legacy code happens to be in VB.NET, you cannot just right-click on a function to have Pex generate all unit-tests for you. So that’s where I hope this article will help you.

First, let’s define a scenario. Imagine there’s a class called Transaction and a class called PaymentMethod. A transaction contains various payment-methods. A PaymentMethod indicates whether it requires the cash-drawer to be opened or not (e.g. it doesn’t make sense to pop cash-drawer for a credit-card while it does for cash and debit-card). There’s a read-only property PopCashDrawer on Transaction which returns true if any of the payment-methods requires the cash-drawer to be opened.

Public Class PaymentMethod

Private mPopCashDrawer As Boolean

Public Property PopCashDrawer() As Boolean
Get
Return Me.mPopCashDrawer
End Get
Set(ByVal value As Boolean)
Me.mPopCashDrawer = value
End Set
End Property

End Class

Public Class Transaction

Private mPaymentMethods() As PaymentMethod

Public Property PaymentMethods() As PaymentMethod()
Get
Return Me.mPaymentMethods
End Get
Set(ByVal value As PaymentMethod())
Me.mPaymentMethods = value
End Set
End Property

Public ReadOnly Property PopCashDrawer() As Boolean
Get
Dim pop = False
For Each pm As PaymentMethod In Me.PaymentMethods
pop = pop OrElse pm.PopCashDrawer
Next
Return pop
End Get
End Property

End Class

To have Pex generate unit-tests for you, here’s what you need to do:

  • First to get started writing unit-tests, just right-click on Transaction in Visual Studio and select “Create Unit Tests”. Make sure you select “Create a new Visual C# project” for Output Project in the dialog that pops up.
  • Next, in the generated class TransactionTest add the following parameterized unit-test (PUT). This guides Pex to come up with different values of arguments to this method which will exercise all code-paths in PopCashDrawer property. Transaction.PopCashDrawer depends upon the PaymentMethods so we take the array of PaymentMethods as argument to our PUT and set it on the transaction before calling PopCashDrawer. The PexAssume.IsNotNull line further guides Pex to say that we don’t really care about the case when transaction is null because we’re really interested in testing PopCashDrawer method.

    [PexMethod]
    public bool PopCashDrawerPUT(Transaction transaction, PaymentMethod[] paymentMethods)
    {
    PexAssume.IsNotNull(transaction);
    transaction.PaymentMethods = paymentMethods;
    return transaction.PopCashDrawer;
    }

  • Next, just right-click on PopCashDrawerPUT and select “Run Pex Explorations”. Pex will then display a table with various values of arguments and the results it got in each case.
  • However since the VB assembly is separate from the C# test-project, Pex will display an icon indicating that it didn’t explore some methods because they were uninstrumented.
  • Make sure you include all methods displayed as uninstrumented and run Pex explorations again.
  • This time around Pex would show 7 different test-cases that it identified.
  • A file named TransactionTest.PopCashDrawerPUT.g.cs would be generated containing unit-tests for those 7 cases. Take a look at that class to see how much work it saved you.
  • You can run the generated unit-tests by going to Test->Run->All Tests in Solution from the main-menu in Visual Studio.
  • Pex would discover inputs which cause PopCashDrawer to throw a NullReferenceException. Determining fixes for those cases is left as an exercise to the reader :)

Download and try out Pex, if you haven’t already!

One Response to “Using Pex to test VB.NET code”

  1. Nice post. Thank you for the info. Keep it up.

Leave a Reply