<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Ivo Manolov's Blog</title><link>http://blogs.msdn.com/b/ivo_manolov/</link><description>.NET, WPF and Win32 Programming</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Debug Build: 5.6.50428.7875)</generator><item><title>Model-View-ViewModel (MVVM) Applications: General Introduction</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2012/03/17/10284665.aspx</link><pubDate>Sat, 17 Mar 2012 23:35:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10284665</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10284665</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2012/03/17/10284665.aspx#comments</comments><description>&lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;MVVM is a central concept in WPF, Silverlight, WindowsPhone and Windows 8 development, so I decided to take some time and bubble up some of the content in the &lt;/em&gt;&lt;a href="http://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;amp;referringTitle=Home"&gt;&lt;em&gt;WPF MVVM Toolkit&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, which we created some time ago.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Model-View separation is by no means a novel idea in the software engineering industry—the idea has been around for at least 25 years. In the past few years, there has been a lot of interest in model-view architectures, fuelled both by the growing complexity of modern software systems and by the necessity to display UI on various devices, while reusing the same underlying business logic.&lt;/p&gt;  &lt;p&gt;This post outlines the benefits of model-view separation. It is essentially the same content as the content included in Part 1 of the documentation, which goes with the WPF MVVM Toolkit. &lt;/p&gt;  &lt;h1&gt;1. Introduction to the Model-View-X Paradigm&lt;/h1&gt;  &lt;p&gt;A well-designed application is an application that is easy to develop, test, maintain, and evolve. Creating such an application typically involves some form of &lt;i&gt;separation and encapsulation of responsibilities&lt;/i&gt;. A common approach involves separation of the UI (the views) from the business logic (the model). In fact, that approach is so common that there are a number of stock solutions, collectively known as the &lt;i&gt;model-view design patterns:&lt;/i&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;u&gt;Model-View-Controller (MVC)&lt;/u&gt; is the granddaddy of them all, dating back to 1979. In MVC, the Controller creates the Views and the Model. The Views register with the Controller, which also has a reference to the Model. A View notifies the Controller of user interactions, and the Controller in turn queries the View for its state and updates the Model appropriately. The Controller notifies the Views when there are changes in the Model, and the Views query the controller to update their states.       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;u&gt;Model-View-ViewModel (MVVM)&lt;/u&gt; is a derivative of MVC that takes advantage of particular strengths of the Windows Presentation Foundation (WPF) architecture to separate the Model and the View by introducing an abstract layer between them: a “Model of the View,” or ViewModel. The pattern was first introduced by &lt;strong&gt;John Gossman&lt;/strong&gt; – the architect on the Blend/WPF/Silverlight team – and derives from the Smalltalk ApplicationModel pattern, as does the PresentationModel pattern described by Martin Fowler. It was first utilized by the Expression team (John was part of that team at the time) as they developed version 1 of Expression Blend. Without the WPF/Silverlight-specific aspects, the Model-View-ViewModel pattern is identical to PresentationModel.       &lt;br /&gt;      &lt;br /&gt;In MVVM, the View and the ViewModel are typically instantiated by the container application. The View keeps a reference to the ViewModel. The ViewModel exposes commands and observable entities (“bindables”) that the View binds to (or to put it in programming terms, view.DataContext = viewModel;). User interactions with the View trigger commands on the ViewModel, and updates in the ViewModel are propagated to the View through data binding. &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;2. Justification&lt;/h1&gt;  &lt;h2&gt;2.1. Simplistic Application Design&lt;/h2&gt;  &lt;p&gt;To demonstrate the use of the Model-View-X architecture, let’s consider a simple contacts application. The application has two windows (views): a table view, where you can see all entries in the contact book in a table, and a record view, where you can see individual records. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/6507.clip_5F00_image002_5F00_46B4FC7F.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/8255.clip_5F00_image002_5F00_thumb_5F00_25C189D8.jpg" width="623" height="249" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 1&lt;/strong&gt; UI of the contacts application&lt;/p&gt;  &lt;p&gt;The Model-View separation for this particular problem feels natural, where the Model is the contact book and the Views are the two windows shown in Figure 1. So the trivial design (which is a two-tier Model-View-only design) would look as shown on Figure 2.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/5432.clip_5F00_image002_5F00_7A10BFDB.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/3465.clip_5F00_image002_5F00_thumb_5F00_247CF0F9.gif" width="595" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 2&lt;/strong&gt; Simplistic application design – the views are directly connected to the model&lt;/p&gt;  &lt;p&gt;As shown, ContactBook keeps a list of views (which are added and removed with AttachView and DetachView). When a contact changes, ContactBook notifies all views by calling their Update methods, and all views update themselves by calling the model's GetContacts method. Upon instantiation, RecordView and TableView are given a reference to ContactBook, which they keep as a field (contactBook). &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#c0504d"&gt;&lt;em&gt;Notice how the two views are tightly coupled with the &lt;b&gt;ContactBook&lt;/b&gt; class. Addition of business logic would only increase the level of coupling.&lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;2.2. Simplistic Application Design – WPF/Silverlight Version &lt;/h2&gt;  &lt;p&gt;Before examining the design further, let’s convert the design to a WPF/Silverlight-friendly design. WPF/Silverlight provides the following native facilities that can be utilized directly:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;i&gt;Databinding&lt;/i&gt; is the ability to bind UI elements to any data. &lt;/li&gt;    &lt;li&gt;&lt;i&gt;Commands&lt;/i&gt; provide the ability to notify the underlying data of changes in the UI. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Using these facilities, the WPF/Silverlight-friendly design is changed as follows:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0652.clip_5F00_image0026_5F00_7CD674CE.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[6]" border="0" alt="clip_image002[6]" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/2308.clip_5F00_image0026_5F00_thumb_5F00_6A217B17.gif" width="595" height="205" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 3&lt;/strong&gt; WPF/Silverlight-friendly simplistic application design&lt;/p&gt;  &lt;p&gt;In the modified design in Figure 3, the views derive from &lt;b&gt;UserControl&lt;/b&gt; (there is no need for an abstract View class) and ContactBook no longer needs to maintain a list of views—ContactBook no longer needs to know about the views. Instead, the views point to ContactBook as their &lt;b&gt;DataContext&lt;/b&gt; and use WPF data-binding to bind to the list of contacts. &lt;/p&gt;  &lt;p&gt;You will also notice that List&amp;lt;Contact&amp;gt; has been replaced with &lt;a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection&lt;/a&gt;&amp;lt;Contact&amp;gt; to allow the views to bind to the ContactBook using WPF data-binding mechanisms.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&lt;font color="#c0504d"&gt;Notice how WPF’s data-binding mechanism allows us to create a much more a loosely coupled design (at least until further addition of business logic).&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;2.3. Problems with the Simplistic Design&lt;/h2&gt;  &lt;p&gt;Things get more complicated if we introduce the following new functionality:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Track the selected item, so that we update RecordView whenever the selection in TableView changes, and vice versa. &lt;/li&gt;    &lt;li&gt;Enable or disable parts of the UI of RecordView and TableView based on some rule (for example, highlight any entry that has an e-mail in the live.com domain). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Feature (a) can be implemented by adding a&lt;b&gt; &lt;/b&gt;CurrentEntry property directly in ContactBook. This solution breaks down, however, if you have more than one instance of the UI connected to the same ContactBook. Feature (b) can be implemented in the views (RecordView and TableView). The problem if we do that, however, is that if we want to change the rule, then we would need to change both views. &lt;/p&gt;  &lt;p&gt;Gradually it becomes apparent that we need a third layer in our application. We need a layer between the views and ContactBook that stores state shared by the views. We need a &lt;i&gt;meta-view&lt;/i&gt; of sorts.&lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;2.4. Enter Model-View-ViewModel (MVVM)&lt;/h2&gt;  &lt;p&gt;A ViewModel can serve as the third layer, providing an abstraction that acts as a meta-view&lt;i&gt; &lt;/i&gt;(a model of a view), storing state and policy that are shared by a group of views. By introducing the concept of a ViewModel, our design changes to the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0714.clip_5F00_image0028_5F00_427AFEED.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[8]" border="0" alt="clip_image002[8]" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/7242.clip_5F00_image0028_5F00_thumb_5F00_61BDA5C0.gif" width="659" height="203" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 4&lt;/strong&gt; Application design using a ViewModel&lt;/p&gt;  &lt;p&gt;In this design, the views know of the ViewModel and bind to its data, to be able to reflect any changes in it. The ViewModel has no reference to the views—it holds only a reference to the model. &lt;/p&gt;  &lt;p&gt;For the views, the ViewModel acts both as a façade to the model, but also as a way to share state between views (selectedContacts in the example). In addition, the ViewModel often exposes commands that the views can bind to and trigger.This use of commands is covered in the next section.&lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;2.5. The use of commanding in MVVM Applications&lt;/h2&gt;  &lt;p&gt;WPF and Silverlight introduce a new input programming mechanism: &lt;a href="http://msdn.microsoft.com/en-us/library/ms752308.aspx"&gt;commanding&lt;/a&gt;. Commands allow loose coupling between the origin and the handling of an action. Multiple sources can invoke the same command, and the same command can be handled differently depending on the target. All commands implement the &lt;a href="http://msdn.microsoft.com/library/system.windows.input.icommand.aspx"&gt;ICommand&lt;/a&gt; interface. &lt;/p&gt;  &lt;p&gt;For UI actions, WPF provides a specialized &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.routedcommand.aspx"&gt;RoutedCommand&lt;/a&gt; class. A &lt;b&gt;RoutedCommand&lt;/b&gt; is routed through the UI element tree, so the target of a &lt;b&gt;RoutedCommand&lt;/b&gt; must be part of the UI element tree. In MVVM designs, however, command targets are often implemented in the ViewModels, which in turn are not typically part of the UI element tree. This requires the introduction of a different kind of command—the &lt;a href="http://msdn.microsoft.com/en-us/library/cc707894.aspx"&gt;DelegateCommand&lt;/a&gt;—that implements &lt;b&gt;ICommand&lt;/b&gt; and can have non-UI elements as its target. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/1374.clip_5F00_image00210_5F00_2EED9F4C.gif"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image002[10]" border="0" alt="clip_image002[10]" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/5187.clip_5F00_image00210_5F00_thumb_5F00_2042F367.gif" width="660" height="279" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 5&lt;/strong&gt; Application design using a ViewModel, exposing bindable commands&lt;/p&gt;  &lt;p&gt;The DelegateCommand construct was originally introduced during the development of Microsoft Expression Blend version 1. A generic version of DelegateCommand was later released as part of the &lt;a href="http://msdn.microsoft.com/en-us/library/dd458807.aspx"&gt;Composite Application Guidance for WPF&lt;/a&gt; on MSDN. Note that some MVVM sources refer to the same construct as RelayCommand.&lt;/p&gt;  &lt;p&gt;A &lt;b&gt;DelegateCommand&lt;/b&gt; is an &lt;b&gt;ICommand&lt;/b&gt; that allows the views to bind to the ViewModel. Even though the diagram above does not show this explicitly, all ICommands exposed by the ViewModel are DelegateCommands. For example, the code for the AddContactCommand in the ViewModel may look as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/0218.image_5F00_54771CAD.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-88-37-metablogapi/2451.image_5F00_thumb_5F00_37FA2ACD.png" width="648" height="238" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;3. Benefits and Consequences of Using MVVM&lt;/h1&gt;  &lt;p&gt;The benefits of MVVM are the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A ViewModel provides a single store for presentation policy and state, thus improving the reusability of the Model (by decoupling it from the Views) and the replaceability of the Views (by removing specific presentation policy from them). &lt;/li&gt;    &lt;li&gt;The Model-View-ViewModel design improves the overall testability of the application. One can easily create unit tests that target the Model and the ViewModel layers. The MVVM design also improves the “mockability” of the application, by allowing easy run-time simulation of the tiers, which is crucial to testing complex software products. &lt;/li&gt;    &lt;li&gt;The Model-View-ViewModel design is a very loosely coupled design. The View holds a reference to the ViewModel, and the ViewModel holds a reference to the Model. The rest is done by the data-binding and commanding infrastructure of WPF. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The consequences of MVVM are the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The typical relationship between a ViewModel and the corresponding Views is one-to-many, but there are also situations where that is not necessarily true. In general, any business logic and input-handling business logic (selection tracking, and so on) is kept in the ViewModel. &lt;/li&gt;    &lt;li&gt;There are situations when one ViewModel is aware of another ViewModel within the same application. Such situations arise when there is a master-subordinate relationship between two ViewModels or when a ViewModel represents a single item (for example, the visual representation state of a single contact). When this happens, one ViewModel can represent a collection of ViewModels. Such a case in demonstrated in the 2nd part of documentation that comes with the &lt;a href="http://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;amp;referringTitle=Home"&gt;WPF MVVM Toolkit&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;4. Next Steps and References&lt;/h1&gt;  &lt;p&gt;Hopefully this post provides a simple introduction to the pattern. As a next step, download the &lt;a href="http://wpf.codeplex.com/wikipage?title=WPF%20Model-View-ViewModel%20Toolkit&amp;amp;referringTitle=Home"&gt;WPF MVVM Toolkit&lt;/a&gt;, review the walk-through and the provided code and go write some apps. &lt;/p&gt;  &lt;p&gt;It is important to note that there are a number of other (more full-featured) MVVM toolkits out there. Perhaps the most popular one is &lt;a href="http://mvvmlight.codeplex.com/"&gt;Laurent Bugnion’s MVVM Light&lt;/a&gt;, but there are many others &lt;a href="http://www.codeplex.com/site/search?query=mvvm&amp;amp;ac=8"&gt;on Codeplex&lt;/a&gt;. You should be using those for your WPF / Silverlight / Windows Phone and Windows 8 applications. Here are a few additional references that may help too:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html"&gt;Presentation Model&lt;/a&gt; by Martin Fowler, July 2004. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx"&gt;Introduction to Model/View/ViewModel pattern for building WPF apps&lt;/a&gt; by John Gossman, October 2005. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.martinfowler.com/eaaDev/SeparatedPresentation.html"&gt;Separated Presentation&lt;/a&gt; by Martin Fowler, June 2006. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.sqlxml.org/bryantlikes/archive/2006/09/27/WPF-Patterns.aspx"&gt;WPF Patterns&lt;/a&gt; by Bryan Likes, September 2006. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.orbifold.net/default/?p=550"&gt;WPF patterns: MVC, MVP or MVVM or…?&lt;/a&gt; by the Orbifold, December 2006. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mikehillberg/archive/2008/05/21/Model-see_2C00_-model-do.aspx"&gt;Model-see, Model-do, and the Poo is Optional&lt;/a&gt; by Mike Hillberg, May 2008. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc785479.aspx"&gt;PRISM: Patterns for Building Composite Applications with WPF&lt;/a&gt; by Glenn Block, September 2008. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx"&gt;The ViewModel Pattern&lt;/a&gt; by David Hill, January 2009. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;WPF Apps with the Model-View-ViewModel Design Pattern&lt;/a&gt; by Josh Smith, February 2009. &lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10284665" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/-NET+3-5/">.NET 3.5</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Architecture/">Software Architecture</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Windows+Phone+7/">Windows Phone 7</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/MVVM/">MVVM</category></item><item><title>Principles 5: End-to-End Development Process (for Large Projects)</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx</link><pubDate>Fri, 22 Apr 2011 06:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10136580</guid><dc:creator>ivom1</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10136580</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx"&gt;Principles 1: The Essence of Driving – A Crash Course in Project Management&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx"&gt;Principles 2: Principles of Software Testing&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx"&gt;Principles 3: Principles of Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx"&gt;Principles 4: End-to-End Development Process&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank"&gt;Principles 5: End-to-End Development Process&amp;#160;&amp;#160; (for Large Projects)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p align="left"&gt;This fifth post discusses and end-to-end development process for large software projects. &lt;/p&gt;  &lt;p align="left"&gt;The only difference between large and small projects is that large projects require more “supporting infrastructure” (more processes, etc.) than small projects, due to the fundamentally imperfect communication between the team members. The “supporting infrastructure” is a tax we have to pay when we develop software. We can minimize it, but we can never really avoid it completely.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;strong&gt;&lt;em&gt;Larger projects require larger teams, which (due to accumulated communication imperfections) require larger process tax. &lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;On one hand, we like short product cycles, because they get the product out in the market quickly; on another hand, the shorter the cycle, the higher the ratio between process tax and actual productive time. This is a classic case of an optimization problem, which can be defined as…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;&lt;em&gt;&lt;font size="3"&gt;“Find the shortest possible project cycle, that keeps the process tax at a reasonably low level&lt;/font&gt;&lt;/em&gt;“.&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Clearly, there’s a variety of other factors that we need to consider when we talk about project and product cycles. To list a few, we need to factor in the general product business model, pre-existing contractual obligations, specific calendar events such as conferences or trade shows, the competitive landscape, etc. For the purpose of this article we can assume that all of these additional factors have already been taken into consideration.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Single Project Rhythm&lt;/h1&gt;  &lt;p&gt;I am a big believer in having a single, transparent, well-socialized and strictly enforced project rhythm. All products that an organization delivers in my opinion should be aligned to this single rhythm.&amp;#160; The rhythm (or cycle) should be short enough, so that it can accommodate all products in development. In this model, different products can take different number of cycles. At the end of every cycle, one or more products get released. &lt;/p&gt;  &lt;p&gt;Having a single cycle in my opinion dramatically decreases the complexity (and ultimately the process tax) that a team has to pay. It helps create well-aligned, synchronized and cohesive organizations, reduces dramatically the release management costs of a product, practically eliminates context switching for the individual engineers, drives ownership deep into the organization, improves communication with supporting disciplines (docs, localization, support, sustained engineering), and so on.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Agility&lt;/h1&gt;  &lt;p&gt;In this model, agility is achieved by having an appropriately-sized cycle. For example, for a desktop OS the right cycle may be 6 months or 12 months. In contrast, a web site would probably need to have a release valve every 2 to 4 weeks. Agility doesn’t mean lack of planning – agility means a reasonably short cycle capable of getting high quality products out in a predictable, controlled fashion.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Process Summary&lt;/h1&gt;  &lt;p&gt;The process of developing a large software project can be organized in 4 major phases (see Fig. 1 below):&lt;/p&gt;  &lt;ol type="A"&gt;   &lt;li&gt;MQ &lt;/li&gt;    &lt;li&gt;Pre-planning and Planning &lt;/li&gt;    &lt;li&gt;1 or more Development Cycles &lt;/li&gt;    &lt;li&gt;Stabilization and Release &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;(A) and (B) happen simultaneously. (A) is “Milestone for Quality” targeted at constructing a high-quality “software production factory”. This milestone gives the engineering organization a chance to optimize and simplify the tools and processes that it uses to product the product. (B) follows a predefined planning process. Planning is a whole other topic in itself. (C) consists of one or more close-looped development cycles.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5488.image_5F00_21C68533.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="Figure 1  Development Process Outline" border="0" alt="Development Process Outline" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1072.image_5F00_thumb_5F00_52E5BFD3.png" width="589" height="229" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 1&lt;/strong&gt;&amp;#160; Development Process Outline&lt;/p&gt;  &lt;p&gt;Obviously this is just a general outline. The size of the different phases has to be determined by the development organization, based on deep understanding of what needs to happen in these phases and on the current state of the business and of the development factory. Some phases (specifically A and B) may shrink if there is no need for them. &lt;/p&gt;  &lt;p&gt;Below I show an actual implementation of this general outline. Each small rectangle represents one week. Weeks in green are “stabilization weeks” (stabilization has different meaning for the different milestones – see tables below). Note again that the size of the actual milestones and phases that I show below are just a specific implementation of the general outline. You can have development cycles that are as short as a week, if you think that the ratio of dev time to process tax associated with managing every cycle is reasonable. You can also have longer cycles, although I personally wouldn’t recommend cycles that are significantly longer that 18 weeks or so. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7026.image_5F00_4E6F3F0C.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Figure 2  Development Process - Detailed View" border="0" alt="Development Process - Detailed View" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5861.image_5F00_thumb_5F00_391189A4.png" width="100%" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 2&amp;#160; &lt;/strong&gt;Development Process - Detailed View&lt;/p&gt;  &lt;p&gt;With these sizes we have…&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;About 18 weeks (4 months) of pre-planning and planning activities. &lt;/li&gt;    &lt;li&gt;One or more dev cycles of 15 weeks (3.5 months) &lt;/li&gt;    &lt;li&gt;Final stabilization of 10 weeks (2.5 months) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I.e. a release with 1 dev cycle takes about 9.5 months; a release with 2 dev cycles takes about 13 months, etc.&lt;/p&gt;  &lt;p&gt;The number of the actual development cycles can vary and is a purely business decision. At the end of every development cycle, the organization delivers shippable functionality. When management deems that the available payload makes sense as a next major version of the product, they switch the team to the RTM (RTW) phase, and drive to an actual release. &lt;/p&gt;  &lt;p&gt;Before we delve in MQ, it’s important to note that all of these phases are divided in “red weeks” and “green weeks” (a block denotes a week). “Red weeks” are weeks of active development, “green weeks” are weeks of stabilization. Obviously the actual activities that happen in these weeks depend on the phase of the project.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;MQ&lt;/h1&gt;  &lt;p&gt;MQ is the Quality Milestone. The role of MQ is ensuring that we have a working high-quality “production factory” before we embark on producing the next version of the product. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8816.image_5F00_7F8E79AC.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 3  MQ and Planning" border="0" alt="MQ and Planning" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6355.image_5F00_thumb_5F00_383923BA.png" width="453" height="255" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 3&lt;/strong&gt;&amp;#160; MQ and Planning&lt;/p&gt;  &lt;p&gt;The breakdown of MQ is as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7024.image_5F00_1ED12080.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 4  Breakdown of MQ" border="0" alt="Breakdown of MQ" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8816.image_5F00_thumb_5F00_654E1088.png" width="684" height="495" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 4 &lt;/strong&gt; Breakdown of MQ&lt;/p&gt;  &lt;p&gt;MQ is all-inclusive collaborative effort between the 3 disciplines. The majority of PM, Dev and Test will be working on MQ activities during MQ. A few PMs and Devs will be working on planning / prototyping in parallel. MQ is planned and rigorously project-managed. MQ has a set of exit criteria that the org needs to hit before exiting the milestone.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;The Dev Cycle&lt;/h1&gt;  &lt;p&gt;All features are developed during the dev cycle, which looks as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6355.image_5F00_16D97E1E.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 5  Dev Cycle" border="0" alt="Dev Cycle" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8510.image_5F00_thumb_5F00_4F84282B.png" width="462" height="254" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 5&lt;/strong&gt;&amp;#160; Dev Cycle&lt;/p&gt;  &lt;p&gt;There is a single prioritized feature backlog that captures all features that are being worked on in the current development cycle or can be worked on in future cycles. The list of features that comprise the current development cycle is &lt;u&gt;stable throughout the cycle&lt;/u&gt; i.e. &lt;u&gt;Management does not change the list beyond M0&lt;/u&gt; – they have to wait for the next M0.&lt;/p&gt;  &lt;p&gt;Any feature that cannot be completed is “cut” until the new dev cycle. Features that take more than one dev cycle to complete will be split into smaller manageable “featurettes” can be completed within the constraints of a dev cycle. Several featurettes may comprise the final feature. At the start of the development new cycle the feature is re-evaluated again against the other features in the backlog.&lt;/p&gt;  &lt;p&gt;The start of every new dev cycle is a clean slate. All bugs and features are automatically “cut” and need to be reevaluated and brought back (can be evaluated and brought back during)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;font color="#000000"&gt;&lt;em&gt;&lt;strong&gt;IMPORTANT: The development cycle is a contained unit of delivery of added value. We can have as many development cycles as necessary to build a compelling value for the “big release”, but every one of them ends with high quality features that are ready to ship.&lt;/strong&gt; &lt;/em&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The breakdown of the development cycle is as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2630.image_5F00_4F17F536.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 6  Breakdown of a Dev Cycle" border="0" alt="Breakdown of a Dev Cycle" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6431.image_5F00_thumb_5F00_23672B3A.png" width="689" height="722" /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p align="center"&gt;&lt;strong&gt;Figure 6&lt;/strong&gt;&amp;#160; Breakdown of a Dev Cycle&lt;/p&gt;  &lt;p&gt;The M0 to M4 cycle can be repeated multiple times within a release. Every time in M0 (but only in M0), executive management gets to redefine the feature backlog.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Stabilization and Release&lt;/h1&gt;  &lt;p&gt;The final phase in the development process (disregarding the various post-release activities for now) is the “Stabilization and Release” phase or “RTM”. &lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2727.image_5F00_49C90E85.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 7  Stabilization and Release (&amp;quot;RTM&amp;quot;)" border="0" alt="Stabilization and Release (&amp;quot;RTM&amp;quot;)" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6763.image_5F00_thumb_5F00_346B591D.png" width="453" height="201" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 7&lt;/strong&gt;&amp;#160; Stabilization and Release (“RTM”)&lt;/p&gt;  &lt;p&gt;This phase is about fixing bugs, integration (if necessary) and managing the final quality of the release. The breakdown is as follows:&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3730.image_5F00_48F0A89B.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 8  Breakdown of Stabilization and Release" border="0" alt="Breakdown of Stabilization and Release" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0564.image_5F00_thumb_5F00_214A2C71.png" width="685" height="207" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 8&lt;/strong&gt;&amp;#160; Breakdown of Stabilization and Release&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;QFEs (Hotfixes)&lt;/h1&gt;  &lt;p&gt;Every large software project needs to have a mechanism to deal with hotfixes (also known as &lt;a href="http://en.wikipedia.org/wiki/QFE" target="_blank"&gt;QFEs&lt;/a&gt;). The nature of these fixes requires reactive delivery (as opposed to the proactive approach described above). Teams typically maintain a separate source code branch (or branches) for QFEs and that is typically the same as the branch that contains the currently shipping version of the software. &lt;/p&gt;  &lt;p&gt;Due to their reactive nature QFEs are delivered on demand with a release schedule that looks as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1641.image_5F00_6BD16A4B.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Figure 9  QFE Release and RI Schedule" border="0" alt="QFE Release and RI Schedule" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2727.image_5F00_thumb_5F00_2724D00A.png" width="533" height="294" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 9&lt;/strong&gt;&amp;#160; QFE Release and RI Schedule&lt;/p&gt;  &lt;p&gt;Typically, fixes introduced in the QFE branch must make their way into the Main product branch, which is done with a series of regular reverse integrations (or RIs) as shows above. QFEs also get packaged as larger packages and released as service packs (or SPs).&lt;/p&gt;  &lt;p&gt;Every QFE is subjected to a root-cause analysis, following a simple standard template, to help the team avoid similar situations in the future.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;        &lt;h1&gt;Templates and Artifacts&lt;/h1&gt;  &lt;p&gt;Last but not least I wanted to provide a quick list with some of the fundamental documents that are required to bootstrap a development process for a larger product. Note that this list is nothing more than a reasonable starting point – at least according to me. &lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0574.image_5F00_71AC0DE4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Figure 10  Key Templates and Artifacts" border="0" alt="Key Templates and Artifacts" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6740.image_5F00_thumb_5F00_05C52A6E.png" width="713" height="493" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 10&lt;/strong&gt;&amp;#160; Key Templates and Artifacts&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;There are many ways to ship software products. Large products require more pampering and more scaffolding, at least until a critical mass of the team adopts a coherent product development culture. If you want to ship high quality products, you need to invest in rationalizing your product development cycle. The best way to do that is to plan, using a series of thought experiments (e.g. “imagine that we have achieved code complete, what are the steps from CC to release ready and how long are they realistically going to take”), and a guiding principle of lowest possible overhead costs and highest possible simplicity. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10136580" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>Updating Your WP7 (and Dealing with Error 800705B4)</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10156905.aspx</link><pubDate>Thu, 21 Apr 2011 23:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10156905</guid><dc:creator>ivom1</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10156905</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10156905.aspx#comments</comments><description>&lt;p&gt;I have had a Samsung Focus WP7 device for several months now and I absolutely love it. I love the hardware (fantastic bright display, sleek look, etc.), I love the Metro UI, and I love the development tools. VS 2010 and Silverlight for WP7 are a ton of fun.&lt;/p&gt;  &lt;p&gt;Like many of you I patiently waited for the February and March updates and just yesterday, at the end of April, I finally got prompted to install them. Unfortunately, as I hooked up the phone to my PC to update it, I hit error 800705B4.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2350.clip_5F00_image001_5F00_05972D74.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7462.clip_5F00_image001_5F00_thumb_5F00_19441708.jpg" width="378" height="435" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Error code 800705B4 resolves to the following:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;0:000&amp;gt; !error 800705B4 Error code:      &lt;br /&gt;(HRESULT) 0x800705b4 (2147943860) - This operation returned because the timeout period expired.&lt;/code&gt; &lt;/p&gt;  &lt;p&gt;Since it took me a bit of digging to recover from it, I wanted to share here the fast way to overcoming this error:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Go to &lt;a title="http://support.microsoft.com/kb/2530409" href="http://support.microsoft.com/kb/2530409"&gt;http://support.microsoft.com/kb/2530409&lt;/a&gt; and download the &lt;strong&gt;Windows Phone Support Tool&lt;/strong&gt; for your PC platform.&lt;/li&gt;    &lt;li&gt;Follow the instructions in the tool. You won’t lose any of your information.&lt;/li&gt;    &lt;li&gt;After the tool is done recovering your phone, hook it up to Zune again and get the update successfully.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Hopefully, that’ll save folks out there some time reading through MSDN docs.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10156905" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Windows+Phone+7/">Windows Phone 7</category></item><item><title>TestApi v0.6 Released!</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2011/02/07/10125931.aspx</link><pubDate>Tue, 08 Feb 2011 00:19:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10125931</guid><dc:creator>ivom1</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10125931</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2011/02/07/10125931.aspx#comments</comments><description>&lt;p&gt;I am happy to announce that we have just released version 0.6 of &lt;a href="http://testapi.codeplex.com/releases/view/60572" target="_blank"&gt;&lt;strong&gt;TestApi&lt;/strong&gt;&lt;/a&gt; – the API library for testing – on Codeplex. Version 0.6 contains the following additions and modifications:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Starting with this release, we are &lt;strong&gt;moving all of the development of the library to Codeplex&lt;/strong&gt;. We have also moved the solution to VS 2010;&lt;/li&gt;    &lt;li&gt;&lt;u&gt;Jared Moore&lt;/u&gt; made several important modifications to our &lt;strong&gt;Fault Injection API&lt;/strong&gt;, including but not limited to support for in-process fault injection, support for MethodInfo-based method identification, various performance improvements and bug fixes. In addition, we are releasing the complete source code of the unmanaged FaultInjectionEngine.dll, which now builds cleanly at warning level 4;&lt;/li&gt;    &lt;li&gt;&lt;u&gt;Dennis Deng&lt;/u&gt; extended the &lt;strong&gt;Input Simulation API&lt;/strong&gt; with support for injection of non-ASCII strings in Keyboard.Type(…). We have also added support for Mouse.DragTo(…);&lt;/li&gt;    &lt;li&gt;We have added support for 64-bit in our &lt;strong&gt;Leak Detection API&lt;/strong&gt;;&lt;/li&gt;    &lt;li&gt;&lt;u&gt;Andrey Arkharov&lt;/u&gt; extended the &lt;strong&gt;Object Comparison API&lt;/strong&gt; with support for encoding and decoding object graphs from arbitrary streams, annotating object graph nodes with custom comparison strategies and type-specific object graph factories, together with several additional tests;&lt;/li&gt;    &lt;li&gt;We extended our &lt;strong&gt;String Generation API&lt;/strong&gt; with support for string generation from regular expressions. We have also added a CommonRegularExpressions class, to speed up test development;&lt;/li&gt;    &lt;li&gt;We have added lots of &lt;strong&gt;additional tests&lt;/strong&gt;, and have refactored the existing tests into namespaces for better discoverability.&lt;/li&gt;    &lt;li&gt;Last, but not least we have made some important &lt;strong&gt;API documentation improvements&lt;/strong&gt; – the API documentation now sports namespace docs.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Check out the &lt;a href="http://testapi.codeplex.com/releases/view/60572" target="_blank"&gt;&lt;strong&gt;TestApi v0.6 release notes&lt;/strong&gt;&lt;/a&gt; for a more detailed version of the above. Then let us know what you think and &lt;a href="http://testapi.uservoice.com/" target="_blank"&gt;&lt;strong&gt;vote&lt;/strong&gt;&lt;/a&gt; for features.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10125931" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>Registering Your WP7 as a Developer Device</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/12/07/10101849.aspx</link><pubDate>Wed, 08 Dec 2010 07:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10101849</guid><dc:creator>ivom1</dc:creator><slash:comments>17</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10101849</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/12/07/10101849.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;u&gt;Update&lt;/u&gt;: Shortly after I posted this article, Peter Henry noted that he had a very similar article out already. Here is the link to it – it has good additional information – check it out: &lt;/em&gt;&lt;/strong&gt;&lt;a href="http://www.pchenry.com/Home/tabid/36/EntryID/389/Default.aspx"&gt;&lt;strong&gt;&lt;em&gt;http://www.pchenry.com/Home/tabid/36/EntryID/389/Default.aspx&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So you got your Windows Phone 7 device, you downloaded the free development tools and now you are itching to write your first “Hello World” app for WP7. You fire up VS 2010, create a quick phone app, connect your WP7 device to your development PC, select “Windows Phone 7 Device” as a target and attempt running your first app on your phone.&lt;/p&gt;  &lt;p&gt;You will get the following message…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1803.image_5F00_3F7F5E29.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5428.image_5F00_thumb_5F00_36AF55DD.png" width="820" height="218" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You have to make sure your device is ”developer unlocked” before you can deploy applications to it. Here’s how you unlock your device:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Connect your device to your PC through USB. &lt;/li&gt;    &lt;li&gt;Start the Zune desktop software. &lt;/li&gt;    &lt;li&gt;Start the “Windows Phone Developer Registration” software. &lt;/li&gt; &lt;/ol&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6505.image_5F00_4F3EF32D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1321.image_5F00_thumb_5F00_3B456097.png" width="501" height="592" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;ol&gt;   &lt;li&gt;At this point, provided you have a developer account (which you get on &lt;a href="http://developer.WindowsPhone.com"&gt;http://developer.WindowsPhone.com&lt;/a&gt;) you can register your device. Once registered you’ll be able to use it for development purposes. &lt;/li&gt; &lt;/ol&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2311.image_5F00_52906508.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/4848.image_5F00_thumb_5F00_66A98191.png" width="514" height="464" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Easy! (not necessarily straightforward though :) )&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10101849" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Windows+Phone+7/">Windows Phone 7</category></item><item><title>Performing Code Reviews in TFS 2010</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/11/29/10097641.aspx</link><pubDate>Mon, 29 Nov 2010 09:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10097641</guid><dc:creator>ivom1</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10097641</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/11/29/10097641.aspx#comments</comments><description>&lt;p&gt;The past few days I moved the development of &lt;a href="http://testapi.codeplex.com/" target="_blank"&gt;TestApi&lt;/a&gt; to the Codeplex TFS servers. Previously, we used to develop TestApi in the internal WPF branch at Microsoft, which had become a bit of a drag due to the need to support contributors from various teams across the company.&lt;/p&gt;  &lt;p&gt;As part of the move, I needed to set up a code review process. Turns out that it’s a bit of a struggle to figure out how to set up a simple CR process using standard tools – mostly due to poor documentation – so I thought I’d share what I did in this post. Hopefully, that will save someone out there some time.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Code Review Process&lt;/h1&gt;  &lt;p&gt;The general CR process goes as follows:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The developer creates a new shelveset (see the &lt;a href="http://msdn.microsoft.com/en-us/library/ms181403(VS.80).aspx" target="_blank"&gt;TFS documentation&lt;/a&gt; for a definition of “shelveset”) with his/her changes and sends the shelveset for CR. &lt;/li&gt;    &lt;li&gt;The code reviewer performs the CR, sending back feedback. &lt;/li&gt;    &lt;li&gt;The developer revises his/her code based on the CR feedback and generates a new shelveset. &lt;/li&gt;    &lt;li&gt;Steps 1-3 get repeated until the code reviewer approves the code change for checkin. &lt;/li&gt;    &lt;li&gt;The developer checks in the code. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The tools we use for CR are VS 2010 itself and &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38" target="_blank"&gt;WINDIFF&lt;/a&gt;. The latter is a diffing tool used for step 2 of the CR process.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Initial Setup&lt;/h1&gt;  &lt;p&gt;To set up WINDIFF as your diff-ing tool, in VS 2010 go to &lt;b&gt;Tools&lt;/b&gt; &amp;gt; &lt;b&gt;Options…&lt;/b&gt;, scroll down to the &lt;b&gt;Source Control&lt;/b&gt; item and configure your compare tool to be WINDIFF as shown below:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7266.image_5F00_4099C8AE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3365.image_5F00_thumb_5F00_063E52CD.png" width="517" height="302" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/4442.image_5F00_3E7CC9E5.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3301.image_5F00_thumb_5F00_4BE2DCEB.png" width="517" height="211" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2311.image_5F00_44576D7E.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8255.image_5F00_thumb_5F00_38C1B03F.png" width="296" height="159" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Shelving&lt;/h1&gt;  &lt;p&gt;&lt;i&gt;Shelving&lt;/i&gt; is the act of storing pending changes on the TFS server (see &lt;a href="http://msdn.microsoft.com/en-us/library/ms181403(VS.80).aspx"&gt;this link&lt;/a&gt; for more). To create a shelveset, in &lt;b&gt;Source Control Explorer&lt;/b&gt;, right-click on the folder, containing all pending changes, and choose &lt;b&gt;Shelve Pending Changes…&lt;/b&gt; in the displayed context menu. This will bring up a dialog that you can use to shelve your changes.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5432.image_5F00_3C5FCB1C.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3465.image_5F00_thumb_5F00_7BBD7EAC.png" width="506" height="248" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Once you shelve your proposed changes, send an email to the code reviewer, with your username and the name of your shelveset.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Unshelving, Diffing and Code Review &lt;/h1&gt;  &lt;p&gt;When you get a CR request, go to &lt;b&gt;File&lt;/b&gt; &amp;gt; &lt;b&gt;Source Control&lt;/b&gt; &amp;gt; &lt;b&gt;Unshelve Pending Changes…&lt;/b&gt; and in the displayed &lt;b&gt;Unshelve&lt;/b&gt; dialog, discover the shelveset that you need to review and click &lt;b&gt;Details…&lt;/b&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5428.image_5F00_16F5D7AE.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6505.image_5F00_thumb_5F00_617D1588.png" width="498" height="227" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In the displayed &lt;b&gt;Shelveset Details&lt;/b&gt; dialog, right click the file you want to review and compare it to its unmodified version. This will trigger WINDIFF as a comparison tool. Record your comments in an email and send them back to the developer (or approve the checkin if you agree to it). &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7563.image_5F00_6EE3288E.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2476.image_5F00_thumb_5F00_473CAC64.png" width="503" height="288" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;That’s pretty much it. Obviously, this is a poor man’s solution, but it’s certainly better than nothing. There are a bunch of more advanced solutions out there providing code annotation, review workflows, etc. that you may find valuable too. &lt;a href="http://www.controlstatements.com/2009/01/team-system-code-review-presentation.html" target="_blank"&gt;This post by JB Brown&lt;/a&gt; may be a good starting point for those who want to go further.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10097641" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Code+Review/">Code Review</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TFS/">TFS</category></item><item><title>Principles 4: End-to-End Development Process</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx</link><pubDate>Fri, 10 Sep 2010 09:11:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10060204</guid><dc:creator>ivom1</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10060204</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx"&gt;Principles 1: The Essence of Driving – A Crash Course in Project Management&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx"&gt;Principles 2: Principles of Software Testing&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx"&gt;Principles 3: Principles of Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank"&gt;Principles 4: End-to-End Development Process&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank"&gt;Principles 5: End-to-End Development Process (for Large Projects)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p align="left"&gt;This fourth post discusses an end-to-end development process. Obviously, there are many ways to develop software. While a lot of the basic principles apply almost universally, every sufficiently autonomous organization needs to figure out what works for itself, and then progressively refine it.&lt;/p&gt;  &lt;p align="left"&gt;It is important to note that this process is the same process we used to manage several projects and has resulted in delivery of high-quality products, in a controlled manner, on time (actually ahead of time in a few cases). In other words, this is a real, proven process, not a theoretical construct.&amp;#160; I’ll actually show two versions of the process – a simple one - for smaller orgs, and a more involved one - for larger orgs.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Guiding Principles&lt;/h1&gt;  &lt;p&gt;Before going further, I want to once again reiterate the &lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx" target="_blank"&gt;Principles of Software Development&lt;/a&gt;. These principles are the underlying “Constitution”. In summary, they are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;Everybody on the team fully understands the plan.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Deliver features in a gradual, close-looped manner.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Define release criteria at the start of the cycle. Track visibly.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Exercise defect prevention – whenever possible.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Have a stable, fully-transparent, committed schedule from the start.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;No code while planning the “What”. No code without spec.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Fully working and timed setup on day 1 of M0.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Strict and reliable reverse- and forward-integration gates from day 1 of M0.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Start together, work together, finish together.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;No work happens outside of the main development cycle.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Every major system has an owner.&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h1 align="left"&gt;Goals&lt;/h1&gt;  &lt;p align="left"&gt;At the high level, we want to be able to produce high-quality, compelling software, in a well-organized, intentional, cost-effective, and predictable manner. In order to pull that off, we need the following:&lt;/p&gt;  &lt;ol type="A"&gt;   &lt;li&gt;Commitment, at all levels of the organization, to “do the right thing”. Full management sponsorship. &lt;/li&gt;    &lt;li&gt;A well-designed organization; &lt;/li&gt;    &lt;li&gt;A well-designed “business cycle”; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;A well-designed development process;&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;A well-designed and working “engineering factory”; &lt;/li&gt;    &lt;li&gt;A high-powered and high-morale team; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This post talks about “D”, but it goes without saying that “A” to “F” represent a system of connected vessels and need to be designed, implemented, and refined together.&lt;/p&gt;  &lt;p&gt;This post also makes the assumption that you have a working “Planning Process” that generates compelling product value propositions. Clearly, without a compelling product that addresses a customer need, it doesn’t matter how excellent you are in delivery. There are various ways to plan a product. At Microsoft, we use a bunch of different approaches, with a lot of folks now gravitating towards the so called “Sinofsky model”. At any rate, this post does not discuss the planning process (I may do this in a future post).&lt;/p&gt;  &lt;p&gt;In order to deliver a high-quality product, you need to plan and design before you code. On the other hand, you don’t want to get stuck in planning for a prolonged period of time, because time may erode the value prop of your product and because you need fast and frequent customer feedback – you may be working in the wrong direction. Clearly, we need to “marry” these two competing priorities and clearly this is an optimization problem. What follows is our solution to the optimization problem, but solutions will vary based on specific product, business, industry and team considerations. Treat this as a starting point – take it and make it your own.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Process 1 – Simple Projects&lt;/h1&gt;  &lt;p&gt;We used this simple version of the process to develop &lt;a href="http://testapi.codeplex.com/" target="_blank"&gt;TestApi&lt;/a&gt; – the API library for test and tool developers. TestApi is a relatively small and simple project. With this process, we released five versions of the library and we released all of them on time or ahead of time. &lt;/p&gt;  &lt;p&gt;The development schedule looks as follows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3527.image21_5F00_30BED639.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" class="wlDisabledImage" title="Figure 1  Simple development schedule" border="0" alt="Simple development schedule" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2538.image21_5F00_thumb_5F00_3705ACC7.png" width="645" height="464" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 1&lt;/strong&gt;. Simple development schedule&lt;/p&gt;  &lt;p&gt;The schedule consists of 5 major milestones:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;M0 – Planning&lt;/strong&gt; – in this phase, we finalize the list of features we’d like to deliver in the release. Every feature has an owner. All owners understand the schedule. The necessary prototyping is done. At the end of M0 we have a backlog for the release, to which we have committed. Once we commit to the backlog. We do not allow feature creep after the end of M0. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;M1 – Design&lt;/strong&gt; – in this phase every owner delivers a “conceptual document” that explains the usage of their feature accompanied if necessary by a design document. In the case of an API library such as TestApi, this is a API usage document and API design document.&amp;#160; The usage and design gets reviewed and approved by the Architecture review body (3 people in the case of TestApi). Once the design has been approved, the owner checks in the empty stubs (e.g. of the API) and the corresponding acceptance tests, together with an initial version of the XML documentation and gets stubs, tests and documentation to build cleanly. The documentation (both docs generated from XML comments as well as the conceptual documentation) gets sent to the Documentation team for editing. The Legal team (LCA) gets engaged. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;M2 – Implementation&lt;/strong&gt; – in this phase, the owner implements the tests, code, fixes the documentation (based on editorial feedback from the Docs team) and drives to ZBB (zero bugs) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;M3 – LCA and Samples&lt;/strong&gt; – in this phase the owner implements stand-alone samples (if applicable) and discussed the product with LCA (legal) if applicable. Legal signs off. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;M4 – Stabilization and Release&lt;/strong&gt; – final stabilization, release checklist (we have a predefined checklist) and final release. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Prep&lt;/strong&gt; – At the end of every release cycle, we have about 4 weeks of “padding”. During that period, we do various post release activities (blogging, etc.), we invest in our engineering “factory” and we engage on preliminary planning for the next release (identifying possible participants, defining dates, etc.) This is a fairly relaxed period and that is by design. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;All features associated with a release are tracked in a table similar to the &lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx" target="_blank"&gt;TestApi Feature Backlog table presented in this post&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8535.image_5F00_5C6599AE.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="Figure 2  Feature readiness checklist" border="0" alt="Feature readiness checklist" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2287.image_5F00_thumb_5F00_1437DDD2.png" width="503" height="438" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Figure 2&lt;/strong&gt;. Feature readiness checklist&lt;/p&gt;  &lt;p&gt;All source code is static analysis clean by default (FxCop, StyleCop, etc.) – checking in a violation results in a build break. There is a FAQ for commonly asked questions (e.g. “I can’t be done with a feature on time, what do I do?”, etc.) that evolves with every release. &lt;/p&gt;  &lt;p&gt;As a general rule, the timelines above are rigorously adhered to. If you “fall off the train” (meaning – fail to meet a deadline), you don’t get back on the train until the next version (which is always no more than 3 months away, and of course you tend to deliver larger payload for it). We have a dedicated project manager who drives every release (for TestApi that was Alexis Roosa).&lt;/p&gt;  &lt;p&gt;The tasks associated with every milestone are done in the order in which they are presented here. For example, we write the acceptance tests against the empty stubs &lt;strong&gt;before&lt;/strong&gt; we write the actual code. Another thing that should be obvious is that we spend a lot of effort on planning and design. We are extremely rigorous in our design review, we look at the API from various different angles (we consider different options, we discuss naming, usage, simplicity, statelessness, future evolveability, etc.) employing both scenario-based design and producing various short-lived and long-lived documents. We have found that this saves us a lot of time during development and significantly increases the confidence of our dates. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Simple, Predictable, Agile&lt;/h1&gt;  &lt;p&gt;The simplicity and predictability of this process have a lot of positive effects – from team morale and cohesion to delivery on time with high quality. To date, we have always been done with M4 on time or ahead of time! The process does, however, have a waterfallish feel, so every once in a while I get questions about agility. Put simply, we believe that design and planning is important, but so is time to market and getting frequent customer feedback.&amp;#160; We resolve that tension by having short release cycles (3 months or less). There is noting that is preventing us from making these cycles even shorter, but we have found that 3 months works well for us.&lt;/p&gt;  &lt;p&gt;My experiences shows that you can’t achieve agility by cutting proven engineering practices such as solid design and code reviews – that only leads to fire-drills, death marches and low quality. You achieve agility by having a reasonably rapid development cycle, aligned to solid business considerations.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;To Be Continued…&lt;/h1&gt;  &lt;p&gt;In my next post, I will introduce a process that is suitable for larger, more complex products and organizations. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10060204" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>The 3 Questions</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/04/10046347.aspx</link><pubDate>Thu, 05 Aug 2010 05:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10046347</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10046347</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/04/10046347.aspx#comments</comments><description>&lt;p&gt;A key goal for every manager is building a happy, productive team. One technique I use when building teams is asking folks on the team the following three questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Q1&lt;/strong&gt;. What do you do, and like doing? &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Q2&lt;/strong&gt;. What do you do, and don&amp;rsquo;t like doing? &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Q3&lt;/strong&gt;. What do you not do, but would like to start doing? &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I ask folks to give these questions some thought and ideally send me a bulletized list of items before we meet in person to discuss them. I explain that I will try my best to minimize the items that fall under Q2, and maximize opportunities for items that fall under Q3.&lt;/p&gt;
&lt;p&gt;Even though this technique is extremely simple, I have found it to be a great tool to anchor and guide career conversations. It provides just enough structure to facilitate the conversation, for a very low overhead cost. &lt;/p&gt;
&lt;p&gt;Clearly, this technique also gives me the ability to intelligently balance responsibilities within the organization. Very often the old adage that &amp;ldquo;one man&amp;rsquo;s garbage is another man&amp;rsquo;s treasure&amp;rdquo; proves to be true, which of course makes everybody in the org happier. And happy people are productive people. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10046347" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Management/">Management</category></item><item><title>Principles 3: Principles of Software Development (aka Principles of Shipping)</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx</link><pubDate>Mon, 02 Aug 2010 05:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10044780</guid><dc:creator>ivom1</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10044780</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx"&gt;Principles 1: The Essence of Driving – A Crash Course in Project Management&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx"&gt;Principles 2: Principles of Software Testing&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx"&gt;Principles 3: Principles of Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank"&gt;Principles 4: End-to-End Development Process&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank"&gt;Principles 5: End-to-End Development Process (for Large Projects)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;The third and fourth posts from my series on “Principles” outline a system of shipping of software, that takes into account the various lessons I have learned during my years as a manager at Microsoft, dating back to the first product I worked on – Windows XP. The post lists a set of guiding engineering principles that result in stable, high quality releases, delivered on time.&lt;/p&gt;  &lt;p&gt;Before we jump into the principles, I want to call out a few things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;No exceptions to the rules&lt;/strong&gt;: There is &lt;u&gt;no such thing as partial implementation&lt;/u&gt; of these principles. Even though I take a lot of time socializing these principles in the organizations I manage and worked in, I and my managers tend to take a fairly assertive approach when implementing these principles and we &lt;u&gt;apply them fully, 100% of the time&lt;/u&gt;. Yes, it takes a while to socialize these and yes, we get a few “you are not being agile” (see more on “agile” at the end of this post), “you don’t understand our reality, we are a special organization” and “can we make an exception for XYZ” comments. We still treat these principles as a Constitution and we (management) support them 100% of the time.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Real products get shipped with these principles&lt;/strong&gt;: Everybody wants to ship a high-quality product, with compelling customer value, on schedule or ahead of schedule. As involved as these principles may sound, they are a very simple scaffolding that gets you to ship predictably with high quality.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Top management sponsorship, commitment and calibration is key&lt;/strong&gt;: You cannot really achieve any significant change in an organization unless you have first-class sponsorship and commitment by the top of the organization. The top management team needs to be committed as well as well-calibrated i.e. different members of the top management team should come up with consistent answers when approached with the same problem.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Commitment eventually leads to organic adoption&lt;/strong&gt;:&amp;#160; Solid principles and processes inevitably lead to cultural changes in the organization. As managers, that’s exactly what we want to achieve – a cultural shift in the organization that results in organic rejection of bad practices, and an appetite for continuous improvement.&amp;#160; &lt;/li&gt; &lt;/ol&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;h1&gt;Everybody on the team fully understands the plan.&lt;/h1&gt;  &lt;p&gt;For a team to be successful, &lt;u&gt;everybody on the team needs to (at all times) understand “the plan”&lt;/u&gt; for the release and his/her role in its various cycles and milestones. The litmus test here is asking a random person on the team what “the plan” (schedule, owners, feature set) is. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Deliver features in a gradual, close-looped manner.&lt;/h1&gt;  &lt;p&gt;A common theme during software releases is a fire-drill towards the end of the release, due to the syndrome of “biting more than we can chew” and due to managing the deliverables in an open-ended, “agile” fashion. One way to overcome this situation is ensuring that we deliver features in smaller “sets”, on a more frequent cadence. &lt;u&gt;Every “feature set” represents a meaningful collection, which gets developed and stabilized together before proceeding to the next set&lt;/u&gt;. &lt;/p&gt;  &lt;p&gt;Thus, we end up with a number of “feature set development cycles”, producing stable sets that integrated together comprise our release. I like to use the metaphor of “putting features in the freezer” i.e. we start working on the new feature set only when we have gotten the current feature set to high shippable quality.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Define release criteria at the start of the release cycle. Track regularly.&lt;/h1&gt;  &lt;p&gt;This sounds like a common sense “must do”, but it is regularly not done sufficiently well. The release criteria generally fall into two groups: (a) RI release criteria, necessary to RI (reverse integrate) a feature into the main product branch and (b) shipping release criteria, necessary to release a feature or a set of features. We need to have the complete list of both &lt;u&gt;before&lt;/u&gt; we check in a single line of code. That helps us understand the true cost of every feature.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Defect prevention – whenever possible.&lt;/h1&gt;  &lt;p&gt;A lot of our effort is spent on &lt;u&gt;generating and fixing defects that could have been prevented in the first place&lt;/u&gt;. We need to make heavy use of all available tools in an attempt to prevent as many defects as possible from entering the product in the first place.&lt;/p&gt;  &lt;p&gt;Examples of such defect prevention opportunities are enabling of tools such as FXCOP in the build environment, by default.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Have a stable, fully-transparent, committed schedule from the start.&lt;/h1&gt;  &lt;p&gt;Another common challenge in software releases is the lack of a stable, transparent, predictable schedule. Our product schedule mimics our features. It starts as a very “low-quality” feature, progressively solidifying throughout the release, as a result of “we are not on track” realizations.&lt;/p&gt;  &lt;p&gt;I have heard claims that the schedule of the parent organization (division, company, etc.) is too “fluxy” which in turn affects the ability of the team to build a predictable, stable and transparent schedule. Even if we assume that this claim is true (it probably is, but it should not be – large companies and divisions prove that they can ship with a stable schedule), &lt;u&gt;the local team still has the ability to be in control of its own fate by defining stable sub-schedules&lt;/u&gt; to combat randomization from the larger organization.&lt;/p&gt;  &lt;p&gt;Having a &lt;u&gt;stable, transparent, fully-internalized and fully-embraced schedule&lt;/u&gt; is a key ingredient to the success of any product – big and small.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;No code while planning the “What”. No code without spec.&lt;/h1&gt;  &lt;p&gt;PM spends the first milestone in the product cycle (MQ – the quality milestone) on defining the “what” for the release. Dev and Test complete engineering debt work, preparing the engineering system for execution. While there may be limited prototype code generated during this milestone, none of this code is allowed to be reverse-integrated in any official branch. Dev and Test should spend the majority of their time stabilizing the engineering system (builds, static analysis tools, unit tests, functional tests and infra, stress tests and infra, performance tests and infra, meaningful reverse-integration tests to prevent other teams from breaking us, etc.) &lt;u&gt;Having a stable factory will ensure producing a stable product&lt;/u&gt;.&lt;/p&gt;  &lt;p&gt;Dev and Test start working together on the features in M0 (not earlier) once the “what” has been defined, scratching any previously generated code.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Fully working and timed setup on day 1 of M0.&lt;/h1&gt;  &lt;p&gt;Another common problem teams face is Setup instability that typically carries on, way into the release. Not having a stable Setup complicates significantly lab operations and prevents the team to self-host the build and discover issues early, so it is something that needs to be addressed.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Setup must always be stable and must visibly display the important metrics that we are optimizing against&lt;/u&gt;. Metrics such as speed (of setup), number of custom setup actions, etc. should be visible to the whole team from the start.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Strict and reliable reverse- and forward-integration gates from day 1 of M0.&lt;/h1&gt;  &lt;p&gt;If we believe that reverse- and forward-integration (RI and FI) gates have a valuable role in ensuring the health of the team branch, then we must ensure that the gates that we have in place are reasonable and that they are strictly adhered to. This simplifies immensely feature development, by defining a simple “rule” for RI-ing and FI-ing code that can be easily understood and embraced by the team. &lt;/p&gt;  &lt;p&gt;No code changes in the team branch will be allowed without a fully operational test and validation systems (unit tests passing, test infra running, functional tests at 99.5% pass rate, Perf lab running, Stress lab running, Code Coverage generating results).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;h1&gt;Start together, work together, finish together.&lt;/h1&gt;  &lt;p&gt;A company or a division ships a successful product by getting all team to adhere to the same fundamental schedule and gates. A development organization can and should be doing the same. Having a single schedule with a single set of expectations for all teams simplifies management of the release and creates synergy between the feature owners. &lt;/p&gt;  &lt;p&gt;Some claim that “agility” is achieved by having different feature teams work against different schedules. My experience is that such pseudo-agility results in a fragmented organization, that is confused about its own deliverables and that delivers low-quality products, because products are not built with the same rhythm. Management of the product deliverables in such situations often degrades to “managing exceptions” as opposed to “managing by the rules”.&lt;/p&gt;  &lt;p&gt;We can and will achieve agility through the power of contained, incremental milestones, not through randomization.&lt;/p&gt;  &lt;p&gt;All teams in the development organization should start together, work together and finish together, adhering to a common schedule, RI gates and exit criteria. All disciplines (Dev, Test, PM) should do that too, working side by side as opposed to serializing work.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;No work happens outside of the main development cycle.&lt;/h1&gt;  &lt;p&gt;“Out-of-band” releases and “off-the-books” investments are good and necessary, but they must be planned as all other work and managed within the constraints of the main development cycle. &lt;/p&gt;  &lt;p&gt;This means that they never appear randomly in the middle of a development cycle (they can appear on the backlog to be considered for the next dev cycle). This includes dev work, test work, prototypes, forum engagement, conference prep work, etc. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Every major system has an owner.&lt;/h1&gt;  &lt;p&gt;Every major system on the team (“system” being a generic name for anything that needs an owner) has clearly defined and documented ownership. This includes, but is not limited to fundamentals, lab systems, build systems, test systems, infrastructures, etc.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;h1&gt;A final word on AGILITY.&lt;/h1&gt;  &lt;p&gt;AGILE is a magic word in our industry these days that gets thrown around somewhat lightly in my opinion. Some people hide behind the term AGILITY to justify the lack of basic structure, basic process, and basic planning adequacy in their organization. Invariably such pseudo-agility leads to constant fire-drills, regular death marches, and the eventual burn out of the team. &lt;/p&gt;  &lt;p&gt;It is my strong belief that every project and team needs basic “scaffolding”. Larger projects and teams tend to need a bit more of that, at least until the scaffolding gets transformed into “team culture”.&amp;#160; &lt;/p&gt;  &lt;p&gt;Clearly, the team leaders have to be accountable for providing that basic scaffolding. Success is easy to define – if you have a happy, productive organization that delivers high-quality products on time, then you have provided the necessary basic structure. &lt;/p&gt;  &lt;p&gt;I am of course aware of the goals of the agile movement, which I am very much supportive of. The best way to achieve agility in my opinion, is by sizing of your development cycle appropriately – a technique that I will demonstrate in my next post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10044780" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>Introduction to TestApi – Part 8: Object Comparison API</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx</link><pubDate>Thu, 29 Jul 2010 19:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10043968</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10043968</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx"&gt;Overview of TestApi&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx"&gt;Part 1: Input Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx"&gt;Part 2: Command-Line Parsing APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx"&gt;Part 3: Visual Verification APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx"&gt;Part 4: Combinatorial Variation Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/11/25/9928447.aspx"&gt;Part 5: Managed Code Fault Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995847.aspx"&gt;Part 6: Text String Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995880.aspx"&gt;Part 7: Memory Leak Detection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx"&gt;Part 8: Object Comparison APIs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;Comparing two objects for equivalence is a relatively common task during test validation. For example, you might test whether a type follows the rules that are required by a particular serializer by saving and loading the object and comparing the two. In a deep object comparison, all the properties and their sub-properties are compared repeatedly until primitives are reached. The .NET Framework provides mechanisms to perform deep comparisons, but requires the types to implement part of the comparison logic (IComparable, .Equals). Obviously some types do not use these mechanisms. This API provides a mechanism to perform a deep comparison of two objects by using reflection, regardless of whether or not they implement IComparable. &lt;/p&gt;  &lt;h1&gt;TestApi Object Comparison&lt;/h1&gt;  &lt;p&gt;TestApi provides an API to create compare operations. The API separates the comparison operation into two parts: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;ObjectGraphFactory&lt;/strong&gt;: Builds an intermediate representation from the object that describes what needs to be compared. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ObjectComparer&lt;/strong&gt;: Uses a reusable compare mechanism to compare the intermediate representations of the objects, generated by the factory. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6523.image_5F00_1B9197A6.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1348.image_5F00_thumb_5F00_15D67E00.png" width="652" height="278" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;h1&gt;Example #1&lt;/h1&gt;  &lt;p&gt;This example demonstrates how to use the object comparer to compare two objects. Assuming we have the following simple class...&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Person
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Person(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; name) 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    { 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        Name = name;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        Children = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Collection&amp;lt;Person&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Name { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Collection&amp;lt;Person&amp;gt; Children { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;;  }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;… we can compare two objects using the following code:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Mary&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p2.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Perform the compare operation&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectGraphFactory factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PublicPropertyObjectGraphFactory();
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectComparer comparer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ObjectComparer(factory);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Console.WriteLine(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &amp;quot;&lt;span style="color: #8b0000"&gt;Objects p1 and p2 {0}&lt;/span&gt;&amp;quot;, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    comparer.Compare(p1, p2) ? &amp;quot;&lt;span style="color: #8b0000"&gt;match!&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;do NOT match!&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Execution of this code produces the following output:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Objects p1 and p2 do NOT match!&lt;/pre&gt;&lt;/pre&gt;

&lt;h1&gt;Example #2&lt;/h1&gt;

&lt;p&gt;The following example demonstrates how to obtain the details of where the two objects do not match.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Mary&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p2.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Perform the compare operation&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectGraphFactory factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PublicPropertyObjectGraphFactory();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectComparer comparer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ObjectComparer(factory);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;IEnumerable&amp;lt;ObjectComparisonMismatch&amp;gt; m12 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;ObjectComparisonMismatch&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Console.WriteLine(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &amp;quot;&lt;span style="color: #8b0000"&gt;Objects p1 and p2 {0}&lt;/span&gt;&amp;quot;, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    comparer.Compare(p1, p2, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; m12) ? &amp;quot;&lt;span style="color: #8b0000"&gt;match!&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;do NOT match!&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (ObjectComparisonMismatch m &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; m12)
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Console.WriteLine(
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &amp;quot;&lt;span style="color: #8b0000"&gt;Nodes '{0}' and '{1}' do not match. Mismatch message: '{2}'&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        m.LeftObjectNode != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? m.LeftObjectNode.Name : &amp;quot;&lt;span style="color: #8b0000"&gt;null&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        m.RightObjectNode != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? m.LeftObjectNode.Name : &amp;quot;&lt;span style="color: #8b0000"&gt;null&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        m.MismatchType); 
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Execution of this code produces the following output:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Objects p1 and p2 do NOT match!
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'Children' and 'Children' do not match. Mismatch message: 'RightNodeHasFewerChildren'
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'IEnumerable1' and 'null' do not match. Mismatch message: 'MissingRightNode'
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'Children' and 'null' do not match. Mismatch message: 'MissingRightNode'
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'Count' and 'null' do not match. Mismatch message: 'MissingRightNode'
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'Name' and 'null' do not match. Mismatch message: 'MissingRightNode'
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Nodes 'Count' and 'Count' do not match. Mismatch message: 'ObjectValuesDoNotMatch'&lt;/pre&gt;&lt;/pre&gt;

&lt;h1&gt;Example #3&lt;/h1&gt;

&lt;p&gt;The following example demonstrates how to create a custom object graph factory which determines which nodes in the object graph to compare. &lt;/p&gt;

&lt;p&gt;For simplicity, we construct a factory that disregards any children.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SimpleObjectGraphFactory : ObjectGraphFactory
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; GraphNode CreateObjectGraph(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; o)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// Build the object graph with nodes that need to be compared.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// in this particular case, we only pick up the object itself&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        GraphNode node = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GraphNode();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        node.Name = &amp;quot;&lt;span style="color: #8b0000"&gt;PersonObject&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        node.ObjectValue = (o &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Person).Name;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; node;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Then, we utilize the factory to generate graph representations of the two object we want to compare.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p1.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Mary&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Person p2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;p2.Children.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Peter&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectGraphFactory factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SimpleObjectGraphFactory();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;ObjectComparer comparer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ObjectComparer(factory);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Console.WriteLine(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &amp;quot;&lt;span style="color: #8b0000"&gt;Objects p1 and p2 {0}&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    comparer.Compare(p1, p2) ? &amp;quot;&lt;span style="color: #8b0000"&gt;match!&lt;/span&gt;&amp;quot; : &amp;quot;&lt;span style="color: #8b0000"&gt;do NOT match!&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Execution of this code produces the following output…&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Objects p1 and p2 match!&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;… which is the expected result, given the fact that our simple factory completely disregards the Children of Person.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Comparing of objects is a common problem in automated test development and TestApi provides a simple generalized and extensible solution.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10043968" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Object+Comparision+API/">Object Comparision API</category></item><item><title>Principles 2: Principles of Software Testing</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx</link><pubDate>Fri, 23 Jul 2010 22:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10042059</guid><dc:creator>ivom1</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10042059</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx"&gt;Principles 1: The Essence of Driving – A Crash Course in Project Management&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx"&gt;Principles 2: Principles of Software Testing&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx"&gt;Principles 3: Principles of Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank"&gt;Principles 4: End-to-End Development Process&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank"&gt;Principles 5: End-to-End Development Process (for Large Projects)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;This is part 2 of my series on “principles”. In this post, I talk about the principles I have used to guide all teams I have managed. Before we delve in – a couple of clarifications:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I have skipped some of the obvious basic principles such as “strive for high levels of automation”, “integrate testing into your development process”, etc. I know that a number of organizations are still struggling with the basics. If you happen to be part of such an organization, grab a book on software testing before reading this post. &lt;/li&gt;    &lt;li&gt;The majority of the principles you will read below are common sense. Some of them, however, seem to contradict common sense and definitely contradict what you’ll read in books on testing. Don’t trust everything you read (including this little gem)... But consider the fact that we used these exact principles to ship several versions of WPF and Visual Studio. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The principles, which I cover, are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;High test stability (99.5%)&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Driving testing upstream &lt;/li&gt;        &lt;li&gt;No major investments in failure investigation tools &lt;/li&gt;        &lt;li&gt;Random configuration management &lt;/li&gt;        &lt;li&gt;Devs and Testers use the same test harness &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;High test performance&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Fast builds &lt;/li&gt;        &lt;li&gt;“No BVT” policy &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Minimum dependencies&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;All test metadata is in the source control system &lt;/li&gt;        &lt;li&gt;Test code, dev code and specs are checked in the same source depot &lt;/li&gt;        &lt;li&gt;Enable a “build-xcopy-run” testing workflow through zero server dependencies &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Fundamentals, Fundamentals, Fundamentals&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Performance and Scalability &lt;/li&gt;        &lt;li&gt;Stress and Stability &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Test Development Principles&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Focus on design and reuse &lt;/li&gt;        &lt;li&gt;Componentization and aggregation (“Lego blocks” mentality) &lt;/li&gt;        &lt;li&gt;Automated code verification as much as possible &lt;/li&gt;        &lt;li&gt;Focus on End-To-End Scenarios &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Continuous Training&lt;/strong&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Enjoy! &lt;/p&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc263947213"&gt;High test stability (99.5%)&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;High test stability is the cornerstone of every good test automation system. Ideally, a test should fail only when there is a product bug. In reality, tests tend to fail for other reasons too, but we should strive to minimize those failures by either fixing or removing (and rewriting) unstable tests.&lt;/p&gt;  &lt;p&gt;The principle of high test stability (99.5% test stability) has several important implications. It allows us to spend less time chasing random test failures and more time discovering bugs in the product. It also allows us to increase test coverage faster than increasing support costs. It helps us land the product in a stable, predictable manner. But most importantly, high test stability allows us to &lt;u&gt;drive testing upstream&lt;/u&gt;. &lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947214"&gt;Driving testing upstream&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Defect prevention is the “holy grail” of quality management. There are many studies that show that preventing a defect of entering the product is a much cheaper option that discovering and fixing the defect after it’s has been introduced. &lt;/p&gt;  &lt;p&gt;Obviously there are many different ways to go about defect prevention. One of the simplest and most robust one is having &lt;u&gt;a stable and fast suite of tests that can easily be run by developers prior to check-in&lt;/u&gt;. The suite has to be stable – because no one likes to debug through 100s of unrelated failures to confirm that the code works. The suite has to be fast, because no one likes to wait for hours for test results to come out.&lt;/p&gt;  &lt;p&gt;Having a stable and fast test suite allows us to practice a continuous “develop – run tests – fix issues – repeat” cycle prior to check-in.&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947215"&gt;No major investments in failure investigation tools&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;About 5 years ago, we used to invest a lot in advanced failure investigation tools, which allowed us to quickly deal with and resolve large numbers of test failures. It turned out that having high test stability negated the need for having advanced failure investigation tools. For the most part, a NUnit-like report (typically XML with a XSLT transform to make the data readable) is all the team needed. At this point of time, I assert that having an advanced failure investigation tool may actually be a dangerous practice for test teams as it acts as a powerful crutch that pulls the team away from the root underlying issues that need to be fixed – i.e. tests with low stability or a very low quality product.&lt;/p&gt;  &lt;p&gt;There is one important aspect of failure investigation tool development that we need to account for though. SDETs are fundamentally software engineers. As software engineers we like to develop software and a failure investigation tool often presents opportunities to hone one’s design and coding skills and to also experiment with new technologies (web services, databases, extensibility frameworks, AI, GUI frameworks, etc.) We clearly have to find ways to expose our SDETs to other opportunities to improve their transferable skills (design, algorithms, etc). &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: 99.5% pass rate of the WPF tests&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;99.5% is obviously an arbitrary number. The right number to strive for is always 100%. A realistic stability goal depends on the size of the team and on the size of the test suite, but typically revolves around 99.5%. For example, in the WPF test team, we had a suite of about 105,000 tests which at 99.5% pass rate produced about 500 test failures for a team of about 30 engineers or about 18 failures per person, which seemed to be a reasonable number (so that every SDET spends no more than about 30 minutes investigating failure every day).&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;With time, 99.5 became a team mantra. SDETs, SDEs, PMs actively identified with it and fought for it.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;&lt;a name="_Toc263947216"&gt;Random configuration management&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;At Microsoft, we serve hundreds of millions of customers with great environment variability. A typical “test matrix” consists of a number of HW configurations, OS platforms, languages, locales, display configurations, etc. and typically contains millions of variations. &lt;/p&gt;  &lt;p&gt;Teams typically do the following to deal with the “configuration matrix explosion” problem:&lt;/p&gt;  &lt;ol type="a"&gt;   &lt;li&gt;Use matrix reduction techniques (“&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx"&gt;pairwise variation generation&lt;/a&gt;”, etc.) &lt;/li&gt;    &lt;li&gt;Prioritize configurations (e.g. “English, x86, FRE, 96 DPI” is higher priority than “Portuguese, x64, CHK, 140 DPI” – no offense to Portuguese folks, I myself am Bulgarian and I have to admit that in the general case English is higher pri than Bulgarian). &lt;/li&gt;    &lt;li&gt;Create and manage a deterministic configuration testing schedule (today we cover “English”, tomorrow we cover “German”, etc.) in an attempt to cover all high priority configurations. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Technique (b) specifically often has the unfortunate effect of getting us to test mostly on “vanilla configurations”, which results in missing bugs until late in the testing cycle and results in “training” the tests to pass on vanilla configurations only. Technique (c) tends to result in high testing schedule management costs.&lt;/p&gt;  &lt;p&gt;An easy way to combat the undesired effects of (b) and (c) is to switch to a &lt;u&gt;weighted random configuration management&lt;/u&gt;. The weight of a certain config can be calculated dynamically based on historical data (pass rate of the last time the config was run on, and frequency of running). &lt;/p&gt;  &lt;p&gt;One can even build predictive models that would allow the team to search for configurations that result in large number of bugs.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: WPF test execution matrix management&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Prior to early 2007, the WPF used to invest a considerable amount of effort to plan day-to-day test execution. The team had a dedicated test lead who managed the test execution matrix and sequence. Introduction of a new OS to the matrix was a fairly disruptive event, necessitating a regeneration of the whole execution sequence. Test passes took a long time, because of completeness concerns.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;At the beginning of 2007, the WPF test team switched to &lt;u&gt;weighted random configuration management&lt;/u&gt;. We introduced a simple Excel spreadsheet, which was used by the lab engineers to generate a &lt;u&gt;random testing config&lt;/u&gt; every day that was then installed in the lab and used for test execution. The team identified about 20 configurations as high priority configurations. 4 out of 5 days in the week, the team used a randomly selected high pri config. Every 5&lt;sup&gt;th&lt;/sup&gt; day or so, the team explored the rest of the configurations.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The switch to random test config generation removed the need for test execution scheduling, resulted in additional test stabilization (because the tests were not trained to pass on vanilla configurations) and enabled the team to find bugs off the beaten path earlier in the development cycle.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;&lt;a name="_Toc263947217"&gt;Devs and testers use the same test harness&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Developer unit tests use exactly the same test harness as the functional tests developed by SDETs. This enables code reuse between the unit tests and the functional tests. It also enables developers to easily run and debug functional tests (because they know how to do it), thus enabling defect prevention.&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947218"&gt;High test performance&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Automated tests are programs that get executed multiple times throughout the lifecycle of the product. Having slow tests results in the following problems:&lt;/p&gt;  &lt;ol type="a"&gt;   &lt;li&gt;Delays bug discovery (because test runs take longer, need to be incomplete due to their length, etc); &lt;/li&gt;    &lt;li&gt;Precludes the team from effectively employing defect-prevention techniques such as TDD, test before check-in, etc; &lt;/li&gt;    &lt;li&gt;Wastes machine time and electricity; &lt;/li&gt;    &lt;li&gt;Creates test management complexity - splitting the test suite in different priorities (BVTs, “nightlies”, etc) and creating the need for managing these different sub-suites, etc. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947219"&gt;Fast Builds&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;One area that often gets overlooked is the speed of building the tests compared to the speed of building the product. Tests often take much longer to build because they are not properly packaged (e.g. too many DLLs) and because no one really looks into improving the build times. In reality having a fast product and test build enables defect prevention. &lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947220"&gt;“No BVT” Policy&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;In theory, the idea of BVTs (build verification tests : a sub-suite of high priority tests that get run more often than the rest of the tests) sounds good. In practice, BVTs tend to become just another “crutch” that typically prevents test teams from addressing the root underlying problem of test slowness and instability&lt;a href="file:///C:/Ivo/MediaRoom/Principles/#_ftn1_5126" name="_ftnref1_5126"&gt;[1]&lt;/a&gt;. Introduction of the notion of BVTs also introduces various “management costs” (suite management and curation, execution schedule management, etc.) that are moving the focus away from more important activities directly related to the quality of the product.&lt;/p&gt;  &lt;p&gt;So I highly discourage the use of BVTs. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: WPF BVTs&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;In the WPF test team, we experienced the full cycle. We started with a suite of tests that we used to run every day. As we expanded the suite of tests, we saw that the run times of the suite became longer and that the stability of tests became lower. Instead of investing in fixing test perf, stability and duplication of coverage, we decided to segment the suite into P0s, P1s, P2s, etc. We created various processes to handle bugs produced by P0 tests, etc. (the “hot bug” concept). Because BVTs were treated as special high-priority tests fortified by these additional processes, SDETs tended to add more and more tests to the BVT suite, which in turn increased the run times of the suite, reduced its stability, and necessitated introducing additional “BVT nomination” and “BVT auditing” processes. We had a BVT team (!!!) whose sole purpose of existence was handling the BVT suite. The “BVT auditing” process did not work, so we invested in further segmenting the BVT suite into “micro-BVTs” and “regular BVTs”, we introduced micro-BVT execution time budgets per area, etc, etc, etc. We lived with this crazy complicated system for years.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;At the beginning of 2007, we decided to put an end to the madness, and focused on optimizing our run times and improving our stability. We improved our test build times 800% and we improved test run times 500%, which enabled us to do a complete test run for about 2 hours on 20 machines. We did not really get rid of priorities, but we found that when the tests are stable and fast, people tend to not care about test priority. Today, nobody cares about priorities. &lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The test result reports visibly display run times, so that SDETs, SDEs and leads can address any excessively long tests. SDEs are also asked to provide feedback whenever they feel that the test run times are too long.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Run times are reported by test (and aggregated into feature area run times) to allow drilling into areas that take too long to run.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h1&gt;&lt;a name="_Toc263947221"&gt;Minimum Dependencies&lt;/a&gt;&lt;/h1&gt;  &lt;h2&gt;&lt;a name="_Toc263947222"&gt;All test metadata is in the source control system&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Tests have both build-time dependencies (the test code, etc.) and run-time dependencies (test metadata such as owners, priorities, test support files, configuration details, etc.) Some teams tend to keep the run-time dependencies on a dedicated server or in databases. In theory that sounds great – after all databases are created for storing of data. &lt;/p&gt;  &lt;p&gt;In practice, storing of test metadata in databases is problematic, because it introduces versioning issues. Handling code branch forks, RIs, FIs, etc. becomes very difficult and error prone because you have to mirror the branch structure on the server or in the database. Some teams have designed elaborate processes to maintain referential integrity between the source control system and the support servers / databases. Although these processes may work (or can be made to work), they come with a significant support cost and are typically not robust when left on their own. &lt;/p&gt;  &lt;p&gt;A better approach is to keep all test-related data in the source control system. There are obviously exceptions (e.g. checking in large video files may not be a good idea), and we have to be smart to not bring the source control system to its knees, but in general this approach is superior to maintaining separate databases, servers, etc.&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947223"&gt;Test code, dev code and specs are checked in the same source depot&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;It’s a good idea to keep dev and test code in the same branch. That helps catching and preventing build breaks as a result of breaking changes. It also enables code reuse across the organization (SDEs can reuse test framework pieces for unit tests, SDETs can reuse dev code for tests).&lt;/p&gt;  &lt;p&gt;A lot of teams tend to keep specs on SharePoint servers. While this makes specs readily accessible and easily editable (if you can get around some of SharePoint’s idiosyncrasies), it suffers from the following problems:&lt;/p&gt;  &lt;ol type="a"&gt;   &lt;li&gt;Spec versioning is very tricky – tracking revision history is even trickier; &lt;/li&gt;    &lt;li&gt;Spec discovery can be tricky – you have to know the address of the SharePoint server in addition to the source code location; &lt;/li&gt;    &lt;li&gt;Specs tend to get lost – as the team moves from SharePoint site to SharePoint site; &lt;/li&gt;    &lt;li&gt;Migration of SharePoint content (e.g. to a SE team) is trickier; &lt;/li&gt;    &lt;li&gt;Specs tend to become stale – folks typically don’t bother updating specs unless they are right next to the code; &lt;/li&gt;    &lt;li&gt;SharePoint servers may have additional maintenance costs (upgrades to new versions of SharePoint, security patching, etc.); &lt;/li&gt;    &lt;li&gt;Specs are not easily accessible offline (although Outlook does provide offline access facilities now). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;As a best practice, specs should be checked in right next to the source code (or in a obvious location that makes sense, based on the source code directory organization). &lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947224"&gt;Enable a “build-xcopy-run” testing workflow through zero server dependencies&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;In principle, it’s a good idea to minimize the server dependencies you have. Having server dependencies increases the maintenance costs, complicates the move to Sustained Engineering (because SE has to replicate all servers and record server management knowledge), prevents SDETs and SDEs to run tests when not connected to the network and in general complicates the lab setup.&lt;/p&gt;  &lt;p&gt;So we should subject every server dependency to careful examination and if we have to have servers, move them to the cloud.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: WPF server and database dependencies&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;At the beginning of 2007, the WPF test team had about 30 servers and a database-based test case management (TCM) system (its name was Tactics). This resulted in significant maintenance costs that could no longer be afforded. So the team decided to switch to a source-control-based TCM.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The results were outstanding – the team reduced server dependencies to about 6 servers (1 file server, 1 web server, 1 SharePoint server and 3 backup servers) and enabled SDETs and SDEs to build and run tests without being connected to the network. It also practically removed the need for any referential integrity related maintenance. &lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The WPF team also checked in all specs in source depot. Specs are bin-placed as part of the build process. This ensured that the team can produce a build with matching specs for every release of the product and we can track and compare different versions of the specs.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h1&gt;&lt;a name="_Toc263947225"&gt;Fundamentals, Fundamentals, Fundamentals&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;For every piece of software, there are a number of cross-cutting concerns which we call “fundamentals” or “basics”. These are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Accessibility &lt;/li&gt;    &lt;li&gt;Compatibility (forward, backward, AppCompat, etc.) &lt;/li&gt;    &lt;li&gt;Compliance &lt;/li&gt;    &lt;li&gt;Deployment, serviceability and servicing &lt;/li&gt;    &lt;li&gt;Globalization and localization &lt;/li&gt;    &lt;li&gt;Performance and scalability &lt;/li&gt;    &lt;li&gt;Security &lt;/li&gt;    &lt;li&gt;Stability &lt;/li&gt;    &lt;li&gt;Etc. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;All of these are extremely important and have historically represented a significant competitive advantage for Microsoft. Testing of fundamentals is expensive so we need to have the right supporting processes and automated systems in place to ensure that we produce solid software by default. &lt;/p&gt;  &lt;p&gt;Some of these fundamentals can be integrated within the functional testing – others typically need dedicated systems and processes. Below, I am only presenting two of the fundamentals above.&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947226"&gt;Performance and Scalability&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Performance and Scalability are two fundamentals that can and should be automated. Ideally, the team has an automated system that runs Perf / Scalability tests (both &lt;u&gt;micro-benchmarks&lt;/u&gt; and &lt;u&gt;end-to-end scenarios&lt;/u&gt; are equality important) on target HW and SW configurations on every daily build. The system runs a set of tests, which capture agreed-upon performance goals and metrics. The system provides facilities for easy visualization of key trends. &lt;/p&gt;  &lt;p&gt;Having an automated Perf system enables early discovery and fixing of Perf regressions. Due to the domain-specific nature of the work, it’s typically necessary to have a dedicated Performance team that develops and supports the necessary processes, tools and systems.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: WPF performance&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The WPF team has a dedicated highly automated Performance lab. The Performance infrastructure automatically picks up and installs daily builds on a stable set of machines and configurations, runs a set of performance tests, presents results (cold startup times, warm startup times, working set size and various other metrics) and trends, identifies regressions, and captures necessary traces for follow up investigation.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The lab infrastructure also allows testing and generating diffs for individual dev changes (this feature is not really broadly used although the lab does do dedicated perf runs of specific potentially disruptive changes.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;&lt;a name="_Toc263947227"&gt;Stress and Stability&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Stress and Stability are another fundamental that requires a dedicated process and system. It can either be done on a dedicated pool of machines / devices or on the devices in engineer’s offices during off-work hours. Some teams tend to invest a lot in automated triage systems, but in my experience these tend to be expensive to maintain so should be avoided at first.&lt;/p&gt;  &lt;p&gt;The Stress system can also be used for security testing by running fuzzers, fault injection, other penetration tools alongside with the &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;Case Study: WPF stress&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The WPF team has a simple dedicated stress framework, which consumes both stress-specific test code and generalized testing blocks. The tests are “deterministically random” i.e. a stress test failure can in theory (and often in practice) be reproved on demand. The tests are distributed to about 100 machines every night (these machines are in the lab). Results get analyzed and presented by vendors in China.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt;    &lt;p&gt;&lt;i&gt;&lt;font color="#c0504d"&gt;The team used to have a fairly sophisticated stress system that was able to do preliminary triage of failure stacks, map them to existing bugs, etc. This turned out to be an over-automated system which had a significant support cost, so we switched to the current significantly simpler system where stress failures are triaged by a vendor team in China, who manage the pool of the stress machines remotely. The system is managed by 2 engineers in China with some support from local Redmond SDETs.&lt;/font&gt;&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h1&gt;&lt;a name="_Toc263947228"&gt;Test Development Principles&lt;/a&gt;&lt;/h1&gt;  &lt;h2&gt;&lt;a name="_Toc263947229"&gt;Focus on design and reuse&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Tests are long-lived software. Tests actually tend to live longer than the product code they test, due to AppCompat and other reasons – in Windows we have tests that are 20 years old, dating back to the Win16 days. In order to build a stable test suite teams need to invest in design and code and asset reuse. &lt;/p&gt;  &lt;p&gt;Proper software design is an acquired taste. It is one of those things that doesn’t just happen on its own. It requires focus on architecture, design reviews, code reviews. It also requires training – both on the job (e.g. through mentoring, DR, CR) and structured training (e.g. design pattern “brownbag” sessions, etc.)&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947230"&gt;Componentization and aggregation (“Lego blocks” mentality)&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;A test suite (as any other piece of software) needs to be able to evolve. A test suite also needs to be portable. The single best way to create a robust, evolvable, maintainable test suite is to construct it as a combination of small self-contained building blocks. &lt;/p&gt;  &lt;p&gt;We employ the principles of componentization and aggregation as opposed to inheritance and integration when constructing test suites. In that sense, tests are like “lego models” constructed as an aggregation of reusable “lego blocks” weaved together by test execution and configuration policy. &lt;a name="_GoBack"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947231"&gt;Automated code verification as much as possible&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;There are two major techniques for automated code verification:&lt;/p&gt;  &lt;ol type="a"&gt;   &lt;li&gt;Static code analysis &lt;/li&gt;    &lt;li&gt;Dynamic code analysis &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Static code analysis should be performed prior to check-in to prevent the team to check-in buggy code. Ideally tools such as PreFast, PreFix, FXCOP, StyleCop, Polycheck should be integrated in the build environment and any violation of their rules should result in a build break. &lt;/p&gt;  &lt;p&gt;Dynamic code analysis is another powerful technique done through in-situ verification (asserts, special OS instrumentation such as that enabled with AppVerifier and driver verifier, etc). &lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc263947232"&gt;Focus on End-To-End Scenarios&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Product features are created in order to enable end-to-end user scenarios. The quality of a product feature does not matter if the e2e scenario doesn’t work. So test teams should work closely with the PM and dev teams to understand the e2e scenarios and to build tests that capture these e2e scenarios early in the development cycle.&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc263947233"&gt;Continuous Training&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;The single fastest way to improve a team’s throughput is through training. Of course all of us experience continuous on-the-job training (which is one of the great things about the dynamic industry we are in), but I am a big believer in providing a bit of a training structure for the organization. &lt;/p&gt;  &lt;p&gt;The fundamental training activities we engage in are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Team-wide brown-bag sessions:      &lt;ul&gt;       &lt;li&gt;Sessions on fundamentals such as design patterns, data-driven testing, stress testing, perf and scalability testing, etc; &lt;/li&gt;        &lt;li&gt;Sessions on product-specific architecture and tools; &lt;/li&gt;        &lt;li&gt;Blitz sessions on product features. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;1:1 mentoring:      &lt;ul&gt;       &lt;li&gt;Done by leads or designated mentors; &lt;/li&gt;        &lt;li&gt;Typically done as part of test spec reviews, design reviews, code reviews. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Official Microsoft training &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc263947221"&gt;Parting Thoughts&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;Hopefully the two words that jump in your mind after reading this post are “simplicity” and “rigor”. As a general rule, I’d always trade advanced functionality for simplicity and we keep doing that all the time in the team. It takes a lot of spine though to truly commit to simplicity – as engineers our natural tendency is to solve the most complicated (and interesting) problem.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10042059" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Testing/">Software Testing</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Test+Automation/">Software Test Automation</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Testing/">Testing</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/QA/">QA</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>Principles 1: The Essence of Driving – A Crash Course in Project Management</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx</link><pubDate>Sun, 18 Jul 2010 21:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10039624</guid><dc:creator>ivom1</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10039624</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/18/10039624.aspx"&gt;Principles 1: The Essence of Driving – A Crash Course in Project Management&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/23/10042059.aspx"&gt;Principles 2: Principles of Software Testing&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/08/01/10044780.aspx"&gt;Principles 3: Principles of Software Development&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/09/10/10060204.aspx" target="_blank"&gt;Principles 4: End-to-End Development Process&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2011/04/21/10136580.aspx" target="_blank"&gt;Principles 5: End-to-End Development Process (for Large Projects)&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;About a year ago, I got feedback from my team that I needed to clarify what I meant by “drive this effort” or “lead that effort”. So I decided to create a quick document explaining what I meant. Below is that document. I later converted the document to a slide-deck, which is also available at the end of the post.&lt;/p&gt;  &lt;p&gt;There are *a lot* of books on project management. From that point of view, there is nothing special about the techniques below – all of them are pretty much common sense and all of them can be found in those books. What is special about the post that follows is the condensed presentation (my goal is to essentially save you from reading a PMP book) and the fact that we actually used every single one of these techniques to manage the WPF 4 and Visual Studio 2010 products, which we released in April 2010.&lt;/p&gt;  &lt;p&gt;The techniques listed below are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Over-communication &lt;/li&gt;    &lt;li&gt;Scorecard &lt;/li&gt;    &lt;li&gt;Trend (and glide-path) &lt;/li&gt;    &lt;li&gt;Backlog / Burn-down List &lt;/li&gt;    &lt;li&gt;“Branded” status emails &lt;/li&gt;    &lt;li&gt;Schedule in Excel &lt;/li&gt;    &lt;li&gt;Schedule in Visio &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc235348126"&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;Project management is a skill that can (as any other skill) be acquired and improved. Really most of our work and a significant part of our personal lives boil down in one way or another to project management.&lt;/p&gt;  &lt;p&gt;Every project has a life-cycle, consisting of several standard phases:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Initiating &lt;/li&gt;    &lt;li&gt;Planning and kick-off &lt;/li&gt;    &lt;li&gt;Executing &lt;/li&gt;    &lt;li&gt;Monitoring &amp;amp; Controlling &lt;/li&gt;    &lt;li&gt;Closing &lt;/li&gt;    &lt;li&gt;Post-mortem learning &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;An effective PM&lt;a name="_ftnref1_1835"&gt;&lt;/a&gt; understands and actively manages the life-cycle of a project.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc235348127"&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;When I ask somebody to “drive” this or that, what I really mean is “be an effective PM of this effort”, exhibiting the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Independence and accountability &lt;/li&gt;    &lt;li&gt;Ability to construct, communicate and get approval for a clear and well-though-out plan for the project, including:      &lt;ul&gt;       &lt;li&gt;Timelines &lt;/li&gt;        &lt;li&gt;Scope, goals / non-goals and success criteria &lt;/li&gt;        &lt;li&gt;Internal and external “unmovables” and requirements &lt;/li&gt;        &lt;li&gt;Stakeholders &lt;/li&gt;        &lt;li&gt;Costs and funding &lt;/li&gt;        &lt;li&gt;Risks and mitigations &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Ability to set the project in motion, keep the project in motion and close down the project      &lt;ul&gt;       &lt;li&gt;Proactive contribution of directive energy to the project, creating excitement, and identifying and removing road-blocks. &lt;/li&gt;        &lt;li&gt;Active monitoring of the progress of the project &lt;/li&gt;        &lt;li&gt;Proactive communication of status &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Ability to reach the desired results &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc235348128"&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;These are the standard milestones of a project. Simpler projects can certainly be managed without necessarily differentiating between some of the milestones.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6371.image_5F00_4E415D1D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3225.image_5F00_thumb_5F00_618213BC.png" width="708" height="585" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It is important to note that there are project management techniques out there that try to simplify the model above. Such simplifications are often based on “hardcoded rules” e.g. (“each project cycle takes exactly 4 weeks”, etc.) It’s also important to note that not all projects require all of the “line items” above delivered explicitly. Most projects do require them at least in implicit form though.&lt;/p&gt;  &lt;p&gt;Depending on the specific project, some of the activities may or may not be required. Below are two example projects that demonstrate how to use the template above.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a name="_Toc235348129"&gt;&lt;/a&gt;&lt;/h4&gt;  &lt;h1&gt;&lt;a name="_Toc235348131"&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;h2&gt;&lt;a name="_Toc235348132"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Keeping good communication throughout the project is a common-sense technique. It is, however, surprisingly rare. So, as a good rule of thumb, &lt;span style="text-decoration: underline"&gt;always over-communicate&lt;/span&gt; your project status. Don’t worry -- you will inevitably hear from your manager and other major stakeholders if you truly are spamming everybody, but I guarantee that would never happen.&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348133"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Scorecards provide a way to track progress against a set of success criteria. Scorecards are often presented in time, although that may not be always possible or meaningful. Here is a sample scorecard: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0508.image_5F00_130D8152.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2577.image_5F00_thumb_5F00_19C08AD5.png" width="515" height="128" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can track both “qualitative assessments” (e.g. “gut-feel of main stakeholders”) as well as “quantitative observables” (e.g. “number of defects”). When rating the progress, it’s useful to use a 4-level scheme similar to the one below. Excel’s conditional formatting feature makes construction of scorecards fairly easy. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0005.image_5F00_396F649D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/6864.image_5F00_thumb_5F00_6447C8AF.png" width="232" height="98" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348134"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Glide-paths are a common way of graphically displaying change in time of one or more observables in an attempt to inform future progress. Here are a few examples:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3247.clip_5F00_image002_5F00_6AFAD232.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1007.clip_5F00_image002_5F00_thumb_5F00_23A57C40.jpg" width="316" height="220" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8446.clip_5F00_image004_5F00_0A3D7906.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3225.clip_5F00_image004_5F00_thumb_5F00_1EC2C884.png" width="305" height="217" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Note a few important details:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Having a glide-path or some other indication of important milestones (e.g. B1, B2, RTM) always helps since it establishes a context for the trend and acts as a gentle “forcing function”; &lt;/li&gt;    &lt;li&gt;It’s a good idea to provide a title for the trend chart and names (and dimensions) for the chart’s axes except when they are self-evident (as is the case with time above). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348135"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Backlogs were popularized by Scrum and other agile project management methodologies. A backlog has two purposes:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Keep all tasks / items associated with a particular project in a central, regularly updated location that is easy to point to, prioritize (hopefully just once in release); &lt;/li&gt;    &lt;li&gt;Have a “parking lot” for future items, feature requests. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here is a sample backlog:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1581.image_5F00_1E56958F.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1172.image_5F00_thumb_5F00_6F90DCEC.png" width="658" height="641" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348136"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The average engineer at Microsoft receives between 200 and 300 emails every day. One way to allow stakeholders and observers to easily monitor the progress of a project you are managing is to “brand” the emails related to that project. Examples of “branding” include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;span style="text-decoration: underline"&gt;Standardized subject line&lt;/span&gt; (e.g. “WPF 4 Pulse: Stress”) – allows people to easily filter and search for emails pertaining to that project; &lt;/li&gt;    &lt;li&gt;&lt;span style="text-decoration: underline"&gt;Standardized “look and feel”&lt;/span&gt; of the email – either by maintaining a consistent structure or by including a common logo in the email; &lt;/li&gt;    &lt;li&gt;&lt;span style="text-decoration: underline"&gt;Setting up a custom alias&lt;/span&gt; for this project only (e.g. “WPF – VS Tactics”, etc.) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348137"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Excel presents an easy way to construct schedules. These typically have a “From”, “To” and “Length” columns. Here is an example:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3644.clip_5F00_image008_5F00_5CDBE335.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8037.clip_5F00_image008_5F00_thumb_5F00_4711FAD8.jpg" width="644" height="210" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;More complicated schedules typically require the introduction of a “Type” (of event) column, to allow filtering per type, thus making your schedules easier to grasp. Using “tables” in Excel makes the constructed schedules easily “filterable”.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc235348138"&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;What Excel schedules lack is a graphical representation of scaled time periods. This is where Visio schedules excel. Here is a sample.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/0820.clip_5F00_image010_5F00_54780DDE.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7444.clip_5F00_image010_5F00_thumb_5F00_33F0CE2C.jpg" width="644" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s often very helpful to complement this with a “we are here” arrow:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/4621.clip_5F00_image012_5F00_5A52B177.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/1184.clip_5F00_image012_5F00_thumb_5F00_6BC3124F.jpg" width="644" height="187" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The arrow accomplished several things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Lightning fast way to communicate to your team and stakeholders where you are in relation to the whole project; &lt;/li&gt;    &lt;li&gt;Increases the confidence that the schedule is real and recent (if you bothered placing an arrow, you probably have ensured that you are placing it on an up-to-date schedule). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;     &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h1&gt;&lt;a name="_Toc235348139"&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;Good project managers are hard to find. Partly, because good project managers grow through experience. Invariably though, through experience, they (or at least the ones I have observed) tend to gravitate to the same basic techniques – the ones you see above. Hopefully, you will find these helpful.&lt;/p&gt;  &lt;p&gt;In case you haven’t noticed, I love Excel. I use it as my main project management tool. My wife is a construction project manager and she constantly bugs me about not using Microsoft Project. Project is a fine product and I have in fact used it for some of the more complicated projects I have managed. What I love about Excel is its simplicity, integration (charts) and high-availability (Excel files are viewable on any device). &lt;/p&gt;  &lt;p&gt;Some manage their projects using databases and web sites. I still prefer Excel. The reason? Versioning. With Excel (or Project), all you need to do is check in the corresponding file in your SCM (source code management) system. Databases are harder to version.&lt;/p&gt;  &lt;p&gt;Finally, here’s a pointer to the slide-deck accompanying this document as well as a sample Feature Backlog spreadsheet:&lt;/p&gt;  &lt;div style="width: 425px" id="__ss_4782200"&gt;&lt;strong&gt;&lt;a title="The Essence of DRIVING" href="http://www.slideshare.net/ivom1234/the-essence-of-driving"&gt;The Essence of DRIVING&lt;/a&gt;&lt;/strong&gt; &lt;object height="355" width="425" id="__sse4782200"&gt; &lt;param value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theessenceofdriving-100718115242-phpapp01&amp;amp;stripped_title=the-essence-of-driving" name="movie" /&gt; &lt;param value="true" name="allowFullScreen" /&gt; &lt;param value="always" name="allowScriptAccess" /&gt;&lt;embed height="355" width="425" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theessenceofdriving-100718115242-phpapp01&amp;amp;stripped_title=the-essence-of-driving" name="__sse4782200"&gt;&lt;/embed&gt; &lt;/object&gt;    &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/ivom1234"&gt;ivom1234&lt;/a&gt;.&lt;/div&gt; &lt;/div&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:1cf53d40-cfc3-4129-a902-d9a9db4c03b5" class="wlWriterEditableSmartContent"&gt;Inserting of file(Feature Backlog.xlsx) failed. Please try again.&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;hr align="left" size="1" width="33%" /&gt;  &lt;p&gt;&lt;a name="_ftn1_1835"&gt;&lt;/a&gt;PM in this context refers to any “project manager” (a lead or an individual contributor in any disciplines tasked with “driving” something), not just a Microsoft PM.&lt;/p&gt;  &lt;p&gt;&lt;a name="_ftn2_1835"&gt;&lt;/a&gt;VMI (Vision-Mission-Identity) is something that is often neglected, mostly because project teams tend to eventually infer these themselves. VMI is, however, a major part of the branding of the project and the project team and tends to have a very positive impact on driving ownership into and empowering of the team members. In practical terms, VMI is answering the questions “what is the ideal outcome of the project (e.g. “deliver the best text on any platform”), who are we (e.g. “we are the team, enabling clear text in VS 2010”), and why are we the right team to do it. &lt;/p&gt;  &lt;p&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10039624" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-03-96-24/Feature-Backlog.xlsx" length="13076" type="application/vnd.openxmlformats-officedocument.spre" /><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>Building Outdoor Pull-Up Bar and Parallel Bars</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/14/10051813.aspx</link><pubDate>Thu, 15 Jul 2010 01:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10051813</guid><dc:creator>ivom1</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10051813</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/14/10051813.aspx#comments</comments><description>&lt;p&gt;Pull-ups and dips are among the best exercises for the upper body. So,&amp;#160; I have always wanted to build the necessary exercise equipment in my backyard. Our move to San Jose and &lt;a href="http://howtomatic.com/category/health_and_exercise/10-how-to-build-an-outdoor-pull-up-bar"&gt;this excellent article&lt;/a&gt; on HowToMatic provided the critical mass to get me started. This post captures all you need to know to build your own.&lt;/p&gt;  &lt;h1&gt;Necessary Tools and Materials&lt;/h1&gt;  &lt;p&gt;I got everything I needed at Home Depot, except for the bungee ropes, which I already had.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/8780.image_5F00_42F21D50.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3404.image_5F00_thumb_5F00_663F11F5.png" width="525" height="439" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 1&lt;/strong&gt;&amp;#160; Tools and materials&lt;/p&gt;  &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Building the Equipment&lt;/h1&gt;  &lt;p&gt;&lt;strong&gt;1. &lt;/strong&gt;Have a plan. Here’s what mine looked like:&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7624.image_5F00_6566AC0B.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/7230.image_5F00_thumb_5F00_12E7CBCF.png" width="554" height="844" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 2&lt;/strong&gt;&amp;#160; Equipment diagram&lt;/p&gt;  &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/3581.image_5F00_127B98DA.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5545.image_5F00_thumb_5F00_709F9A7B.png" width="511" height="381" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;strong&gt;Fig. 3&lt;/strong&gt; Final result&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Dig the 6 holes. It took me about 4 hours to dig all of them without killing myself and I made the mistake of digging them a bit too narrow. Don’t be afraid to dig wide. The holes need to be at least 1.5 feet (50 cm) deep and need to be about 1.5 feel (50 cm) in diameter.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Drill holes for the pipes through the wooden beams. Drill about 4 inches (10 cm) away from the end of the beam. Don’t forget to wear glasses / goggles for eye protection. You can either drill al the way through the entire beam or drill just on one side of the beam. In retrospect, I should have done the latter for all holes.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt; Position the beams in the holes. Use small stones and the bungee ropes to ensure that the beams are properly positioned and straight. I decided to make one side of the dip bars slightly wider than the other side – for exercise versatility – so my dip bars are not exactly parallel. Position the pipes into the beam holes. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; Prep the concrete, following the directions on the bag. I prepped the concrete one bag at a time. Mixing concrete is tough so I recommend the following workflow:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Pour all water you need for a full bag of concrete in the bucket &lt;/li&gt;    &lt;li&gt;Pour half a bag of concrete in the bucket. Mix, until you get a homogenous mixture. &lt;/li&gt;    &lt;li&gt;Pour the other half – mix again. &lt;/li&gt;    &lt;li&gt;Work fast – you have less than 5 minutes to mix the whole bag and probably another 5 minutes to pour the concrete into the holes. &lt;/li&gt;    &lt;li&gt;Use some help – having a second set of hands helps a lot. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt; Pour the concrete into the holes, compressing it. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;7.&lt;/strong&gt; Clean up. Let it cure for a day before using the equipment. Then drill the small holes for the screws to prevent the pipes from rotating. &lt;/p&gt;  &lt;p&gt;Frankly, I loved the physical labor, and you will too… It is a surprisingly therapeutic and rewarding experience. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Exercises&lt;/h1&gt;  &lt;p&gt;The great thing about this setup is that you can do all sorts of different exercises that develop strength and agility, using the weight of your own body, for example…&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Chin-up"&gt;Chin-ups&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Pull-up_(exercise)"&gt;Pull-ups&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/File:Muscle-up.gif"&gt;Muscle-ups&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Pull up and around the bar &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Dip_(exercise)"&gt;Dips&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.straighttothebar.com/2008/05/swinging_dips_to_45_degrees.html"&gt;Swinging dips&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I recommend starting with chin-ups and dips (3 sets each, max repetitions in each set) and progressing from there.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10051813" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Exercise/">Exercise</category></item><item><title>Move to California, Principles, etc.</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/13/10037769.aspx</link><pubDate>Tue, 13 Jul 2010 20:44:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10037769</guid><dc:creator>ivom1</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10037769</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/13/10037769.aspx#comments</comments><description>&lt;p&gt;A couple of quick announcements…&lt;/p&gt;  &lt;p&gt;First, about a month ago we moved to California. It was a bit of a bitter-sweet move for us. On one hand, we left behind a lot of good friends and colleagues – it felt like the end of an era. On another, while Seattle itself is a nice city, we never got used to the rain – we’ve been aching for sunshine for 9+ years. The release of WPF 4 and VS 2010 presented the right time to make the jump, so we made the jump we had been thinking of. I took a position in the &lt;a href="http://microsoft.com/mediaroom"&gt;Mediaroom&lt;/a&gt; team, working at Microsoft’s Silicon Valley Campus in Mountain View. The past 3.5 years in WPF were fantastic – I worked with great people, worked for a great manager (&lt;a href="http://twitter.com/IanET"&gt;Ian Ellison-Taylor&lt;/a&gt;) and shipped 3 great versions of WPF, culminating with WPF 4, which now powers the $1B Visual Studio business. &lt;/p&gt;  &lt;p&gt;Second, a change is always a good opportunity for a retrospective brain-dump. So in the coming weeks I will be sharing some pearls of wisdom (“the principles”) that guided our execution in the WPF team. Hopefully, you’ll find them useful…&lt;/p&gt;  &lt;p&gt;As for Cali, give me a shout if you are in the vicinity and want to hook up!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10037769" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Principles/">Principles</category></item><item><title>XAML Compliance Suite v1 Released!</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/08/10035943.aspx</link><pubDate>Thu, 08 Jul 2010 14:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10035943</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10035943</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/08/10035943.aspx#comments</comments><description>&lt;p&gt;Lester and his team (the XAML test team) just released v1 of the XAML compliance suite – a set of basic tests that can be used to assess the compliance of any customer XAML parser to the XAML spec.&lt;/p&gt;  &lt;p&gt;To download the suite, check our &lt;a href="http://blogs.msdn.com/b/llobo/archive/2010/07/07/xaml-compliance-suite-v1.aspx"&gt;Lester’s blog post&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10035943" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/XAML/">XAML</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Testing/">Testing</category></item><item><title>A Lap Around TestApi v0.5</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/22/10028876.aspx</link><pubDate>Wed, 23 Jun 2010 06:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10028876</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10028876</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/22/10028876.aspx#comments</comments><description>&lt;p&gt;A few days ago we released the new version of &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; &amp;ndash; the API library for testing. &lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/18/10026880.aspx"&gt;My previous post&lt;/a&gt; from 6/18 summarized the additions and modifications to the library. This post goes a little bit deeper.&lt;/p&gt;
&lt;h1&gt;Documentation&lt;/h1&gt;
&lt;p&gt;In the TestApi package, we release both MSDN-style documentation (as CHM file and as a set of HTML files) as well as &amp;ldquo;conceptual documentation&amp;rdquo;. In TestApi 0.5, we spent a lot of effort cleaning up, updating and extending all of our documentation in an attempt to improve the usability of the library.&lt;/p&gt;
&lt;h1&gt;Theme Configuration API&lt;/h1&gt;
&lt;p&gt;TestApi v0.5 has a simple API for OS theme management. For example, you can easily list all available themes on the system and dump various attributes:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.Theming;
...

Console.WriteLine(&lt;span class="str"&gt;"Current Theme:"&lt;/span&gt;);
Console.WriteLine(&lt;span class="str"&gt;"\tName:    {0}\n"&lt;/span&gt;, Theme.GetCurrent().Name);

Console.WriteLine(&lt;span class="str"&gt;"Available Themes:"&lt;/span&gt;);
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Theme t &lt;span class="kwrd"&gt;in&lt;/span&gt; Theme.GetAvailableSystemThemes())
{
    Console.WriteLine(&lt;span class="str"&gt;"\tName:    {0}"&lt;/span&gt;, t.Name);
    Console.WriteLine(&lt;span class="str"&gt;"\tPath:    {0}"&lt;/span&gt;, t.Path);
    Console.WriteLine(&lt;span class="str"&gt;"\tEnabled: {0}"&lt;/span&gt;, t.IsEnabled);
    Console.WriteLine(&lt;span class="str"&gt;"\tStyle:   {0}\n"&lt;/span&gt;, t.Style);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;You can also switch to a desired theme programmatically, which is valuable when you need to verify appearance across themes:&lt;/div&gt;
&lt;pre class="csharpcode"&gt;Theme ot = Theme.GetCurrent();

&lt;span class="kwrd"&gt;try&lt;/span&gt;
{
    Theme[] availableThemes = Theme.GetAvailableSystemThemes();
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Theme t &lt;span class="kwrd"&gt;in&lt;/span&gt; availableThemes)
    {
        Console.WriteLine(&lt;span class="str"&gt;"Switching to theme \"{0}\"..."&lt;/span&gt;, t.Name);
        Theme.SetCurrent(t);
    }
}
&lt;span class="kwrd"&gt;finally&lt;/span&gt;
{
    Theme.SetCurrent(ot);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h1&gt;Revamped Input Injection API&lt;/h1&gt;
&lt;p&gt;In previous releases of the library, our input injection API had the peculiarity of being dependent on WPF types (specifically the &lt;strong&gt;Key&lt;/strong&gt; and &lt;strong&gt;MouseButton&lt;/strong&gt; enums). Apart from introducing an unnecessary dependency for tests that target WinForms, this had the annoying side effect of making the use of the API too verbose, i.e. in TestApi 0.4 you had to explicitly qualify Mouse and Keyboard, because you had to have dependencies on WPF namespaces which happen to also have similarly named classed in them:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Input;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.Input;
...

Microsoft.Test.Input.Mouse.MoveTo(&lt;span class="kwrd"&gt;new&lt;/span&gt; System.Drawing.Point(...));
Microsoft.Test.Input.Mouse.Click(MouseButton.Left);
...
Microsoft.Test.Input.Keyboard.Type(&lt;span class="str"&gt;"Hello, world!"&lt;/span&gt;);
...&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;TestApi 0.5 fixes all of that. Now you can simply do:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.Input;
...

Mouse.MoveTo(&lt;span class="kwrd"&gt;new&lt;/span&gt; Point(...));
Mouse.Click(MouseButton.Left);
...
Keyboard.Type(&lt;span class="str"&gt;"Hello, world!"&lt;/span&gt;);
...&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;h1&gt;Visual Verification API Additions&lt;/h1&gt;
&lt;p&gt;By popular demand, we have added support for searching for sub-images to Snapshot, so now you can do things like:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.VisualVerification;

Snapshot s1 = Snapshot.FromFile(&lt;span class="str"&gt;"BigImage.png"&lt;/span&gt;);
Snapshot s2 = Snapshot.FromFile(&lt;span class="str"&gt;"SubImage.png"&lt;/span&gt;);

&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Rectangle r &lt;span class="kwrd"&gt;in&lt;/span&gt; s1.Find(s2))
{
    Console.WriteLine(
        &lt;span class="str"&gt;"Found s2... Coords: ({0}, {1}); Size: ({2}, {3})"&lt;/span&gt;,
        r.Left, r.Top, r.Width, r.Height);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Snapshot.Find also has an overload which takes as a second parameter a SnapshotVerifer, so that you can do &amp;ldquo;fuzzy&amp;rdquo; searches.&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h1&gt;Text String Generation API Extensions&lt;/h1&gt;
&lt;p&gt;TestApi 0.4 introduced the new text string generation API. However, what we had in TestApi 0.4 had an important limitation &amp;ndash; you could only generate strings in one UnicodeRange at a time, i.e. you used to write the following code:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.Text;
...

StringProperties sp = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringProperties();

sp.MinNumberOfCodePoints = 10;
sp.MaxNumberOfCodePoints = 20;
sp.UnicodeRange = &lt;span class="kwrd"&gt;new&lt;/span&gt; UnicodeRange(UnicodeChart.BraillePatterns);

&lt;span class="kwrd"&gt;string&lt;/span&gt; s = StringFactory.GenerateRandomString(sp, 1234);&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;TestApi 0.5 lifts that restriction. Now you can generate strings that contain code points from multiple ranges:&lt;/div&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.Text;
...

StringProperties sp = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringProperties();

sp.MinNumberOfCodePoints = 10;
sp.MaxNumberOfCodePoints = 20;
sp.UnicodeRanges.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; UnicodeRange(UnicodeChart.BraillePatterns));
sp.UnicodeRanges.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; UnicodeRange(UnicodeChart.Cyrillic));

&lt;span class="kwrd"&gt;string&lt;/span&gt; s = StringFactory.GenerateRandomString(sp, 1234);&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Revamped Combinatorial Variation Generation API&lt;/h1&gt;
&lt;p&gt;The Combinatorial Variation Generation API underwent a major revamp in TestApi 0.5. We introduced support for generics, support for declarative models and moved to a LINQ-based syntax for constraints.&lt;/p&gt;
&lt;p&gt;The example below demonstrates the basic usage:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Test.VariationGeneration;

...

&lt;span class="rem"&gt;// Specify the parameters and parameter values&lt;/span&gt;
var os = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"OS"&lt;/span&gt;) { &lt;span class="str"&gt;"WinXP"&lt;/span&gt;, &lt;span class="str"&gt;"Win2k3"&lt;/span&gt;, &lt;span class="str"&gt;"Vista"&lt;/span&gt;, &lt;span class="str"&gt;"Win7"&lt;/span&gt; };
var memory = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Memory"&lt;/span&gt;) { 512, 1024, 2048, 4096 };
var graphics = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Graphics"&lt;/span&gt;) { &lt;span class="str"&gt;"Nvidia"&lt;/span&gt;, &lt;span class="str"&gt;"ATI"&lt;/span&gt;, &lt;span class="str"&gt;"Intel"&lt;/span&gt; };
var lang = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Lang"&lt;/span&gt;) { &lt;span class="str"&gt;"enu"&lt;/span&gt;, &lt;span class="str"&gt;"jpn"&lt;/span&gt;, &lt;span class="str"&gt;"deu"&lt;/span&gt;, &lt;span class="str"&gt;"chs"&lt;/span&gt;, &lt;span class="str"&gt;"ptb"&lt;/span&gt; };

var parameters = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;ParameterBase&amp;gt; { os, memory, graphics, lang };

var model = &lt;span class="kwrd"&gt;new&lt;/span&gt; Model(parameters);

&lt;span class="rem"&gt;// The model is complete; now generate the configurations and print out&lt;/span&gt;
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var config &lt;span class="kwrd"&gt;in&lt;/span&gt; model.GenerateVariations(2))
{
    Console.WriteLine(&lt;span class="str"&gt;"{0} {1} {2} {3}"&lt;/span&gt;,
        config[&lt;span class="str"&gt;"OS"&lt;/span&gt;],
        config[&lt;span class="str"&gt;"Memory"&lt;/span&gt;],
        config[&lt;span class="str"&gt;"Graphics"&lt;/span&gt;],
        config[&lt;span class="str"&gt;"Lang"&lt;/span&gt;]);
}&lt;/pre&gt;
&lt;p&gt;


