Debugging Hosted Assemblies , Page 2
Defining the NUnit Tests
To test our code we can downloaded the superlative NUnit Version 2.1 testing software from www.nunit.org. (Refer to last month's article on www.codeguru.com for more information on debugging with NUnit.)
NUnit will play the role of our testing host. Listing 3 contains some NUnit tests that we can very quickly assemble to begin scaffolding a suite of tests in conjunction with our application development.
Listing 3: NUnit tests for our Card and Ace classes.
Imports NUnit.FrameworkImports BlackJackLibVBImports System.Windows.Forms
_Public Class BlackJackTests _ Public Sub CardSuitTest() Dim aceOfClubs As Ace = _ New Ace(Suit.Club) Console.WriteLine(aceOfClubs.GetCardValue()) Assertion.AssertEquals("Expected 'AC'", _ aceOfClubs.GetCardValue(), _ "AC") End Sub _ Public Sub CardAceLowValueTest() Dim a As Ace = New Ace(Suit.Heart) Console.WriteLine(a.GetCardValue()) Assertion.AssertEquals("Expected 1", _ 1, a.GetLowFaceValue()) End Sub _ Public Sub CardAceHighValueTest() Dim a As Ace = New Ace(Suit.Heart) Console.WriteLine(a.GetCardValue()) Assertion.AssertEquals("Expected 11", _ 11, a.GetHighFaceValue()) End Sub Private spade As Ace _ Public Sub GraphicPaintAceTest() spade = New Ace(Suit.Spade) Dim F As Form = New Form AddHandler F.Paint, AddressOf OnPaint F.ShowDialog() Assertion.Assert(MsgBox("Did you see the ace of spades?", _ MsgBoxStyle.Question Or MsgBoxStyle.YesNo, "Ace of Spades") _ = MsgBoxResult.Yes) End Sub Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs) If (spade Is Nothing) Then Return spade.PaintGraphicFace(e.Graphics, 0, 0, 75, 100) End SubEnd Class
NUnit tests can be as advanced or as simple as you like. The real benefit of using NUnit is that it was designed to work with .NET specifically, uses a simple green for pass and red for fail visual metaphor, and offers a consistent predetermined means of defining, running, and evaluating tests.
To demonstrate I implemented some simple test that evaluate the text face-value of a card and one test that displays the graphic representation of the Ace of Spades. Figure 3 shows NUnit running in the background with the dynamic form and Ace card shown in the foreground.
Click here for larger image
Figure 3: The paint test for the ace of spades.
NUnit can be used quite simply as a pass or fail testing tool. Generally, you will need a testing scaffold that permits you to interact with your code while it's running; NUnit can be used for this too.
Attaching Visual Studio .NET to the Host Process
As the king of your demesne you can elect to step through your code for any reason. I wanted to work on the precise positioning of the playing cards. Pretending that the Ace of Spades didn't print where I anticipated we could test the BlackJackLibVB library while it is running in Visual Studio .NET. To do this we need to attach to the host process, NUnit. To debug a library running in its host, follow these steps:
- Open the library project you would like to test in Visual Studio .NET
- Run the host process that loads the library you will be testing. (In the example we need to run nunit-gui.exe and load the BlackJackLibVB.dll as shown in figure 3.)
- Back in Visual Studio .NET select Debug|Processes
- In the list of Available Processes find the nunit-gui.exe process hosting the BlackJackLibVB.dll as shown in figure 4
- Click the hosting process and click Attach
- In the Attach to Process dialog (see figure 5) check the Common Language Runtime program type and click OK
- Click Close to close the Processes dialog
Click here for larger image
Figure 4: Attached to the host process hosting your library.
Figure 5: We are debugging .NET code so select the Common Language Runtime program type.
After you click close you will see the dependent assemblies loaded into the integrated debugger in the Debug view of the Output window. Your library code is now running in the integrated debugger.
Debugging the BlackJackLibVB
Debugging a library this way is identical to debugging an executable, once the library is loaded via the host process. To debug the BlackJackLibVB set some breakpoints in the code at areas in which you are interested and run the tests. When the debugger hits your breakpoint the debugger will suspend code execution and you can take over. All of the great features you are used to in Visual Studio .NET are now at your fingertips when debugging library assemblies.
When You are Finished Debugging
When you have finished debugging your hosted assembly you can kill the host process or detach the debugger from the host process by selecting Debug|Processes, clicking the attached process and clicking Detach (see figure 4).
If you are debugging and NUnit is your host you have the luxury of detaching the debugger from NUnit, modifying your code, rebuilding, and re-attaching the debugger to NUnit all without shutting down VS.NET or NUnit. Collectively, these tools will yield some powerful results.
Some programmers aren't building rich client applications. Some of us, sometimes, are building frameworks of our own. Instead of spending a lot of time building test applications use the host your assembly will really run in and attach VS.NET to that process.
Using the VS.NET Debug|Processes dialog to attach to a running host process permits you to use the powerful integrated debugger in VS.NET without a lot of extra effort.
About the AuthorPaul Kimmel is the VB Today columnist for Codeguru.com and Developer.com and has written several books on object oriented programming, including the recently released Visual Basic .NET Power Coding from Addison-Wesley and the upcoming Excel VBA 2003: Programmer's Reference from Wiley. He is the chief architect for Software Conceptions and is available to help design and build your next application.
# # #