This chapter is taken from book
"Moving to Microsoft Visual Studio 2010" by Patrice Pelland, Pascel Pare, and
Ken Haines published for Microsoft Press.
After reading this chapter, you will be able to
- Use the new debugger features of Microsoft Visual Studio 2010
- Create unit tests and execute them in Visual Studio 2010
- Compare what was available to you as a developer in Visual Studio 2005
As we were writing this book, we realized how
much the debugging tools and developer aids have evolved over the last three
versions of Visual Studio. Focusing on debugging an application and writing unit
tests just increases the opportunities we have to work with Visual Studio 2010.
Visual Studio 2010 Debugging Features
In this chapter, you'll go through the different debugging features using a
modified Plan My Night application. If you installed the companion content at
the default location, you'll find the modified Plan My Night application at the
following location: %userprofile%\Documents\Microsoft Press\Moving to Visual
Studio 2010\Chapter 7\Code. Double-click the PlanMyNight.sln file.
First, before diving into the debugging session itself, you'll need to set up a
- In Solution Explorer, ensure that PlanMyNight.Web is the startup project. If the project name is not in bold, right-click on PlanMyNight.Web and select Set As StartUp Project.
- To get ready for the next steps, in the PlanMyNight.Web solution open the Global.asax.cs file by clicking the triangle beside the Global.asax folder and then double-clicking the Global.asax.cs file, as shown in Figure 7-1:
FIGURE 7-1 Solution Explorer before opening the file Global.asax.cs
Managing Your Debugging Session
Using the Plan My Night application, you'll examine how a developer can manage
and share breakpoints. And with the use of new breakpoint enhancements, you'll
learn how to inspect the different data elements in the application in a much
faster and more efficient way. You'll also look at new minidumps and the
addition of a new intermediate language (IL) interpreter that allows you to
evaluate managed code properties and functions during minidump debugging.
New Breakpoint Enhancements
At this point, you have the Global.ascx.cs file opened in your editor. The
following steps walk you through some ways to manage and share breakpoints:
- Navigate to the Application_BeginRequest(object sender, EventArgs e) method, and set a breakpoint on the line that reads var url = HttpContext.Current.Request.Url; by clicking in the left margin or pressing F9. Look at Figure 7-2 to see this in action:
FIGURE 7-2 Creating a breakpoint
- Press F5 to start the application in debug mode. You should see the developer Web server starting in the system tray and a new browser window opening. The application should immediately stop at the breakpoint you just created. The Breakpoints window might not be visible even after starting the application in debug mode. If that is the case, you can make it visible by going to the Debug menu and selecting Windows and then Breakpoints, or you can use the keyboard shortcut: Ctrl+D+B.
You should now see the Breakpoints window as shown in Figure 7-3:
FIGURE 7-3 Breakpoints window
- In the same method, add three more breakpoints so that the editor and the Breakpoints window look like those shown in Figure 7-4:
FIGURE 7-4 Code editor and Breakpoints window with three new breakpoints
Visual Studio 2005 As a reader and a professional developer who used Visual Studio 2005 often, you probably noticed a series of new buttons as well as new fields in the Breakpoints window in this exercise. As a reminder, take a look at Figure 7-5 for a quick comparison of what it looks like in Visual Studio 2005.
FIGURE 7-5 Visual Studio 2005 Breakpoints window
- Notice that the Labels column is now available to help you index and to search breakpoints.
It is a really nice and useful feature that Visual Studio 2010 brings to the table. To use this feature, you simply right-click on a breakpoint in the Breakpoints window and select Edit Labels or use the keyboard shortcut Alt+F9, L, as shown in Figure 7-6:
FIGURE 7-6 Edit Labels option
- In the Edit Breakpoint Labels window, add labels for the selected breakpoint (which is the first one in the Breakpoints window). Type ContextRequestUrl in the Type A New Label text box, and click Add. Repeat this operation on the next breakpoint, and type a label name of url. When you are done, click OK. You should see a window that looks like Figure 7-7 while you are entering them, and to the right you should see the Breakpoints window after you are done with those two operations:
FIGURE 7-7 Adding labels that show up in the Breakpoints window
Note You can also right-click on the breakpoint in the left margin and select Edit Labels to accomplish the same tasks I just outlined.
Note You'll see that when adding labels to a new breakpoint you can choose any of the existing labels you have already entered. You'll find these in the Or Choose Among Existing Labels area, which is shown in the Edit Breakpoint Labels dialog box on the left in the preceding figure.
- Using any of the ways you just learned, add labels for each of the breakpoints, and make sure your Breakpoints window looks like Figure 7-8 after you're done.
FIGURE 7-8 Breakpoints window with all labels entered
When you have a lot of code and are in the midst of a debugging session, it would be great to be able to filter the displayed list of breakpoints. That's exactly what the new Search feature in Visual Studio 2010 allows you to do.
- To see the Search feature in action, just type url in the search text box and you'll see the list of breakpoints is filtered down to breakpoints containing url in one of their labels.
In a team environment where you have many developers and testers working together, often two people at some point in time are working on the same bugs. In Visual Studio 2005, the two people needed to sit near each other, send one another screen shots, or send one another the line numbers of where to put breakpoints to refine where they should look while debugging a particular bug.
Important One of the great new additions to breakpoint management in Visual Studio 2010 is that you can now export breakpoints to a file and then send them to a colleague, who can then import them into his own environment. Another scenario that this feature is useful for is to share breakpoints between machines. We'll see how to do that next.
- In the Breakpoints window, click the Export button to export your breakpoints to a file, and then save the file on your desktop. Name the file breakexports.xml.
- Delete all the breakpoints either by clicking the Delete All Breakpoints Matching The Current Search Criteria button or by selecting all the breakpoints and clicking the Delete The Selected Breakpoints button . The only purpose of deleting them is to simulate two developers sharing them or one developer sharing breakpoints between two machines.
- You'll now import your breakpoints by clicking the Import button and loading them from your desktop. Notice that all your breakpoints with all of their properties are back and loaded in your environment. For the purposes of this chapter, delete all the breakpoints.
Inspecting the Data
When you are debugging your applications, you know how much time one can spend
stepping into the code and inspecting the content of variables, arguments, and
so forth. Maybe you can remember when you were learning to write code, a while
ago, when debuggers weren't a reality or when they were really rudimentary. Do
you remember (maybe not-you might not be as old as we are) how many printf or
WriteLn statements you had to write to inspect the content of different data
Visual Studio 2005 In Visual Studio 2005, things were already a big improvement
from the days of writing all kinds of statements to the console, because Visual
Studio had a real debugger with new functionalities. New data visualizers
allowed you to see XML as a well-formed XML snippet and not as a long string.
Furthermore, with those data visualizers, you could view arrays in a more useful
way, with the list of elements and their indices, and you accomplished that by
simply hovering your mouse over the object. Take a look at Figure 7-9 for an
FIGURE 7-9 Collection view versus an array view in the debugger in Visual Studio
2010 and in Visual Studio 2005
Although those DataTip data visualization techniques are still available in
Visual Studio 2010, a few great enhancements have been added that make DataTips
even more useful. The DataTip enhancements have been added in conjunction with
another new feature of Visual Studio 2010, multimonitor support. Floating
DataTips can be valuable to you as a developer. Having the ability to put
DataTips on a second monitor can make your life a lot easier while debugging,
because it keeps the data that always needs to be in context right there on the
second monitor. The following steps demonstrate how to use these features:
- In the Global.ascx.cs file, insert breakpoints on lines 89 and 91, lines starting with the source code var authority and var pathAndQuery, respectively.
- You are now going to experiment with the new DataTip features. Start the debugger by pressing F5. When the debugger hits the first breakpoint, move your mouse over the word url and click on the pushpin, as seen in Figure 7-10:
FIGURE 7-10 The new DataTip pushpin feature
- To the right of the line of code, you should see the pinned DataTip (as seen in the following
figure on the left). If you hover your mouse over the DataTip, you'll get the DataTip management bar (as seen in Figure 7-11 on the right):
FIGURE 7-11 On the left is the pinned DataTip, and on the right is the DataTip management bar
Note You should also see in the breakpoint gutter a blue pushpin indicating that the DataTip is pinned. The pushpin should look like this: . Because you have a breakpoint on that line, the pushpin is actually underneath it. To see the pushpin, just toggle the breakpoint by clicking on it in the gutter. Toggle once to disable the breakpoint and another time to get it back.
Note If you click the double arrow pointing down in the DataTip management bar, you can insert a comment for this DataTip, as shown in Figure 7-12. You can also remove the DataTip altogether by clicking the X button in the DataTip management bar.
FIGURE 7-12 Inserting a comment for a DataTip
- One nice feature of the new DataTip is that you can insert any expression to be evaluated right there in your debugging session. For instance, right-click on the DataTip name, in this case url, select Add Expression, type authority, and then add another one like this: (authority != null). You'll see that the expressions are evaluated immediately and will continue to be evaluated for the rest of the debugging session every time your debugger stops on those breakpoints. At this point in the debugging session, the expression should evaluate to null and false, respectively.
- Press F10 to execute the line where the debugger stopped, and look at the url DataTip as well as both expressions. They should contain values based on the current context, as shown in Figure 7-13:
FIGURE 7-13 The url pinned DataTip with the two evaluated expressions
- Although it is nice to be able to have a miniâ€“watch window where it matters-right there where the code is executing-you can also see that it is superimposed on the source code being debugged. Keep in mind that you can move the DataTip window anywhere you want in the code editor by simply dragging it, as illustrated in Figure 7-14:
FIGURE 7-14 Move the pinned DataTip away from the source code
- Because it is pinned, the DataTip window stays where you pinned it, so it will not be in view if you trace into another file. But in some cases, you need the DataTip window to be visible at all times. For instance, keeping it visible is interesting for global variables that are always in context or for multimonitor scenarios. To move a DataTip, you have to first unpin it by clicking the pushpin in the DataTip management bar. You'll see that it turns yellow. That indicates you can now move it wherever you want-for instance, over Solution Explorer, to a second monitor, over your desktop, or to any other window. Take a look at Figure 7-15 for an example:
FIGURE 7-15 Unpinned DataTip over Solution Explorer and the Windows desktop
Note If the DataTip is not pinned, the debugger stops in another file and method, and the DataTip contains items that are out of context, the DataTip windows will look like Figure 7-16. You can retry to have the debugger evaluate the value of an element by clicking on this button: . However, if that element has no meaning in this context, it's possible that nothing happens.
FIGURE 7-16 DataTip window with out-of-context items
Note You'll get an error message if you try to pin outside the editor, as seen in Figure 7-17:
FIGURE 7-17 Error message that appears when trying to pin a DataTip outside the code editor
Note Your port number might be different than in the screen shots just shown. This is normal-it is a random port used by the personal Web server included with Visual Studio.
Note You can also pin any child of a pinned item. For instance, if you look at url and expand its content by pressing the plus sign (+), you'll see that you can also pin a child element,
as seen in Figure 7-18:
FIGURE 7-18 Pinned child element within the url DataTip
- Before stopping the debugger, go back to the Global.ascx.cs if you are not already there and re-pin the DataTip window. Then stop the debugging session by clicking the Stop Debugging button in the debug toolbar ( ) or by pressing Shift+F5. Now if you hover your mouse over the blue pushpin in the breakpoint gutter, you'll see the values from the last debug session, which is a nice enhancement to the watch window. Take a look at Figure 7-19 for what you should see:
FIGURE 7-19 Values from the last debug session for a pinned DataTip
Note As with the breakpoints, you can export or import the DataTips by going to the Debug menu and selecting Export DataTips or Import DataTips, respectively.
Using the Minidump Debugger
Many times in real-world situations, you'll have access to a minidump from your
product support team. Apart from their bug descriptions and repro steps, it
might be the only thing you have to help debug a customer application. Visual
Studio 2010 adds a few enhancements to the minidump debugging experience.
Visual Studio 2005 In Visual Studio 2005, you could debug managed application or
minidump files, but you had to use an extension if your code was written in
managed code. You had to use a tool called SOS and load it in the debugger using
the Immediate window. You had to attach the debugger both in native and managed
mode, and you couldn't expect to have information in the call stack or Locals
window. You had to use commands for SOS in the Immediate window to help you go
through minidump files. With application written in native code, you used normal
debugging windows and tools. To read more about this or just to refresh your
knowledge of the topic, you can read the Bug Slayer column in MSDN magazine
Let's see the new enhancements to the minidump debugger. First you need to
create a crash from which you'll be able to generate a minidump file:
- In Solution Explorer in the PlanMyNight.Web project, rename the file Default.aspx to DefaultA.aspx. Note the A appended to the word "Default."
- Make sure you have no breakpoints left in your project. To do that, look in the Breakpoints window and delete any breakpoints left there using any of the ways you learned earlier in the chapter.
- Press F5 to start debugging the application. Depending on your machine speed, soon after the build process is complete you should see an unhandled exception of type HttpException. Although the bug is simple in this case, let's go through the steps of creating the minidump file and debugging it. Figure 7-20 shows what you should see at this point:
FIGURE 7-20 The unhandled exception you should expect
- It is time to create the minidump file for this exception. Go to the Debug menu, and select Save Dump As, as seen in Figure 7-21. You should see the name of the process from which the exception was thrown. In this case, the process from which the exception was thrown was Cassini or the Personal Web Server in Visual Studio. Keep the file name proposed (WebDev.WebServer40.dmp), and save the file on your desktop. Note that it might take some time to create the file because the minidump file size will be close to 300 MB.
FIGURE 7-21 Saving the minidump file
- Stop Debugging by pressing Shift+F5 or the Stop Debugging button.
- Next, go to the File menu and close your solution.
- In the File menu, click Open and point to the desktop to load your minidump file named WebDev.WebServer40.dmp. Doing so opens the Minidump File Summary page, which gives you some summary information about the bug you are trying to fix. (Figure 7-22 shows what you should see.) Before you start to debug, you'll get basic information from that page such as the following: process name, process architecture, operating system version, CLR version, modules loaded, as well as some actions you can take from that point. From this place, you can set the paths to the symbol files. Conveniently, the Modules list contains the version and path on disk of your module, so finding the symbols and source code is easy. The CLR version is 4.0; therefore, you can debug here in Visual Studio 2010.
FIGURE 7-22 Minidump summary page
- To start debugging, locate the Actions list on the right side of the Minidump File Summary page and click Debug With Mixed.
- You should see almost immediately a first-chance exception like the one shown in Figure 7-23. In this case, it tells you what the bug is; however, this won't always be the case. Continue by clicking the Break button.
FIGURE 7-23 First-chance exception
- You should see a green line indicating which instruction caused the exception If you look at the source code, you'll see in your Autos window that the controllerExport variable is null, and that just before that we specified that if the variable was null we wanted to have an HttpException thrown if the file to load was not found. In this case, the file to look for is Default.aspx, as you can see in the Locals window in the controllerName variable. You can glance at many other variables, objects, and so forth in the Locals and Autos windows containing the current context. Here, you have only one call that belongs to your code, so the call stack indicates that the code before and after is external to your process. If you had a deeper chain of calls in your code, you could step back and forth in the code and look at the variables. Figure 7-24 shows a summary view of all that:
FIGURE 7-24 Autos, Locals, and Call Stack windows, and the next instruction to execute
- OK, you found the bug, so stop the debugging by pressing Shift+F5 or clicking the Stop Debugging button. Then fix the bug by reloading the PlanMyNight solution and renaming the file back to default.aspx. Then rebuild the solution by going to the Build menu and selecting Rebuild Solution. Then press F5, and the application should be working again.
This next new feature, while small, is one that will delight many developers
because it saves them time while debugging. The feature is the Web.Config
transformations that allow you to have transform files that show the differences
between the debug and release environments. As an example, connection strings
are often different from one environment to the other; therefore, by creating
transform files with the different connection strings-because ASP.NET provides
tools to change (transform) web.config files-you'll always end up with the right
connection strings for the right environment. To learn more about how to do
this, take a look at the following article on MSDN:
Creating Unit Tests
Most of the unit test framework and tools are unchanged in Visual Studio 2010
Professional. It is in other versions of Visual Studio 2010 that the change in
test management and test tools is really apparent. Features such as UI Unit
Tests, IntelliTrace, and Microsoft Test Manager 2010 are available in other
product versions, like Visual Studio 2010 Premium and
Visual Studio 2010 Ultimate. To see which features are covered in the
Application Lifecycle Management and for more specifics, refer to the following
article on MSDN:
Visual Studio 2005 With Visual Studio 2005, you had to own either Visual Studio
2005 Team System or Visual Studio 2005 Team Test to have the ability to create
and execute tests out of the box within Visual Studio 2005. Another option back
then was to go with a third-party option like Nunit.
In this part of the chapter, we'll show you how to add a unit test for a class
you'll find in the Plan My Night application. We won't spend time defining what
a unit test is or what it should contain; rather, we'll show you within Visual
Studio 2010 how to add tests and execute them.
You'll add unit tests to the Plan My Night application for the Print Itinerary
Add-in. To create unit tests, open the solution from the companion content
folder. If you do not remember how to do this, you can look at the first page of
this chapter for instructions. After you have the solution open, just follow
- In Solution Explorer, expand the project PlanMyNight.Web and then expand the Helpers folder. Then double-click on the file ViewHelper.cs to open it in the code editor. Take a look at Figure 7-25 to make sure you are at the right place:
FIGURE 7-25 The PlanMyNight.Web project and ViewHelper.cs file in Solution Explorer
- In the code editor, you can add unit tests in two different ways. You can right-click on a class name or on a method name and select Create Unit Tests. You can also go to the Test menu and select New Test. We'll explore the first way of creating unit tests. This way Visual Studio automatically generates some source code for you. Right-click on the GetFriendlyTime method, and select Create Unit Tests. Figure 7-26 shows what it looks like:
FIGURE 7-26 Contextual menu to create unit tests from by right-clicking on a class name
- After selecting Create Unit Tests, you'll be presented with a dialog that, by default, shows the method you selected from that class. To select where you want to create the unit tests, click on the drop-down combo box at the bottom of this dialog and select PlanMyNight.Web.Tests. If you didn't have an existing location, you would have simply selected Create A New Visual C# Test Project from the list. Figure 7-27 shows what you should be seeing:
FIGURE 7-27 Selecting the method you want to create a unit test against
- After you click OK, the dialog switches to a test-case generation mode and displays a progress bar. After this is complete, a new file is created named TimeHelperTest.cs that has autogenerated code stubs for you to modify.
- Remove the method and its attributes because you'll create three new test cases for that method. Remove the following code:
///A test for GetFriendlyTime
// TODO: Ensure that the UrlToTest attribute specifies a URL to an ASP.NET page (for
// example, http://.../Default.aspx). This is necessary for the unit test to be
// executed on the web server,
// whether you are testing a page, web service, or a WCF service.
public void GetFriendlyTimeTest()
int totalMinutes = 0;// TODO: Initialize to an appropriate value
string expected =string.Empty; // TODO: Initialize to an appropriate value
actual = TimeHelper.GetFriendlyTime(totalMinutes);
Assert.Inconclusive("Verify the correctness of this test method.");
- Add the three simple test cases validating three key scenarios used by Plan My Night. To do that, insert the following source code right below the method attributes that were left behind when you deleted the block of code in step 5:
public void ZeroReturnsSlash()
public void LessThan60MinutesReturnsValueInMinutes()
public void MoreThan60MinutesReturnsValueInHoursAndMinutes()
Assert.AreEqual("2h 3m", TimeHelper.GetFriendlyTime(123));
- In the PlanMyNight.Web.Tests project, create a solution folder called Helpers. Then move your TimeHelperTests.cs file to that folder so that your project looks like Figure 7-28 when you are done:
FIGURE 7-28 TimeHelperTest.cs in its Helpers folder
- It is time to execute your newly created tests. To execute only your newly created tests, go into the code editor and place your cursor on the class named public class TimeHelperTest. Then you can either go to the Test menu, select Run, and finally select Test In Current Context or accomplish the same thing using the keyboard shortcut CTRL+R, T. Look at Figure 7-29 for a reference:
FIGURE 7-29 Test execution menu
- Performing this action executes only your three tests. You should see the Test Results window (shown in Figure 7-30) appear at the bottom of your editor with the test results.
FIGURE 7-30 Test Results window for your newly created tests
More Info Depending on what you select, you might have a different behavior when you choose the Tests In Current Context option. For instance, if you select a test method like ZeroReturnsSlash, you'll execute only this test case. However, if you click outside the test class, you could end up executing every test case, which is the equivalent of choosing All Tests In Solution.
New Threads Window
The emergence of computers with multiple cores and the fact that language
features give developers many tools to take advantage of those cores creates a
new problem: the difficulty of debugging concurrency in applications. The new
Threads window enables you, the developer, to pause threads and search the
calling stack to see artifacts similar to those you see when using the famous
SysInternals Process Monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx).
You can display the Threads window by going to Debug and selecting Windows And
Threads while debugging an application. Take a look at Figure 7-31 to see the
Threads window as it appears while debugging Plan My Night.
FIGURE 7-31 Displaying the Threads window while debugging Plan My Night
The Threads window allows you to freeze threads and then thaw them whenever you
are ready to let them continue. It can be really useful when you are trying to
isolate particular effects. You can debug both managed code and unmanaged code.
If your application uses threads, you'll definitely love this new feature of the
debugger in Visual Studio 2010.
Visual Studio 2005 In Visual Studio 2005, you had to uses many tools not
integrated into Visual Studio or third-party tools. And in most cases, you still
had to rely on your instinct and experience to find concurrency bugs.
In this chapter, you learned how to manage your debugging sessions by using new
breakpoint enhancements and employing new data-inspection and data-visualization
techniques. You also learned how to use the new minidump debugger and tools to
help you solve real customer problems from the field. The chapter also showed
you how to raise the quality of your code by writing unit tests and how Visual
Studio 2010 Professional can help you do this. Multicore machines are now the
norm, and so are multithreaded applications. Therefore, the fact that Visual
Studio 2010 Professional has specific debugger tools for finding issues in
applications is great news.
Finally, throughout this chapter you also saw how Visual Studio 2010
Professional has raised the bar in terms of debugging applications and has given
professional developers the tools to debug today's feature-rich experiences. You
saw that it is a clear improvement over what was available in Visual Studio
2005. The exercises in the chapter scratched the surface of how you'll save time
and money by moving to this new debugging environment and showed that Visual
Studio 2010 is more than a small iteration in the evolution of Visual Studio. It
a huge leap in productivity for developers.
The various versions of Visual Studio 2010 give you a great list of improvements
related to the debugger and testing. My personal favorites are IntelliTrace-http://msdn.microsoft.com/en-us/library/dd264915(VS.100).aspx-which
is available only in Visual Studio 2010 Ultimate and Microsoft Test Manager.
IntelliTrace enables test teams to have much better experiences using Visual
Studio 2010 and Visual Studio 2010 Team Foundation Server-http://msdn.microsoft.com/en-us/library/bb385901(VS.100).aspx.