&lt;/p&gt;
&lt;p&gt;Often, one needs to apply constraints when generating variations. TestApi 0.5 constraints are now LINQ-based as shown below:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;var de = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Destination"&lt;/span&gt;) { &lt;span class="str"&gt;"Whistler"&lt;/span&gt;, &lt;span class="str"&gt;"Hawaii"&lt;/span&gt;, &lt;span class="str"&gt;"Las Vegas"&lt;/span&gt; };
var ho = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Hotel Quality"&lt;/span&gt;) { 5, 4, 3, 2, 1 };
var ac = &lt;span class="kwrd"&gt;new&lt;/span&gt; Parameter&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Activity"&lt;/span&gt;) { &lt;span class="str"&gt;"gambling"&lt;/span&gt;, &lt;span class="str"&gt;"swimming"&lt;/span&gt;, &lt;span class="str"&gt;"shopping"&lt;/span&gt;, &lt;span class="str"&gt;"skiing"&lt;/span&gt; };

var parameters = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;ParameterBase&amp;gt; { de, ho, ac };
var constraints = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Constraint&amp;lt;Variation&amp;gt;&amp;gt;
{
    &lt;span class="rem"&gt;// If going to Whistler or Hawaii, then no gambling&lt;/span&gt;
    Constraint&amp;lt;Variation&amp;gt;
        .If(v =&amp;gt; de.GetValue(v) == &lt;span class="str"&gt;"Whistler"&lt;/span&gt; || de.GetValue(v) == &lt;span class="str"&gt;"Hawaii"&lt;/span&gt;)
        .Then(v =&amp;gt; ac.GetValue(v) != &lt;span class="str"&gt;"gambling"&lt;/span&gt;),

    &lt;span class="rem"&gt;// If going to Las Vegas or Hawaii, then no skiing&lt;/span&gt;
    Constraint&amp;lt;Variation&amp;gt;
        .If(v =&amp;gt; de.GetValue(v) == &lt;span class="str"&gt;"Las Vegas"&lt;/span&gt; || de.GetValue(v) == &lt;span class="str"&gt;"Hawaii"&lt;/span&gt;)
        .Then(v =&amp;gt; ac.GetValue(v) != &lt;span class="str"&gt;"skiing"&lt;/span&gt;),

    &lt;span class="rem"&gt;// If going to Whistler, then no swimming&lt;/span&gt;
    Constraint&amp;lt;Variation&amp;gt;
        .If(v =&amp;gt; de.GetValue(v) == &lt;span class="str"&gt;"Whistler"&lt;/span&gt;)
        .Then(v =&amp;gt; ac.GetValue(v) != &lt;span class="str"&gt;"swimming"&lt;/span&gt;),
};
var model = &lt;span class="kwrd"&gt;new&lt;/span&gt; Model(parameters, constraints);


