Summary: Describes the features available in Microsoft Visual Studio Team Edition for Software Developers for improving code quality. (18 printed pages)
Note This content originally appeared in the January 2005 edition of .NET Developer's Journal. It is reproduced here with permission of the publisher.
In 1991, Microsoft released Visual Basic 1.0 and ushered in a new era of developer productivity. Building graphical user interfaces for Windows applications (which was once the domain of a select few) became instantly accessible to a broad range of developers. Over time, Visual Basic was joined by Visual C++, Visual C#, and Visual J# to form the Visual Studio suite. Although the development challenges have changed (from building desktop applications to building applications for the Internet), Visual Studio has remained true to its birthright of maximizing developer productivity.
Today, it is increasingly common, and crucial, to measure developer productivity at the team level, rather than merely at the individual level. Building software for today's global market requires a variety of disciplines working together in teams.
The introduction of Visual Studio Team System extends the promise of productivity, which was introduced in 1991, from the individual developer to these multidiscipline teams. Visual Studio Team System was designed from the ground up to recognize both the needs of the unique disciplines involved in software development today, as well as the need for these unique disciplines to work together. Figure 1 illustrates the various components that make up Visual Studio Team System.
Figure 1. Visual Studio Team System
Visual Studio Team System targets individual disciplines with editions targeted at Architects, Developers, and Testers. Each uses the traditional Visual Studio 2005 as its base. From that base, each edition adds features that reflect their namesake disciplines as well as features to reflect how these disciplines work together.
Tying these disciplines together is Team Foundation Server. Team Foundation Server provides the source-code control, work item tracking, data warehousing, and reporting that allows developers, architects, testers, and project managers to work together efficiently.
The discipline-focused Team editions and Team Foundation Server together form a comprehensive suite of technology. To help understand the best way to use this technology, Process Architecture and Guidance (PAG) content was created to illustrate how Visual Studio Team System can be used to address real-world problems.
Finally, Visual Studio Team System recognizes the importance of being a platform on which partners can build their own technology. Visual Studio Industry Partners (VSIP) has long been a part of traditional Visual Studio offers. Visual Studio Team System continues this tradition; there will be a wide range of extensibility points available in Visual Studio Team System.
This article primarily focuses on Microsoft Visual Studio Team Edition for Software Developers features. However, as we examine each feature, we will take the opportunity to explore other features that are available in Team System.
Working at AdventureWorks
As an example, suppose that we are developers working in a fictional company called "AdventureWorks." Our company sells outdoor sporting goods through its Web site, as shown in Figure 2. Our job is to implement a new feature that will allow our customers to pick up items they have purchased at a physical store, rather than having the items shipped to them.
Figure 2: AdventureWorks Web site
Working on a Team
Deciding on what code to write and communicating that choice to your team can sometimes be a clumsy affair with today's programming environments. Typically, software development teams use their own work item tracking tools; testers and project managers just do the best they can to track the progress of these work items.
The integration of Visual Studio Team Edition for Software Developers with Team Foundation Server is intended to make this workflow more natural, and therefore more productive. Work items are stored in Team Foundation Server and are accessible from a number of clients, including Visual Studio Team Edition for Software Developers. Our project managers have created a schedule and a list of work items, using Microsoft Project and Microsoft Excel, to track this new feature.
These tools are not traditional development tools. However, Visual Studio Team System was designed from the beginning to recognize the different disciplines that are part of software development, as well as the different tools that these disciplines use.
Visual Studio Team System will ship with plug-ins to Microsoft Excel and Microsoft Project that allow these tools to use Team Foundation Server to create, modify, or delete work items. Figure 3 illustrates how you can use Microsoft Excel to import work items that are actually stored in Team Foundation Server. The extensions to Excel and Project were built using Visual Studio Team System's extensibility framework.
Figure 3. Importing work items into Microsoft Excel
With the schedule and work items in hand, we can start our development work. Figure 4 shows how we would use Visual Studio Team Edition for Software Developers to view the work items that were assigned to us.
Figure 4. Viewing work items in Visual Studio
As we work (i.e., resolving work items, fixing bugs, etc.) and change the status of these work items, our project managers can refresh their spreadsheets and project plans to get an instant status update whenever they want to. Within Visual Studio Team Edition for Software Developers, we can choose whether we want to be notified when our work items in Team Foundation Server change. Figure 5 shows how we can make these choices. As we work, we can rest assured that if any of our work items change, we will be notified instantly.
Figure 5. Changing the status of work items
Writing Code: A Test-Driven Approach
Visual Studio Team System allows you to follow any number of development practices. One practice that's gaining momentum is test-driven development. This revolves around the idea of writing tests first, followed by your actual feature code. This novel approach has proved to be very effective in practice.
Visual Studio Team System is very well suited for test-driven development, so we will use it as an example. However, the scope of this article won't allow for the in-depth discussion that test-driven development deserves; a much more detailed explanation of this development practice can be found at http://msdn.microsoft.com/msdnmag/issues/04/04/ExtremeProgramming/.
Our first work item calls for us to implement in-store pickup. Because we are using a test-driven development approach, our first step will be to write the code that will test this feature, rather than the feature itself.
One of the benefits of starting with the test is that you can define the most intuitive interface for your feature first. This can occur without being influenced by how that feature may have been implemented. In our case, we will choose to expose our new functionality through a function in our business logic called DoInStorePickup.
Our first unit test (see Figure 6) is C# code. The code is decorated with attributes. These attributes are used to identify what methods in a given class represent a test and how that test should be executed.
Figure 6. C# code, with test attributes
If we were to build at this point, our test would not compile because we have not implemented the DoInStorePickup method. This is intentional. Following test-driven development, our next step is to write just enough code to make our test compile.
We can easily do this by using the refactoring features in Visual Studio 2005 to generate a stub for our new method. Visual Studio 2005 allows you to choose an arbitrary piece of source code and refactor it into various things such as methods or classes. In Figure 7 we will use this feature to generate a method stub for DoInStorePickup.
Figure 7. Generating a Stub method
After creating a stub for DoInStorePickup, we can build and run our test from within Visual Studio Team Edition for Software Developers. Figure 8 illustrates the simple, easy-to-use user interface part for organizing, executing, and monitoring the process of our unit tests. More extensive organizational features are available with Visual Studio Team Edition for Software Testers.
Figure 8. Organizing unit tests
As you can see in Figure 8, the first attempt at running our test has failed. This is another intentional aspect of test-driven development. Our next step is to add just enough functionality to InStorePickup to allow our test to pass.
By using this iterative process of writing a test and then writing just enough functionality to allow it to pass, we can build toward more complicated functionality. The final product of our test-driven efforts will be a fully implemented feature with a full suite of unit tests that will catch possible regressions in the future. As an example, we will fast forward through this process and finish off our method. Figure 9 shows the complete code for our DoInStorePickup method.
Figure 9. Complete DoInStorePickup method
One benefit of test-driven development is that the tests usually execute a high percentage of our feature code. One of the many attributes that we can configure as part of a unit test run is one that automatically collects code coverage data. Figure 10 shows how we can select which artifacts (i.e., Visual Studio projects and binaries) we want to collect code coverage for.
Figure 10. Selecting artifacts for code coverage
Code coverage results are organized in a hierarchical manner by namespace, class, and method. Code coverage data in this form is well suited for merging between runs or publishing as part of a larger report. Figure 11 illustrates how code coverage results are just another aspect of test results.
Figure 11. Code coverage results
For day-to-day development or whenever more immediate feedback is needed, Visual Studio Team Edition for Software Developers can report code coverage in its natural environment: source code. Figure 12 shows how code coverage results are associated with your source code.
Figure 12. Code coverage with code
Lines that were executed are shown in green, uncovered lines are shown in red, and partially covered lines are shown in blue. Lines of code that are branches or loops are most often partially covered. In our example, we can see that we missed an entire method. Unit testing is also available in its natural environment. In the code editor, we can choose what we want to test and automatically create a unit test. Figure 13 shows how this functionality is integrated into Visual Studio's code editor. The resulting unit test is very similar to the one we just hand-coded. Generating unit tests automatically can be very useful if you already have an existing code base to generate a suite of unit tests.
Figure 13. Automatically generating unit tests
Saving Our Work: Using Source-Code Control
With our in-store pickup feature written, the next logical step would be to check-in our changes. Visual Studio Team System introduces a completely new, enterprise-level source-code control system that is an integral part of Team Foundation Server. Figure 14 shows one aspect of this new system: the pending check-ins dialog box.
Aside from seeing what files need to be checked-in, with this dialog box you can query to find work items to associate with this check-in. Work items associated in this manner are automatically checked-in. The check-in notes page on this dialog box is a customizable interface that your organization can use to gather information pertinent to a given check-in.
Figure 14. Pending check-ins
The last aspect of this dialog allows us to introduce another feature in Visual Studio Team Edition for Software Developers. Team Foundation Server allows you configure and optionally create policies that are enforced with each check-in. One of the policies you can enable specifies static code analysis should be run before each check-in.
Automatic Code Reviews
Static code analysis is essentially an automated code review; it is available in Visual Studio Team Edition for Software Developers for both .NET and C/C++ source code. For .NET, the analysis is done based on a set of configurable warnings (see Figure 15). These warnings identify known issues involving security, performance, design, and general quality. Continuing with the theme of extensibility in Visual Studio Team System, you can write your own plug-ins and use them with managed code analysis.
Figure 15. Configurable warnings
When we run code analysis on our example, we see that several issues are identified in our source code. Code analysis warnings are shown in Visual Studio's task list so they should be familiar to any developer. Code analysis for C/C++ is specially tuned to identify potential security vulnerabilities such as buffer overruns. The exact code paths to these types of errors (which are not as common in .NET code) are highlighted directly in Visual Studio's code editor. Figure 16 shows the path of execution that is vulnerable to a buffer-overflow.
Figure 16. Vulnerable code
For some warnings, we may want to do some more in-depth investigation. We can use Team Foundation Server to file bugs directly against these warnings. Figure 17 shows an example of how we can create a bug based on a code analysis warning.
Figure 17. Creating a bug based on code analysis
Once we correct these warnings, we will be able to check our changes into Team Foundation Server. Code analysis gives us confidence that our source code has passed a rigorous analysis against known issues.
Before we call it a day, our last step will be to investigate the performance characteristics of the code we just wrote. There are a number of ways to start a performance investigation; for this article, we will go back to our unit test. Based on our code coverage results, we know our unit test does a good job of exercising our source code. Now, let's use that unit test to drive our performance investigation.
We can create a Performance Session directly from the result of our unit test. Figure 18 shows an example of how this is done.
Figure 18. Creating a performance session
Writing Efficient Code
The Visual Studio Team Edition for Software Developers Performance Tools trace their technological roots back almost a decade to the labs of Microsoft Research. At that time, Microsoft Research was responsible for a set of performance tools that was created to help optimize products such as Windows Server 2003 and SQL Server. From these efforts came technology that would eventually find its way into Visual Studio Team Edition for Software Developers—albeit in a much more refined, enterprise-friendly form. Visual Studio Team Edition for Software Developers allows us to gather performance data at a number of levels. We can use a method of profiling called sampling to get a very high-level view of the potential hotspots in our application. From there, we can use Visual Studio Team Edition for Software Developers to insert timing probes into our application; this process is called instrumentation. This method of profiling allows us to gather very detailed performance data about specific areas in our application. For .NET applications, we can gather data about how our application is using memory. This is often a key factor in how an application performs.
Visual Studio Team Edition for Software Developers hides all of the complexity of configuring an application for profiling behind a wizard (see Figure 19). We can choose to profile .NET, ASP.NET, or C/C++ applications, and Visual Studio Team Edition for Software Developers will ensure that our application is properly configured for profiling.
Figure 19. Configuring an application for profiling
Once Visual Studio Team Edition for Software Developers has gathered data about our application, we generate a performance report based on this data. This report can be viewed in a number of different ways depending on whether you want to see how functions call each other, a sequence of events, or a list of all function called by your applications.
It's very easy to gather a lot of performance data for an application. To help cope with this data, you can generate a summary that highlights key areas where you might choose to start your investigation.
For example, a histogram can be rendered to show your .NET application is using garbage collection. A suspicious pattern in this histogram would lead you to the Allocations view shown in Figure 20. This view shows all of the .NET types that were allocated by your application, and the functions that did the allocation. This view allows you to quickly spot any objects that might be causing problematic garbage collection patterns.
Figure 20. Allocations view
Once we have fixed any possible performance issues or entered work items for them in Team Foundation Server, we're ready to check-in our work. We can associate our check-in with the work items that started us off.
These work items will be automatically resolved and the project managers at AdventureWorks who created them can easily see the progress we've made in their Excel spreadsheets or Project plans. Figure 21 shows all of our initial work items completed.
Figure 21. Initial work items completed
Visual Studio Team Edition for Software Developers takes the best of Visual Studio 2005 (programming languages, debuggers, libraries, etc.), and extends it with features targeted toward developers working on a team. The goal of Visual Studio Team Edition for Software Developers, and Team System as a whole, is to take the vision of productivity that created Visual Studio in the first place and extend it to the enterprise. We found that the challenge to realizing this vision is not just in how developers, testers, project managers, and architects worked on their own, but it is also in how they work together. Every aspect of Visual Studio Team System 2005 was carefully designed and scrutinized to ensure that they work together seamlessly. From this crucible comes a product, like its distant cousin, Visual Basic 1.0, that will usher in a new standard of developer productivity.
About the author
Eric Lee graduated from the University of Windsor Ontario in 1998 and joined Microsoft shortly afterwards. He has spent his career at Microsoft as a tester, developer, and now product manager for the Developer Tools division. Eric previously held positions on the Windows Server 2003 team, where he contributed to Enterprise UDDI Services.