&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var vacationOption &lt;span class="kwrd"&gt;in&lt;/span&gt; model.GenerateVariations(2))
{
    Console.WriteLine(&lt;span class="str"&gt;"{0}, {1} stars -- {2}"&lt;/span&gt;,
        vacationOption[&lt;span class="str"&gt;"Destination"&lt;/span&gt;],
        vacationOption[&lt;span class="str"&gt;"Hotel Quality"&lt;/span&gt;],
        vacationOption[&lt;span class="str"&gt;"Activity"&lt;/span&gt;]);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Another major addition in TestApi 0.5 is the ability to use declarative models, which simplifies the model definition syntax significantly. Users of the API apply attributes to a regular class to declare parameters and possible parameter values:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; OsConfiguration
{
    [Parameter(512, 1024, 2048)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Memory { get; set; }

    [Parameter(&lt;span class="str"&gt;"WinXP"&lt;/span&gt;, &lt;span class="str"&gt;"Vista"&lt;/span&gt;, &lt;span class="str"&gt;"Win2K8"&lt;/span&gt;, &lt;span class="str"&gt;"Win7"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; OS { get; set; }

    [Parameter(&lt;span class="str"&gt;"enu"&lt;/span&gt;, &lt;span class="str"&gt;"jpn"&lt;/span&gt;, &lt;span class="str"&gt;"deu"&lt;/span&gt;, &lt;span class="str"&gt;"chs"&lt;/span&gt;, &lt;span class="str"&gt;"ptb"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Language { get; set; }

    [Parameter(&lt;span class="str"&gt;"NVidia"&lt;/span&gt;, &lt;span class="str"&gt;"ATI"&lt;/span&gt;, &lt;span class="str"&gt;"Intel"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Graphics { get; set; }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Then the model is formed and used as follows:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;var model = &lt;span class="kwrd"&gt;new&lt;/span&gt; Model&amp;lt;OsConfiguration&amp;gt;();
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (OsConfiguration c &lt;span class="kwrd"&gt;in&lt;/span&gt; model.GenerateVariations(2))
{
    Console.WriteLine(&lt;span class="str"&gt;"{0} {1} {2} {3}"&lt;/span&gt;, 
        c.Memory, 
        c.OS,
        c.Language,
        c.Graphics);
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;The declarative syntax supports also equivalence classes, as well as parameter value weights. In the example below for example&amp;rdquo;Vista&amp;rdquo; and &amp;ldquo;Win7&amp;rdquo; are treated as values in same equivalence class. &amp;ldquo;Vista&amp;rdquo; or &amp;ldquo;Win7&amp;rdquo; will collectively appear more often than &amp;ldquo;WinXP&amp;rdquo; because of their larger weight value:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; OsConfiguration
{
    [Parameter(&lt;span class="str"&gt;"WinXP"&lt;/span&gt;, Weight = .3F)]
    [Parameter(&lt;span class="str"&gt;"Vista"&lt;/span&gt;, &lt;span class="str"&gt;"Win7"&lt;/span&gt;, Weight = .5F)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; OS { get; set; }

    [Parameter(&lt;span class="str"&gt;"EN-US"&lt;/span&gt;)]
    [Parameter(&lt;span class="str"&gt;"JP-JP"&lt;/span&gt;, &lt;span class="str"&gt;"CN-CH"&lt;/span&gt;)]
    [Parameter(&lt;span class="str"&gt;"HE-IL"&lt;/span&gt;, &lt;span class="str"&gt;"AR-SA"&lt;/span&gt;)]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Language { get; set; }
}&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Fault Injection API Enabled for .NET 4 Binaries&lt;/h1&gt;
&lt;p&gt;The fault injection facilities in TestApi 0.4 did not work for .NET 4 binaries. TestApi 0.5 fixes that problem. TestApi 0.5 also ships all binaries necessary for fault injection as part of the package, to reduce dependency on the .NET installation on the target machine. &lt;/p&gt;
&lt;p&gt;We have also made a minor naming change, renaming &lt;strong&gt;BuiltInConditions.TriggerEveryOnNthCall&lt;/strong&gt; to &lt;strong&gt;BuiltInConditions.TriggerOnEveryNthCall&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;Fixes and Additions to the Command-Line Parsing API&lt;/h1&gt;
&lt;p&gt;We have made significant modifications and fixes to the documentation of the command-line parsing API, expanding and fixing the MSDN-style documentation and the conceptual documentation to achieve consistency and correctness and to streamline the use of the API.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;xUnit 1.5&lt;/h1&gt;
&lt;p&gt;As part of TestApi 0.5 we have switched to using &lt;a href="http://xunit.codeplex.com/releases/view/31606"&gt;xUnit 1.5&lt;/a&gt;. xUnit continues to be a fantastic unit-testing framework &amp;ndash; both simpler and more full features than other comparable frameworks. xUnit 1.5 in particular provides a significantly improved GUI tool, which makes execution of the TestApi acceptance tests significantly easier.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5100.image_5F00_2.png"&gt;&lt;img height="484" width="618" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5187.image_5F00_thumb.png" alt="image" border="0" title="image" class="wlDisabledImage" style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 align="center"&gt;&lt;span style="font-size: x-small;"&gt;+++&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Most of the updates in TestApi 0.5 are under the cover, but in their entirety represent a significant update compared to TestApi 0.4. Let us know what you&amp;rsquo;d like to see in the future revisions of the library.&lt;/p&gt;
&lt;p&gt;Attached is a solution with the sample code above.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10028876" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-02-88-76/TestApi-0.5-Samples.zip" length="59605" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>TestApi v0.5 Released!</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/18/10026880.aspx</link><pubDate>Fri, 18 Jun 2010 07:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10026880</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10026880</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/18/10026880.aspx#comments</comments><description>&lt;p&gt;I am happy to announce that we have just released version 0.5 of &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; &amp;ndash; the testing API library &amp;ndash; on Codeplex. Version 0.5 contains a number of important additions and modifications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We made &lt;strong&gt;significant updates to our documentation&lt;/strong&gt;, revising practically all conceptual and MSDN-style API documents, to make the library easier to use. I have also been updating my blog posts on the library because some of the content there has gotten somewhat stale. Big thanks to &lt;span style="text-decoration: underline;"&gt;Christine Warren&lt;/span&gt; &amp;ndash; our technical documentation editor.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Vincent Sibal&lt;/span&gt; created &lt;strong&gt;a new Theme Configuration API&lt;/strong&gt; allowing you to easily switch Windows OS themes.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Vince&lt;/span&gt; also revamped the &lt;strong&gt;Input Injection API&lt;/strong&gt;, removing the dependency on WPF, and adding new acceptance tests.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Tim Cowley&lt;/span&gt; added sub-image search support to the &lt;strong&gt;Visual Verification API&lt;/strong&gt;, based on a request by NLord.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Dennis Deng&lt;/span&gt; &lt;strong&gt;extended the Text String Generation API&lt;/strong&gt; with the ability to generate strings from multiple Unicode ranges. He also added additional acceptance tests.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Nathan Anderson&lt;/span&gt; and &lt;span style="text-decoration: underline;"&gt;Eugene Zakhareyev&lt;/span&gt; &lt;strong&gt;revamped the Combinatorial Variation Generation API&lt;/strong&gt;, converting constraints to a LINQ-based syntax, adding support for generics, adding support for equivalence classes, adding weights and tags and enabling declarative models.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Bill Liu&lt;/span&gt; enabled the &lt;strong&gt;Fault Injection API for .NET 4&lt;/strong&gt; binaries.      &lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration: underline;"&gt;Dan Marley&lt;/span&gt; made various fixes and test additions to the &lt;strong&gt;Command-line Parsing API&lt;/strong&gt;.      &lt;/li&gt;
&lt;li&gt;We also &lt;strong&gt;switched to using xUnit 1.5&lt;/strong&gt;, which is included in the TestApi 0.5 package.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Last but not least, a big thank you to &lt;span style="text-decoration: underline;"&gt;Alexis Roosa&lt;/span&gt; (the PM of the effort) and &lt;span style="text-decoration: underline;"&gt;Peter Antal&lt;/span&gt; (who together with Dan Marley did a bunch of design reviews).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Let us know what you think!&amp;nbsp; And &lt;a href="http://testapi.uservoice.com/"&gt;&lt;strong&gt;vote&lt;/strong&gt;&lt;/a&gt; for features!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10026880" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>TestApi Voting Site</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/14/10024990.aspx</link><pubDate>Tue, 15 Jun 2010 03:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10024990</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=10024990</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/06/14/10024990.aspx#comments</comments><description>&lt;p&gt;I wanted to point all TestApi users to our new feature-suggestion-slash-voting site for TestApi on &lt;a href="http://testapi.uservoice.com"&gt;http://testapi.uservoice.com&lt;/a&gt;. Earlier today we seeded the site with a few ideas for features. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/2541.image_5B00_7_5D00_.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image[7]" border="0" alt="image[7]" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-88-37-metablogapi/5518.image_5B00_7_5D005F00_thumb.png" width="628" height="597" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;Help us prioritize future TestApi features by submitting your feature requests and voting on existing submissions.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10024990" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>Introduction to TestApi – Part 7: Memory Leak Detection API</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/15/9995880.aspx</link><pubDate>Thu, 15 Apr 2010 17:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9995880</guid><dc:creator>ivom1</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9995880</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/15/9995880.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx"&gt;Overview of TestApi&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx"&gt;Part 1: Input Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx"&gt;Part 2: Command-Line Parsing APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx"&gt;Part 3: Visual Verification APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx"&gt;Part 4: Combinatorial Variation Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/11/25/9928447.aspx"&gt;Part 5: Managed Code Fault Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995847.aspx"&gt;Part 6: Text String Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995880.aspx"&gt;Part 7: Memory Leak Detection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx"&gt;Part 8: Object Comparison APIs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;h1&gt;General Notes&lt;/h1&gt;  &lt;p&gt;A &lt;i&gt;memory leak&lt;/i&gt; is the inability to release reserved memory. Memory leaks often lead to continuously increasing memory usage in applications, which in turn degrades the application and system performance.&lt;/p&gt;  &lt;p&gt;Most modern operating systems free all the memory that is reserved by a process when the process terminates, which provides some protection against cumulative memory leaks that result from repeated execution of the same “leaky” application. However, this solution is at best only partially successful because &lt;i&gt;all&lt;/i&gt; kinds of memory leaks are undesirable, and you need to catch and eliminate them.&lt;/p&gt;  &lt;p&gt;TestApi provides a simple memory-leak-detection mechanism, which takes &lt;i&gt;memory snapshots&lt;/i&gt; of an executing process and then processes the snapshots with arbitrarily complex leak-detection algorithms, as the following figure shows. The leak detection APIs were designed and implemented by our engineer Shozub Qureshi in collaboration with other members of our team.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart7MemoryLeakDete_620F/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart7MemoryLeakDete_620F/clip_image002_thumb.jpg" width="644" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;&lt;b&gt;Fig.1&lt;/b&gt; Leak detection workflow&lt;/p&gt;  &lt;p align="center"&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;TestApi currently only provides mechanisms for crude detection of leaks. If a leak is suspected, the TestApi user should use a profiler to narrow down possible memory leaks, and then confirm or disprove them. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Terminology&lt;/h1&gt;  &lt;p&gt;Different tools often use different names for the same memory metrics. The following table maps the naming across three popular tools – the OS-provided &lt;a href="http://msdn.microsoft.com/en-us/library/aa373083(VS.85).aspx"&gt;Performance Counters&lt;/a&gt;, &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx"&gt;Process Explorer&lt;/a&gt; and Task Manager (on Windows 7). &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart7MemoryLeakDete_620F/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart7MemoryLeakDete_620F/image_thumb.png" width="752" height="344" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Except when necessary to resolve inconsistencies, TestApi typically follows the naming convention that is used by the Performance Counters. For an in-depth description of all metrics, refer to the TestApi reference documentation.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Usage&lt;/h1&gt;  &lt;p&gt;Now let’s demonstrate the usage of the API through a few examples...&lt;/p&gt;  &lt;h2&gt;Example #1&lt;/h2&gt;  &lt;p&gt;TestApi provides the &lt;b&gt;MemorySnapshot&lt;/b&gt; class, which helps you capture, serialize, deserialize, and make initial comparisons of the memory state of a process. The following example demonstrates how to use the MemorySnapshot class to display memory usage differences for a given process.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;MemorySnapshot&lt;/strong&gt; gives you a very easy way to capture crude memory information for your process. In this first version of the API we don’t provide facilities to track individual memory allocations – we will provide these in a future revision of the API.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//&lt;/span&gt;
&lt;span class="rem"&gt;// Taking two memory snapshots of Notepad and comparing them for leaks&lt;/span&gt;
&lt;span class="rem"&gt;//&lt;/span&gt;

&lt;span class="rem"&gt;// Start an instance of Notepad.exe, get its PID, and take a memory snapshot&lt;/span&gt;
Process p = Process.Start(&lt;span class="str"&gt;&amp;quot;notepad.exe&amp;quot;&lt;/span&gt;);
p.WaitForInputIdle(5000);
&lt;span class="kwrd"&gt;int&lt;/span&gt; pid = p.Id;
MemorySnapshot s1 = MemorySnapshot.FromProcess(pid);

&lt;span class="rem"&gt;//&lt;/span&gt;
&lt;span class="rem"&gt;// Perform operations that may cause a leak in Notepad...&lt;/span&gt;
&lt;span class="rem"&gt;//&lt;/span&gt;

&lt;span class="rem"&gt;// Capture a second snapshot&lt;/span&gt;
MemorySnapshot s2 = MemorySnapshot.FromProcess(pid);

&lt;span class="rem"&gt;// Compare the two memory snapshots and generate a diff.&lt;/span&gt;
&lt;span class="rem"&gt;// Then display the diff to the console.&lt;/span&gt;
MemorySnapshot diff = s2.CompareTo(s1);

Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Memory diff for process {0}:&amp;quot;&lt;/span&gt;, pid);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Start time: {0}&amp;quot;&lt;/span&gt;, s1.TimeStamp);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;End time: {0}&amp;quot;&lt;/span&gt;, s2.TimeStamp);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tGDI Object Count: {0}&amp;quot;&lt;/span&gt;, diff.GdiObjectCount);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tHandle Count: {0}&amp;quot;&lt;/span&gt;, diff.HandleCount);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tPageFile Bytes: {0}&amp;quot;&lt;/span&gt;, diff.PageFileBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tPageFile Peak Bytes: {0}&amp;quot;&lt;/span&gt;, diff.PageFilePeakBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tPool Nonpaged Bytes: {0}&amp;quot;&lt;/span&gt;, diff.PoolNonpagedBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tPool Paged Bytes: {0}&amp;quot;&lt;/span&gt;, diff.PoolPagedBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tThread Count: {0}&amp;quot;&lt;/span&gt;, diff.ThreadCount);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tUser Object Count: {0}&amp;quot;&lt;/span&gt;, diff.UserObjectCount);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tVM Bytes: {0}&amp;quot;&lt;/span&gt;, diff.VirtualMemoryBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tVM Private Bytes: {0}&amp;quot;&lt;/span&gt;, diff.VirtualMemoryPrivateBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tWS Bytes: {0}&amp;quot;&lt;/span&gt;, diff.WorkingSetBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tWS Peak Bytes: {0}&amp;quot;&lt;/span&gt;, diff.WorkingSetPeakBytes);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;\tWS Private Bytes: {0}&amp;quot;&lt;/span&gt;, diff.WorkingSetPrivateBytes);

&lt;span class="rem"&gt;// Close the process.&lt;/span&gt;
p.CloseMainWindow();
p.Close();&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Example #2&lt;/h2&gt;

&lt;p&gt;In addition to MemorySnapshot, TestApi provides the &lt;b&gt;MemorySnapshotCollection&lt;/b&gt; class, which allows serialization / deserialization of a series of memory snapshots. The use of this class is demonstrated below:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//&lt;/span&gt;
&lt;span class="rem"&gt;// Taking multiple memory snapshots of Notepad and storing them for&lt;/span&gt;
&lt;span class="rem"&gt;// later analysis&lt;/span&gt;
&lt;span class="rem"&gt;//&lt;/span&gt;

&lt;span class="rem"&gt;// Create a memory snapshot collection and add the snapshots to it.&lt;/span&gt;
MemorySnapshotCollection c = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemorySnapshotCollection();

&lt;span class="rem"&gt;// Start an instance of the target process and wait for it to reach steady state.&lt;/span&gt;
&lt;span class="rem"&gt;// Then take a memory snapshot.&lt;/span&gt;

Process p = Process.Start(&lt;span class="str"&gt;&amp;quot;notepad.exe&amp;quot;&lt;/span&gt;);
p.WaitForInputIdle(5000);
MemorySnapshot s1 = MemorySnapshot.FromProcess(p.Id);
c.Add(s1);

&lt;span class="rem"&gt;// Perform operations that may cause a leak in the target process...&lt;/span&gt;
&lt;span class="rem"&gt;// Then take a second memory snapshot&lt;/span&gt;
MemorySnapshot s2 = MemorySnapshot.FromProcess(p.Id);
c.Add(s2);

&lt;span class="rem"&gt;// Save the collection to a XML file for later analysis.&lt;/span&gt;
c.ToFile(&lt;span class="str"&gt;@&amp;quot;C:\mySnapshots.xml&amp;quot;&lt;/span&gt;);

&lt;span class="rem"&gt;// Close the process.&lt;/span&gt;
p.CloseMainWindow();
p.Close();&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Although admittedly crude in its first version, the memory leak detection API provided by &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; enable easy creation of memory leak detection tests and tools. The documentation provides a lot of information about how the different metrics are calculated with pointers to the relevant articles and OS APIs.&lt;/p&gt;

&lt;p&gt;We will be expanding this API in the future to include allocation tracking as well as advanced leak detection analysis (currently, you have the perform the analysis yourself based on the collected data or fire up a debugger or profiler to analyze a leaky process), so let us know of specific needs, feature requests and ideas, etc.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9995880" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>Introduction to TestApi – Part 6: Text String Generation API</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/14/9995847.aspx</link><pubDate>Wed, 14 Apr 2010 13:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9995847</guid><dc:creator>ivom1</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9995847</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/14/9995847.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx"&gt;Overview of TestApi&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx"&gt;Part 1: Input Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx"&gt;Part 2: Command-Line Parsing APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx"&gt;Part 3: Visual Verification APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx"&gt;Part 4: Combinatorial Variation Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/11/25/9928447.aspx"&gt;Part 5: Managed Code Fault Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995847.aspx"&gt;Part 6: Text String Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995880.aspx"&gt;Part 7: Memory Leak Detection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx"&gt;Part 8: Object Comparison APIs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;h1&gt;General Notes&lt;/h1&gt;  &lt;p&gt;Testing often necessitates constructing strings to deliberately exercise specific features of an application. TestApi provides a text string generation API to facilitate generating strings that are random within a set of fixed parameters, such as the number of characters, target Unicode range, whether or not the string should contain numbers, whether or not the string should contain line breaks, etc.&lt;/p&gt;  &lt;p&gt;The API was created by our engineer Dennis Deng in collaboration with other engineers around the company. &lt;/p&gt;  &lt;h1&gt;Unicode Basics&lt;/h1&gt;  &lt;p&gt;The TestApi text string generation API targets both general testers and professional text testers and exposes functionality for constructing strings given a novice or advanced understanding of Unicode. Two common Unicode concepts which are used throughout the library are defined below. For a comprehensive introduction to Unicode and a complete glossary, visit &lt;a href="http://unicode.org/glossary/"&gt;http://unicode.org/glossary/&lt;/a&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;i&gt;&lt;u&gt;Code Points&lt;/u&gt;&lt;/i&gt;: In Unicode terminology any particular character set is referred to as an &lt;b&gt;Encoding&lt;/b&gt; or &lt;b&gt;Code&lt;/b&gt;. A&lt;i&gt; &lt;/i&gt;&lt;b&gt;code point&lt;/b&gt; is one specific point within a code, i.e. one specific character within a character set.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;i&gt;&lt;u&gt;Unicode Character Code Chart&lt;/u&gt;&lt;/i&gt;: The Unicode standard defines a number of different character sub-sets, which are called &lt;b&gt;Unicode character code charts&lt;/b&gt; (or &lt;b&gt;Unicode charts&lt;/b&gt; for short). These charts are available on &lt;a href="http://unicode.org/charts"&gt;http://unicode.org/charts&lt;/a&gt;. Every chart (represented by the UnicodeChart class) is uniquely identified by three properties: group name, name and sub-name. For example, the “Armenian Ligatures” chart has a group name of “European Scripts”, name of “Armenian” and sub-name of “Armenian Ligatures”. It is important to note that the Unicode charts are versioned. TestApi supports the Unicode chart which is built in the referenced version of the .NET framework. &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;String Generation Technology&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;i&gt;&lt;u&gt;StringFactory&lt;/u&gt;&lt;/i&gt;: A StringFactory is an object used for generating random strings. Rather than constructing purely random strings, the factory will generate strings within a certain set of parameters, determined by a provided StringProperties object.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;i&gt;&lt;u&gt;StringProperties&lt;/u&gt;&lt;/i&gt;: A StringProperties object specifies the properties of a string to be randomly generated by a StringFactory, such as the number of unique characters or the Unicode character set (or subset) to use. A StringProperties object is passed to StringFactory.GenerateRandomString(…).       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;i&gt;&lt;u&gt;UnicodeRange&lt;/u&gt;&lt;/i&gt;: A UnicodeRange is a range of Unicode code points. A StringProperties object contains a UnicodeRange. When the UnicodeRange of a particular StringProperties object is set to a particular range of values, any strings generated using that StringProperties object will be confined to the given UnicodeRange. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart6TextStringGene_41FB/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart6TextStringGene_41FB/image_thumb_1.png" width="644" height="346" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Example #1&lt;/h2&gt;  &lt;p&gt;The following example demonstrates how to generate a Cyrillic string that contains between 10 and 30 characters.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//&lt;/span&gt;
&lt;span class="rem"&gt;// Generate a Cyrillic string with a length between 10 and 30 characters.&lt;/span&gt;
&lt;span class="rem"&gt;//&lt;/span&gt;

StringProperties properties = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringProperties();
properties.MinNumberOfCodePoints = 10;
properties.MaxNumberOfCodePoints = 30;
properties.UnicodeRanges.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; UnicodeRange(UnicodeChart.Cyrillic));

&lt;span class="kwrd"&gt;string&lt;/span&gt; s = StringFactory.GenerateRandomString(properties, 1234);&lt;/pre&gt;
&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The generated string may look as follows:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;font size="5"&gt;
s: Ӥёӱіӱӎ҄ҤяѪӝӱѶҾүҕГ

&lt;/font&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Notice how the string contains 17 characters that are all part of the &lt;a href="http://www.unicode.org/charts/PDF/U0400.pdf"&gt;Cyrillic character code chart&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Example #2&lt;/h2&gt;

&lt;p&gt;The following example demonstrates how to generate a string of a fixed length with numbers.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// &lt;/span&gt;
&lt;span class="rem"&gt;// Generate a string of 20 random code points containing numbers.&lt;/span&gt;
&lt;span class="rem"&gt;//&lt;/span&gt;

StringProperties properties = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringProperties();
properties.MinNumberOfCodePoints = 20;
properties.MaxNumberOfCodePoints = 20;
properties.HasNumbers = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
properties.UnicodeRanges.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; UnicodeRange(0, 0xFFFF));

&lt;span class="kwrd"&gt;string&lt;/span&gt; s1 = StringFactory.GenerateRandomString(properties, 5678);
&lt;span class="kwrd"&gt;string&lt;/span&gt; s2 = StringFactory.GenerateRandomString(properties, 5678);&lt;/pre&gt;
&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The generated strings may look as follows:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;font size="5"&gt;
s1: 鼯粳뷷賵Ɨ烣૝犥0崪𣏕窚氢ཝꥁ姽戁䅽7
s2: 鼯粳뷷賵Ɨ烣૝犥0崪𣏕窚氢ཝꥁ姽戁䅽7

&lt;/font&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Notice how the strings contain numbers and have exactly 20 code points (characters). Notice also how using the same seed (5678) results in generation of exactly the same strings.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Text string generation is a tricky. &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; exposes a simple straightforward API for generation of text strings from a set of desired string properties.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9995847" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category></item><item><title>A Few Good Posts on WPF 4</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/13/9995149.aspx</link><pubDate>Tue, 13 Apr 2010 14:59:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9995149</guid><dc:creator>ivom1</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9995149</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/04/13/9995149.aspx#comments</comments><description>&lt;p&gt;Yesterday, we celebrated the &lt;a href="http://www.microsoft.com/visualstudio/en-us/visual-studio-events"&gt;official release of Visual Studio 2010&lt;/a&gt; and .NET 4. Check out Bob Muglia’s keynote &lt;a href="http://www.microsoft.com/visualstudio/en-us/watch-it-live"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;One of the major changes in VS 2010 is the fact that its UI was built using WPF. We in the WPF team had to do a fair amount of work to support the migration of the VS UI to WPF. Paul Harrington’s series on &lt;a href="http://blogs.msdn.com/visualstudio/archive/2010/02/16/wpf-in-visual-studio-2010-part-1.aspx"&gt;WPF in Visual Studio 2010&lt;/a&gt; has all the details.&lt;/p&gt;  &lt;p&gt;There is, however, a lot more that is new and fresh in WPF 4 in addition to VS-related improvements.&lt;/p&gt;  &lt;p&gt;Here is a list of a few blog posts that walk through the new features:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pete Brown&lt;/strong&gt;, a Community PM of ours, has an excellent post called &lt;a href="http://10rem.net/blog/2010/04/12/wpf-4-release-a-guide-to-the-new-features"&gt;WPF 4 Release: A guide to the new features&lt;/a&gt;. See Scott Guthrie’s &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/10/26/wpf-4-vs-2010-and-net-4-0-series.aspx"&gt;post on WPF 4&lt;/a&gt; too. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Jossef Goldberg&lt;/strong&gt;, our Deployment and Performance PM, has a couple of posts on deployment (&lt;a href="http://blogs.msdn.com/jgoldb/archive/2010/04/12/what-s-new-in-net-framework-4-client-profile-rtm.aspx"&gt;What’s new in .NET Framework 4 Client Profile RTM&lt;/a&gt;) and performance (&lt;a href="http://blogs.msdn.com/jgoldb/archive/2010/04/12/what-s-new-for-performance-in-wpf-in-net-4.aspx"&gt;What’s New for Performance in WPF in .NET 4&lt;/a&gt;).&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Chipalo Street&lt;/strong&gt;, our Text PM, has several blog entries on text clarity – a big area of investment for WPF 4. I recommend starting with the &lt;a href="http://blogs.msdn.com/text/archive/2010/03/05/additional-wpf-text-clarity-improvements.aspx"&gt;Additional WPF Text Clarity Improvements&lt;/a&gt; post. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lester Lobo&lt;/strong&gt;, the XAML SDET Lead for .NET 4, has a great &lt;a href="http://blogs.msdn.com/llobo/archive/tags/New+WPF+4+features/default.aspx"&gt;series of posts on new WPF 4 features&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Enjoy WPF 4 and VS 2010!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9995149" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/-NET/">.NET</category></item><item><title>The 22 Minute Meeting</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/03/09/9975744.aspx</link><pubDate>Tue, 09 Mar 2010 21:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9975744</guid><dc:creator>ivom1</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9975744</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/03/09/9975744.aspx#comments</comments><description>&lt;p&gt;A good back-to-basics &lt;a href="http://www.scottberkun.com/blog/2010/the-22-minute-meeting/"&gt;article by Scott Berkun&lt;/a&gt; on how to do efficient meetings, based on the original idea by &lt;a href="http://twitter.com/nicolesteinbok"&gt;Nicole Steinbok&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;And here is the poster that says it all:&lt;/p&gt;  &lt;p&gt;&lt;img title="22meeting" alt="" src="http://www.scottberkun.com/wp-content/uploads/2010/03/22meeting1.png" width="517" height="495" /&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9975744" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Project+Management/">Software Project Management</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Project+Management/">Project Management</category></item><item><title>February 2010 WPF Toolkit Release</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2010/02/23/9968494.aspx</link><pubDate>Wed, 24 Feb 2010 05:59:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9968494</guid><dc:creator>ivom1</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9968494</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2010/02/23/9968494.aspx#comments</comments><description>&lt;p&gt;I am happy to announce that we have just released the February 2010 release of the WPF Toolkit! The toolkit contains updated versions of previously released components (DataGrid, DatePicker, Calendar and VSM) as well as WPF ports of 3 popular controls from the Silverlight toolkit -- the AutoCompleteBox, Accordion and Rating controls.&lt;/p&gt;  &lt;p&gt;Check out this new release on &lt;a href="http://wpf.codeplex.com/releases/view/40535"&gt;http://wpf.codeplex.com/releases/view/40535&lt;/a&gt; and of course – share your feedback. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9968494" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/WPF/">WPF</category></item><item><title>Introduction to TestApi – Part 5: Managed Code Fault Injection APIs</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2009/11/25/9928447.aspx</link><pubDate>Wed, 25 Nov 2009 08:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9928447</guid><dc:creator>ivom1</dc:creator><slash:comments>20</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9928447</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2009/11/25/9928447.aspx#comments</comments><description>&lt;h1&gt;Series Index&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx"&gt;Overview of TestApi&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx"&gt;Part 1: Input Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx"&gt;Part 2: Command-Line Parsing APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx"&gt;Part 3: Visual Verification APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx"&gt;Part 4: Combinatorial Variation Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/11/25/9928447.aspx"&gt;Part 5: Managed Code Fault Injection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995847.aspx"&gt;Part 6: Text String Generation APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2010/04/14/9995880.aspx"&gt;Part 7: Memory Leak Detection APIs&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/ivo_manolov/archive/2010/07/29/10043968.aspx"&gt;Part 8: Object Comparison APIs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Fault_injection" mce_href="http://en.wikipedia.org/wiki/Fault_injection"&gt;Fault Injection&lt;/a&gt; is the act of artificially changing the behavior of an existing executable code to simulate various faults. FI is very useful for validation of error handling code paths and for improving code coverage. &lt;/p&gt;  &lt;p&gt;There are several types of fault injection. In runtime fault injection, the fault injecting test modifies the execution logic of the application under test (AUT), by injecting faults, triggered by specific runtime conditions. One could for example implement a FI test with the following semantic:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;i&gt;Throw an out-of-memory (OOM) exception, whenever the application calls method CreateWidget of class WidgetManager.&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The FI terminology is as follows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;AUT (application under test)&lt;/b&gt; – this is the tested application, in which faults are being injected; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Fault Rule&lt;/b&gt; – The fault rule is a central construct in an FI test that determines WHEN faults get triggered and WHAT TYPES of faults get triggered. A fault rule consists of:       &lt;ul&gt;       &lt;li&gt;a &lt;b&gt;Method Signature&lt;/b&gt;, determining the method where the fault will be injected; &lt;/li&gt;        &lt;li&gt;a &lt;b&gt;Fault Condition&lt;/b&gt;, determining when the specific fault should be triggered (e.g. every N&lt;sup&gt;th&lt;/sup&gt; call) &lt;/li&gt;        &lt;li&gt;a&lt;b&gt; Fault &lt;/b&gt;-- Determines the type of fault (e.g. throwing an exception, returning a specific value, etc.) that occurs when the fault condition is met. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Fault Session &lt;/b&gt;– The fault session is a collection of fault rules that are applied to a given AUT. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;TestApi provides a simple, but powerful &lt;em&gt;runtime fault injection API&lt;/em&gt; for injecting faults in managed code. The API was originally designed and implemented by Bill Liu et al from the “Essential Business Server” team, and adapted to &lt;a href="http://codeplex.com/testapi" mce_href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; by Sam Terilli from our WPF XAML team. The following content provides a quick introduction to the API.&lt;/p&gt;  &lt;h1&gt;Sample AUT&lt;/h1&gt;  &lt;p&gt;Following is the code of a trivial AUT that we will use for demonstration purposes:&lt;/p&gt;  &lt;div style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 1pt; padding-left: 4pt; padding-right: 4pt; background: rgb(242,242,242) 0% 50%; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 1pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;&lt;code&gt;     &lt;pre&gt;&lt;font color="#008000"&gt;//
// This is a sample application used for demonstration purposes.
//&lt;/font&gt;
using System;

class MyApplication
{
    static void Main(string[] args)
    {
        int a = 2;
        int b = 3;

        for (int i = 0; i &amp;lt; 10; i++)
        {
            Console.WriteLine(&amp;quot;{0}) {1} + {2} = {3}&amp;quot;, i, a, b, Sum(a, b));
        }
    }

    private static int Sum(int a, int b)
    {
        return a + b;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/code&gt;&lt;/code&gt;

  &lt;div&gt;&lt;/div&gt;

  &lt;p&gt;The result of running this application is of course:&lt;/p&gt;
  &lt;code&gt;&lt;strong&gt;&amp;gt; MyApplication.exe&lt;/strong&gt; 

    &lt;br /&gt;0) 2 + 3 = 5 

    &lt;br /&gt;1) 2 + 3 = 5 

    &lt;br /&gt;2) 2 + 3 = 5 

    &lt;br /&gt;3) 2 + 3 = 5 

    &lt;br /&gt;4) 2 + 3 = 5 

    &lt;br /&gt;5) 2 + 3 = 5 

    &lt;br /&gt;6) 2 + 3 = 5 

    &lt;br /&gt;7) 2 + 3 = 5 

    &lt;br /&gt;8) 2 + 3 = 5 

    &lt;br /&gt;9) 2 + 3 = 5 &lt;/code&gt;

  &lt;h1&gt;&amp;#160;&lt;/h1&gt;

  &lt;h1&gt;A Simple Fault Injection Test&lt;/h1&gt;

  &lt;p&gt;Now, let’s try to inject a fault in the AUT. Let’s assume that we want to modify the return value of Sum. Here’s how we can accomplish that:&lt;/p&gt;

  &lt;div style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 1pt; padding-left: 4pt; padding-right: 4pt; background: rgb(242,242,242) 0% 50%; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 1pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial"&gt;&lt;code&gt;
      &lt;pre&gt;&lt;font color="#008000"&gt;// 
// Simple fault injection test
//&lt;/font&gt;
using System;
using System.Diagnostics;
&lt;font style="background-color: yellow"&gt;using Microsoft.Test.FaultInjection;
&lt;/font&gt;
public class FaultInjectionTest 
{ 
    public static void Main() 
    { 
&lt;font color="#008000"&gt;        // 
        // Set up a fault rule to return –1000 the second time Sum is called.
        //&lt;/font&gt;
        string method = &amp;quot;MyApplication.Sum(int,int)&amp;quot;;
        &lt;font style="background-color: yellow"&gt;ICondition&lt;/font&gt; condition = BuiltInConditions.TriggerOnNthCall(2);
        &lt;font style="background-color: yellow"&gt;IFault&lt;/font&gt; fault = BuiltInFaults.ReturnValueFault(-1000);
        &lt;font style="background-color: yellow"&gt;FaultRule&lt;/font&gt; rule = new FaultRule(method, condition, fault);            

&lt;font color="#008000"&gt;        //
        // Establish a session, injecting the faults defined by the fault rule(s)
        //&lt;/font&gt;
        &lt;font style="background-color: yellow"&gt;FaultSession&lt;/font&gt; session = new FaultSession(rule);
        ProcessStartInfo psi = session.GetProcessStartInfo(@&amp;quot;.\MyApplication.exe&amp;quot;); 

&lt;font color="#008000"&gt;        //
        // Launch the target process and observe faults
        //&lt;/font&gt;
        Process p = Process.Start(psi);        
        p.WaitForExit();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/code&gt;&lt;/code&gt;

    &lt;div&gt;&lt;/div&gt;

    &lt;p&gt;Fairly straightforward. Upon running the test (which will itself spawn the AUT) we observe the following output:&lt;/p&gt;

    &lt;p mce_keep="true"&gt;&lt;code&gt;&lt;strong&gt;&amp;gt; FaultInjectionTest.exe&lt;/strong&gt; 

        &lt;br /&gt;0) 2 + 3 = 5 

        &lt;br /&gt;&lt;font style="background-color: red"&gt;1) 2 + 3 = -1000&lt;/font&gt; 

        &lt;br /&gt;2) 2 + 3 = 5 

        &lt;br /&gt;3) 2 + 3 = 5 

        &lt;br /&gt;4) 2 + 3 = 5 

        &lt;br /&gt;5) 2 + 3 = 5 

        &lt;br /&gt;6) 2 + 3 = 5 

        &lt;br /&gt;7) 2 + 3 = 5 

        &lt;br /&gt;8) 2 + 3 = 5 

        &lt;br /&gt;9) 2 + 3 = 5&lt;/code&gt; &lt;/p&gt;

    &lt;p&gt;As intended, we injected a runtime fault in MyApplication.exe, which resulted in Sum returning –1000 the second time it got called.&lt;/p&gt;

    &lt;h1&gt;Under The Covers&lt;/h1&gt;

    &lt;p&gt;Under the covers, the managed code Fault Injection API uses the CLR profiling API to modify the prologue of the intercepted method at runtime in order to inject the desired fault. The injected prologue instructions essentially call a method in the library, which then dispatches the call to the specified fault. &lt;/p&gt;

    &lt;p&gt;Because faults are injected at runtime, the code of the original application is not modified in any way. There is a certain performance degradation, which depends on the number of the injected faults. &lt;/p&gt;

    &lt;p&gt;The fault injection API provides a variety of built-in conditions and faults (in the &lt;strong&gt;BuiltInConditions&lt;/strong&gt; and &lt;strong&gt;BuiltInFaults&lt;/strong&gt; classes respectively). Users of the API can also create custom conditions and faults (by implementing the &lt;strong&gt;ICondition&lt;/strong&gt; and &lt;strong&gt;IFault&lt;/strong&gt; interfaces respectively). The API also provides a set of classes that expose the ability to fine tune and monitor the injected faults.&lt;/p&gt;

    &lt;p&gt;In addition, the API provides a facility to set “global faults”, which is useful for server application testing, where one application typically consists of and recycles many different processes.&lt;/p&gt;

    &lt;p&gt;I have attached the sample above, which should get you up and running with fault injection. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9928447" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-92-84-47/FaultInjectionSample.zip" length="718596" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Testing/">Software Testing</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/-NET+3-5/">.NET 3.5</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/TestApi/">TestApi</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Software+Test+Automation/">Software Test Automation</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Fault+Injection/">Fault Injection</category></item><item><title>Application Accessibility Testing</title><link>http://blogs.msdn.com/b/ivo_manolov/archive/2009/11/24/9928304.aspx</link><pubDate>Wed, 25 Nov 2009 00:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9928304</guid><dc:creator>ivom1</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/ivo_manolov/rsscomments.aspx?WeblogPostID=9928304</wfw:commentRss><comments>http://blogs.msdn.com/b/ivo_manolov/archive/2009/11/24/9928304.aspx#comments</comments><description>&lt;p&gt;A lot of our customers and partners have asked us to provide guidance on how to make their WPF and Silverlight applications accessible, so I decided to publish a post folks can refer to. Note most of the content below is directly applicable to any other Windows application.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Introduction&lt;/h1&gt;  &lt;p&gt;In general “Accessibility” means two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;u&gt;Nominal accessibility&lt;/u&gt;: An application or an application programming stack exposes the necessary information so that it makes its UI elements accessible;       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;u&gt;Accessibility with an accessibility tool&lt;/u&gt;: An accessibility tool (e.g. a screen reader) can access the UI of a given application and expose the UI to its users. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;For an application to be “accessible”, ideally it would satisfy both (1) and (2) i.e. be both nominally accessible and also accessible with popular accessibility tools. Satisfying (1) guarantees that the level of accessibility of an application does not depend significantly on the accessibility tool. Satisfying (2) guarantees that a disabled user can interact with an application, when using a particular accessibility tool. Satisfying (2) is clearly more important, and as a matter of fact the various accessibility tools go to extraordinary lengths to make applications that are not nominally accessible be accessible through the tool. &lt;/p&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;Accessibility tools use several techniques to build an accurate in-memory representation of what is presented on the screen:&lt;/p&gt;  &lt;ol type="i"&gt;   &lt;li&gt;Public accessibility API &lt;/li&gt;    &lt;li&gt;Public platform API &lt;/li&gt;    &lt;li&gt;Kernel interfaces &lt;/li&gt;    &lt;li&gt;In-process code injection &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Microsoft provides two accessibility API – &lt;a href="http://msdn.microsoft.com/en-us/library/ms697707(VS.85).aspx"&gt;MSAA&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms747327.aspx"&gt;UIA&lt;/a&gt;. MSAA is a legacy API, introduced circa 1996, which is not extensible and is no longer sufficient for modern UIs. UIA is the new much richer and fully extensible Accessibility API from Microsoft, originally introduced in WPF / Windows Vista in 2007.&lt;/p&gt;  &lt;p&gt;It’s important to note that many existing Win32 applications &lt;u&gt;are not nominally accessible&lt;/u&gt;. I.e. they do not expose the right accessibility information, using public accessibility API. They are only made accessible through the use (by the accessibility tools) of techniques such as (ii), (iii) and (iv) above.&lt;/p&gt;  &lt;p align="center"&gt;+++&lt;/p&gt;  &lt;p&gt;Accessibility API typically expose:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;u&gt;Provider API&lt;/u&gt; : these are the API used by an application stack to expose its UI elements; &lt;/li&gt;    &lt;li&gt;&lt;u&gt;Client API&lt;/u&gt;: these are the API used by an accessibility tool (e.g. a screen reader) to query the UI elements of an application. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;MSAA and UIA both conform to that client-provider model. There is also a bridge between MSAA and UIA, which allows a client using the MSAA client API to access an application exposed through UIA.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;General Accessibility Testing Workflow&lt;/h1&gt;  &lt;p&gt;Microsoft provides a number of accessibility testing tools that can help with identifying of nominal accessibility problems. Combining these with the target accessibility tool is the winning recipe for creating of fully accessible applications.&lt;/p&gt;  &lt;p&gt;Below is a suggested accessibility testing work-flow:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="654"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;&lt;b&gt;Step&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;&lt;b&gt;If “Pass”&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;&lt;b&gt;if “Fail”&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;1. Run “AccChecker”            &lt;br /&gt;(download from &lt;a href="http://www.codeplex.com/AccCheck"&gt;here&lt;/a&gt;)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;Go to step 2&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;Fix reported issues            &lt;br /&gt;Go to step 2&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;2. Run “UIA Verify”            &lt;br /&gt;(download from &lt;a href="http://uiautomationverify.codeplex.com/"&gt;here&lt;/a&gt;)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;Go to step 3&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;Fix reported issues            &lt;br /&gt;Go to step 3&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;3. Run “Inspect”            &lt;br /&gt;(download from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=3755582A-A707-460A-BF21-1373316E13F0&amp;amp;displaylang=en"&gt;here&lt;/a&gt;)             &lt;br /&gt;- only for focus and caret tracking testing&lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;Go to step 4&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;Fix reported issues            &lt;br /&gt;Go to step 4&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;4. Verify contrast, DPI, color, magnification            &lt;br /&gt;(see next table)&lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;Go to step 5&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;Fix issues            &lt;br /&gt;Go to step 5&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="340"&gt;         &lt;p&gt;5. Run target accessibility tool &lt;/p&gt;       &lt;/td&gt;        &lt;td width="114"&gt;         &lt;p&gt;DONE&lt;/p&gt;       &lt;/td&gt;        &lt;td width="198"&gt;         &lt;p&gt;Contact tool vendor.            &lt;br /&gt;Report issue to Microsoft.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;For contrast, DPI, color and magnification verification (step 4 above), use the following tools and steps:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;b&gt;Test Criteria&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;&lt;b&gt;Verification Tools and Steps&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;High-contrast&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Control Panel - Ease of Access            &lt;br /&gt;Switch to each of 6 High Contrast modes&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;High-DPI&lt;/p&gt;                 &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Control Panel – Display            &lt;br /&gt;Switch to 150% (1200x1000 min resolution)             &lt;br /&gt;Switch to 200% (1600x1200 min resolution)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Redundant Color Information&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Use a tool such as &lt;a href="http://design.fujitsu.com/en/universal/assistance/colordoctor/"&gt;Fujitsu’s Color Doctor&lt;/a&gt;             &lt;br /&gt;Try each of the 4 conversion filters&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Magnifier tracks all keyboard navigation&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Control Panel – Ease of Access – Magnifier            &lt;br /&gt;Enable follow mouse/keyboard/insertion point             &lt;br /&gt;Use WinKey+Plus / WinKey+Minus to change magnification&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;All UIs respect the accessibility system settings&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Control Panel – Ease of Access&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;All documentation is accessible&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;All UIs have 5:1 or higher contrast ratio of text to background&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Use a tool such as the &lt;a href="http://www.paciellogroup.com/resources/contrast-analyser.html"&gt;Color Contrast Analyzer&lt;/a&gt;             &lt;br /&gt;Install the luminosity and brightness version&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;All UIs can be used fully with On-Screen Keyboard&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Control Panel – On-Screen-Keyboard (OSK.EXE)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;UIs do not flash with rate between 2 Hz and 55 Hz&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;Use a tool such as &lt;a href="http://trace.wisc.edu/peat/#download"&gt;PEAT (Photosensitive Epilepsy Analyzer Tool)&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;WPF Accessibility&lt;/h1&gt;  &lt;p&gt;WPF is a fully accessible stack. WPF uses UIA (in fact the original UIA team used to be part of the WPF team) to provide access to the various UI elements. All standard WPF elements (packaged controls, etc.) implement the necessary client-side UIA interfaces to expose themselves to accessibility readers. &lt;/p&gt;  &lt;p&gt;Development and testing of nominally accessible WPF applications is fairly straightforward. For more information, refer to the &lt;a href="http://windowsclient.net/wpf/white-papers/wpf-app-quality-guide.aspx#accessibilitytesting"&gt;“Accessibility Testing” section in the “WPF Application Quality Guide”&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;While following these guidelines will result in nominally accessible applications, it is important to once again stress that all applications should also be tested with the target accessibility tool to confirm that they are truly accessible from the point of view of a disabled user.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9928304" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Accessibility/">Accessibility</category><category domain="http://blogs.msdn.com/b/ivo_manolov/archive/tags/Silverlight/">Silverlight</category></item></channel></rss>