<?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 : Software Test Automation</title><link>http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx</link><description>Tags: Software Test Automation</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Introduction to TestApi – Part 5: Managed Code Fault Injection APIs</title><link>http://blogs.msdn.com/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>ivom</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9928447.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9928447</wfw:commentRss><description>&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;H2&gt;Sample AUT&lt;/H2&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("{0}) {1} + {2} = {3}", 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;/DIV&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;H2&gt;A Simple Fault Injection Test&lt;/H2&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 = "MyApplication.Sum(int,int)";
        &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(@".\MyApplication.exe"); 

&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;/DIV&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;H2&gt;Under The Covers&lt;/H2&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;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&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/ivo_manolov/attachment/9928447.ashx" length="718596" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>TestApi v0.4 Released!</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/11/21/9926003.aspx</link><pubDate>Sat, 21 Nov 2009 21:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9926003</guid><dc:creator>ivom</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9926003.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9926003</wfw:commentRss><description>&lt;p&gt;I am happy to announce that we have just released version 0.4 of &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; – the testing API library - on Codeplex. &lt;/p&gt;  &lt;p&gt;Version 0.4 contains the following additions and modifications:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;An improved &lt;u&gt;Combinatorial Variation Generation API&lt;/u&gt; with added support for parameter value weights and tags (for “negative” variations); &lt;/li&gt;    &lt;li&gt;A new &lt;u&gt;Memory Leak Detection API&lt;/u&gt; allowing capture, comparison and serialization / de-serialization of memory snapshots of a running process; &lt;/li&gt;    &lt;li&gt;A new &lt;u&gt;Object Comparison API&lt;/u&gt; allowing comparison of arbitrary .NET objects, using arbitrary object comparison strategies; &lt;/li&gt;    &lt;li&gt;A new &lt;u&gt;Text String Generation API&lt;/u&gt;, allowing generation of random strings, for testing purposes; &lt;/li&gt;    &lt;li&gt;Various documentation and sample improvements. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We will be blogging about some of these API in the near future. As always, TestApi is available on &lt;a href="http://codeplex.com/testapi"&gt;&lt;strong&gt;http://codeplex.com/testapi&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9926003" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Win32/default.aspx">Win32</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>TestApi Slide-Deck from the Patterns &amp; Practices Summit</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx</link><pubDate>Thu, 15 Oct 2009 05:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9907447</guid><dc:creator>ivom</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9907447.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9907447</wfw:commentRss><description>This week is Microsoft’s Patterns &amp;amp; Practices summit in Redmond . Earlier today I gave a 15-minute presentation on TestApi . Here is the slide-deck: Test Api View more presentations from ivom1234 ....(&lt;a href="http://blogs.msdn.com/ivo_manolov/archive/2009/10/14/9907447.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9907447" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Win32/default.aspx">Win32</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>Introduction to TestApi – Part 4: Combinatorial Variation Generation APIs</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/08/26/9884004.aspx</link><pubDate>Thu, 27 Aug 2009 03:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9884004</guid><dc:creator>ivom</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9884004.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9884004</wfw:commentRss><description>&lt;P&gt;The state and behavior of every software system depends on a number of parameters. These parameters can be both inputs as well as environmental factors.&lt;/P&gt;
&lt;P&gt;One can think of software testing as a controlled experiment, where the system under test is observed upon varying of the parameters that affect it, in an attempt to discover unexpected system behavior.&lt;/P&gt;
&lt;P&gt;Depending on who you talk to, the act of generation of these variations is called &lt;STRONG&gt;variation generation&lt;/STRONG&gt;, &lt;STRONG&gt;matrix expansion&lt;/STRONG&gt;, &lt;A href="http://en.wikipedia.org/wiki/Design_of_experiments" mce_href="http://en.wikipedia.org/wiki/Design_of_experiments"&gt;&lt;STRONG&gt;design of experiments (DOE)&lt;/STRONG&gt;&lt;/A&gt;, etc.&lt;/P&gt;
&lt;P align=center&gt;+++&lt;/P&gt;
&lt;H2&gt;The Problem&lt;/H2&gt;
&lt;P&gt;Modern-day software systems are complex and depend on many parameters. Expanding all possible combinations of all parameter values often results in a phenomenon called &lt;STRONG&gt;matrix explosion&lt;/STRONG&gt; – having an overwhelmingly high number of test variations. &lt;/P&gt;
&lt;P&gt;Matrix explosion is undesirable because:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;It &lt;U&gt;increases the runtime&lt;/U&gt; of your tests (which, among other things, makes TDD impractical and TDD is the single most effective way to ensure high product quality); &lt;/LI&gt;
&lt;LI&gt;It &lt;U&gt;increases the support costs&lt;/U&gt; of your tests – for a test pool of 100,000 tests, even with 99% pass rate (which in reality is hard to achieve), you still have to investigate 1,000 test failures. Investigating 1,000 test failures is always more expensive than investigating say 10 failures; &lt;/LI&gt;
&lt;LI&gt;It is often &lt;U&gt;impractical or impossible to cover all combinations&lt;/U&gt;, so you end up with partial test coverage (very often “vanilla” test coverage). &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;There are many ways to deal with matrix explosion, which depend on various system and/or experimental constraints. The theory and practice of DOE deals with that.&amp;nbsp; &lt;/P&gt;
&lt;H2&gt;TestApi’s Solution &lt;/H2&gt;
&lt;P&gt;&lt;A href="http://codeplex.com/testapi" mce_href="http://codeplex.com/testapi"&gt;TestApi&lt;/A&gt; provides a generic API for combinatorial variation generation, using the algorithm presented in Jacek Czerwonka’s “&lt;A href="http://www.pairwise.org/docs/pnsqc2006/PNSQC%20140%20-%20Jacek%20Czerwonka%20-%20Pairwise%20Testing%20-%20BW.pdf" mce_href="http://www.pairwise.org/docs/pnsqc2006/PNSQC%20140%20-%20Jacek%20Czerwonka%20-%20Pairwise%20Testing%20-%20BW.pdf"&gt;Pairwise Testing in Real World&lt;/A&gt;” article. The API uses the following nomenclature:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Parameter&lt;/STRONG&gt; – represents a single factor / variable and its values; &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Constraint&lt;/STRONG&gt; – represents a relationship between parameters, their values, constants, and other constraints; &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Model&lt;/STRONG&gt; – contains all parameters and constraints for the system, for which we are generating variations; &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Variation&lt;/STRONG&gt; – represents a tuple with a single value for every Parameter in the Model. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;All of these are represented as correspondingly named types. Following are several examples demonstrating the use of the API. &lt;/P&gt;
&lt;H2&gt;Example 1 : Simple Matrix&lt;/H2&gt;
&lt;P&gt;For the purposes of a simple artificial example, consider having a system with the following parameters and values:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=0 width=334&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=100&gt;&lt;STRONG&gt;Parameter&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=232&gt;&lt;STRONG&gt;Values&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=100&gt;Color&lt;/TD&gt;
&lt;TD vAlign=top width=232&gt;White, Green, Red&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=100&gt;Height&lt;/TD&gt;
&lt;TD vAlign=top width=232&gt;Short, Tall&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=100&gt;Size&lt;/TD&gt;
&lt;TD vAlign=top width=232&gt;Small, Medium, Large&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Assuming, there are no constraints, here is the code you would use to create a model&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;PRE&gt;&lt;CODE&gt;using System;
using System.Collections.Generic;
&lt;FONT style="BACKGROUND-COLOR: yellow"&gt;using Microsoft.Test.VariationGeneration;&lt;/FONT&gt;

class Example1
{
    static void Main(string[] args)
    {
&lt;FONT color=#008000&gt;        //
        // Declare all parameters and construct a model
        //&lt;/FONT&gt;
        &lt;FONT style="BACKGROUND-COLOR: yellow"&gt;Parameter&lt;/FONT&gt; p1 = new Parameter("Color") { "White", "Green", "Red" };
        Parameter p2 = new Parameter("Height") { "Short", "Tall" };
        Parameter p3 = new Parameter("Size") { "Small", "Medium", "Large" };

        &lt;FONT style="BACKGROUND-COLOR: yellow"&gt;Model&lt;/FONT&gt; m = new Model(new List&amp;lt;Parameter&amp;gt;
&lt;PARAMETER&gt; { p1, p2, p3 } );

&lt;FONT color=#008000&gt;        //
        // Generate and print out all possible variations of the parameters in the model
        //&lt;/FONT&gt;
        foreach (&lt;FONT style="BACKGROUND-COLOR: yellow"&gt;Variation&lt;/FONT&gt; v in m.GenerateVariations(3, 1234))
        {
            System.Console.WriteLine("{0}\t{1}\t{2}", v[p1.Name], v[p2.Name], v[p3.Name]);
        }
    }
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Executing the code below produces the following 3*2*3=18 variations, representing all possible combinations of the values of the three parameters:&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;PRE&gt;&lt;CODE&gt;&lt;STRONG&gt;&amp;gt; Example1.exe&lt;/STRONG&gt;
White   Short   Small
White   Short   Medium
White   Short   Large
White   Tall    Small
White   Tall    Medium
White   Tall    Large
Green   Short   Small
Green   Short   Medium
Green   Short   Large
Green   Tall    Small
Green   Tall    Medium
Green   Tall    Large
Red     Short   Small
Red     Short   Medium
Red     Short   Large
Red     Tall    Small
Red     Tall    Medium
Red     Tall    Large&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;The variations are generated by the call to &lt;STRONG&gt;GenerateVariations(3, 1234)&lt;/STRONG&gt;. The number "1234" is the seed for the random generator, utilized by the algorithm. The number "3" is the order of the generated combinations. The order of generated combinations must be a number between 1 and the number of parameters in the model. The output for orders "1" and "2" are presented below:&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;P&gt;&lt;EM&gt;&lt;STRONG&gt;Output for order "1":&lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;White   Short   Small
Green   Tall    Medium
Red     Short   Large&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Output for order "2":&lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;White   Short   Small
White   Tall    Medium
White   Short   Large
Green   Tall    Small
Green   Short   Medium
Green   Tall    Large
Red     Short   Small
Red     Tall    Medium
Red     Tall    Large&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H2&gt;Example 2 : Vacation Planner&lt;/H2&gt;
&lt;P&gt;This example (created by Nathan Anderson – our engineer who designed and implemented the combinatorial variation generation API) demonstrates the use of parameter constraints.&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;PRE&gt;&lt;CODE&gt;Parameter destination = new Parameter("Destination") { "Whistler", "Hawaii", "Las Vegas" };
Parameter hotelQuality = new Parameter("Hotel Quality") { 5, 4, 3, 2, 1 };
Parameter activity = new Parameter("Activity") { "gambling", "swimming", "shopping", "skiing" };

List&amp;lt;Parameter&amp;gt;
&lt;PARAMETER&gt; parameters = new List&amp;lt;Parameter&amp;gt;
&lt;PARAMETER&gt; { destination, hotelQuality, activity };
List&amp;lt;&lt;FONT style="BACKGROUND-COLOR: yellow"&gt;Constraint&lt;/FONT&gt;&amp;gt; constraints = new List&amp;lt;Constraint&amp;gt;&lt;CONSTRAINT&gt;
{
    new &lt;FONT style="BACKGROUND-COLOR: yellow"&gt;IfThenConstraint&lt;/FONT&gt;
    {
        If = destination.Equal("Whistler").Or(destination.Equal("Hawaii")),
        Then = activity.NotEqual("gambling")                        
    },
    new IfThenConstraint
    {
        If = destination.Equal("Las Vegas").Or(destination.Equal("Hawaii")),
        Then = activity.NotEqual("skiing")
    },
    new IfThenConstraint
    {
        If = destination.Equal("Whistler"),
        Then = activity.NotEqual("swimming")
    },
};

Model model = new Model(parameters, constraints);

&lt;FONT color=#008000&gt;//
// Call the method under test with each generated variation
//&lt;/FONT&gt;
foreach (var variation in model.GenerateVariations())
{
    CallVacationPlanner(
        (string)variation[destination.Name], 
        (int)variation[hotelQuality.Name], 
        (string)variation[activity.Name]);
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H2&gt;Example 3 : The WPF Platform Matrix&lt;/H2&gt;
&lt;P&gt;This last example demonstrates how we deal with a real-world problem we face in the WPF team... &lt;/P&gt;
&lt;P&gt;WPF must work reliably on all OS configurations, defined by the following matrix:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=0 width=685&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;&lt;STRONG&gt;Parameter&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=66&gt;&lt;STRONG&gt;Number of Values&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;&lt;STRONG&gt;Values&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;OS&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;6&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;XP SP2, Vista SP1, 7, Server 2003 SP2, Server 2008 SP1, Server 2008 R2&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;Language&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;25&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;&lt;EM&gt;(using 3-letter language abbreviations) &lt;BR&gt;&lt;/EM&gt;ARA, CHS, CHT, CSY, DAN, DEU, ELL, ENG, ESN, FIN, FRA, HEB, HUN, ITA, JPN, KOR, NLD, NOR, PLK, PSE, PTB, PTG, RUS, SVE, TRK &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;System Locale&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;2&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;Same as OS language, TRK&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;Flavor&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;2&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;Free, Checked&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;Platform&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;3&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;x86, x64, x64 wow&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;IE version&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;3&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;OS default, IE7, IE8&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;High DPI&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;2&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;120 DPI, 96 DPI&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;Theme&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;6&lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;Native, Classic, Luna, Royale, Classic High Contrast, Aero&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=92&gt;Side-by-side&lt;/TD&gt;
&lt;TD vAlign=top width=66 align=middle&gt;9 &lt;/TD&gt;
&lt;TD vAlign=top width=525&gt;3.5 SP1 + 4 (3.5 tests), 3.5 SP1 + 4 (4 tests), 3.5 SP1 + 4 - 4 (3.5 tests), 4 + Mock 4.5 (4 tests), 4 + Mock 5 (4 tests), 4 + 3.5 SP1 (4 tests), 4 + 3.5 SP1 (3.5 tests), 4 + 3.5 SP1 - 4 (3.5 tests), 4 (4 tests) &lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Most of the parameters are self-descriptive. “Side-by-side” captures the .NET installation state. For example “3.5 SP1 + 4 - 4 (3.5 tests)” means “install .NET 3.5 SP1, install .NET 4, uninstall .NET 4, run tests built against 3.5 SP1”. This is done to confirm that there are no unexpected side effects as a result of the installation and un-installation of .NET 4.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The trivial full expansion of the matrix results in 583,200 combinations (=6*25*2*2...). Of course, some of these combinations (e.g. XP SP2 OS with a Aero theme) are not valid, but even after removing the invalid combinations, we still end up with a prohibitively large number of platform configurations to test on. &lt;/P&gt;
&lt;P&gt;There are several ways to deal with this problem. One is identifying the so called equivalence classes. For example, from the point of view of Side-by-Side, Vista SP1 and Server 2008 SP1 can be regarded as equivalent OS-es and so on. Another popular approach is reducing regular testing to “vanilla configurations” (e.g. mostly ENG (English), 96-DPI configurations), venturing outside of the “vanilla domain” in accordance with a predefined schedule (e.g. during test passes at the end of major milestones).&amp;nbsp; A third approach is using a pair-wise combinatorial variation generator, reducing the number of platform variations to about 230 – still a fairly high number for any real-world test pool, but clearly much better than the original number above. &lt;/P&gt;
&lt;P&gt;In the WPF team, we use the third approach, combined with an adaptive random algorithm, which prioritizes testing on platform configurations that have not been tested on recently. The simplified code below demonstrates how to construct a model for platform config variation generation.&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;PRE&gt;&lt;CODE&gt;using System;
using System.Collections.Generic; &lt;BR&gt;using Microsoft.Test.CommandLineParsing; &lt;BR&gt;using Microsoft.Test.VariationGeneration;
using Microsoft.Test.VariationGeneration.Constraints;

public class OsVariationGeneration
{
    public static void Main(string[] args)
    {            
        CommandLineDictionary d = CommandLineDictionary.FromArguments(args);
        int order = Int32.Parse(d["order"]);
        int seed = Int32.Parse(d["seed"]);

&lt;FONT color=#008000&gt;        //
        //  Parameters
        //&lt;/FONT&gt;
        Parameter os = new Parameter("OS") { "Windows XP SP3", "Windows Vista SP1", "Windows 7", "Windows Server 2003 SP2", "Windows Server 2008 R2" };
        Parameter language = new Parameter("language") { "ARA", "CHS", "CHT", "CSY", "DAN", "DEU", "ELL", "ENG", "ESN", "FIN", "FRA", "HEB", "HUN", "ITA", "JPN", "KOR", "NLD", "NOR", "PLK", "PSE", "PTB", "PTG", "RUS", "SVE", "TRK" };
        Parameter sysLocale = new Parameter("sysLocale") { "SameAsOsLanguage", "TRK" };
        Parameter flavor  = new Parameter("flavor")     { "fre", "chk" };
        Parameter platform = new Parameter("platform")  { "x86", "x64", "x64wow" };
        Parameter ieVersion = new Parameter("ieVersion") { "osDefault", "ie7", "ie8" };
        Parameter highDpi = new Parameter("hiDpi") { "yes", "no" };
        Parameter theme = new Parameter("theme") { "Classic", "Luna", "Royale", "Classic High Contrast", "Aero Basic", "Aero Glass" };
        Parameter sxs = new Parameter("sxs") 
        {
            "3.5 SP1 + 4 (3.5 tests)",
            "3.5 SP1 + 4 (4 tests)",
            "3.5 SP1 + 4 - 4 (3.5 tests)",
            "4 + Mock 4.5 (4 tests)",
            "4 + Mock 5 (4 tests)",
            "4 + 3.5 SP1 (4 tests)",
            "4 + 3.5 SP1 (3.5 tests)",
            "4 + 3.5 SP1 - 4 (3.5 tests)",
            "4 (4 tests)",
        };
        List&amp;lt;Parameter&amp;gt;
&lt;PARAMETER&gt; parameters = new List&amp;lt;Parameter&amp;gt;
&lt;PARAMETER&gt; { os, language, sysLocale, flavor, platform, ieVersion, highDpi, theme, sxs };


&lt;FONT color=#008000&gt;        //
        //  Constraints
        //&lt;/FONT&gt;
        List&amp;lt;Constraint&amp;gt;&lt;CONSTRAINT&gt; constraints = new List&amp;lt;Constraint&amp;gt;&lt;CONSTRAINT&gt;
        {
            new IfThenConstraint
            {
                If = os.Equal("Windows XP SP3").Or(os.Equal("Windows Server 2003 SP2")),
                Then = theme.NotEqual("Aero Basic")
            },
            new IfThenConstraint
            {
                If = os.Equal("Windows XP SP3").Or(os.Equal("Windows Server 2003 SP2")),
                Then = theme.NotEqual("Aero Glass")
            },
            new IfThenConstraint
            {
                If = os.Equal("Windows 7").Or(os.Equal("Windows Server 2008 R2")),
                Then = theme.NotEqual("Luna")
            }
        };


&lt;FONT color=#008000&gt;        //
        //  Model
        //&lt;/FONT&gt;
        Model m = new Model(parameters, constraints);

        uint i = 0;
        foreach (Variation v in m.GenerateVariations(order, seed))
        {
            Console.WriteLine(
                "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}", 
                i,
                v[os.Name],
                v[language.Name],
                v[sysLocale.Name],
                v[flavor.Name],
                v[platform.Name],
                v[ieVersion.Name],
                v[highDpi.Name],
                v[theme.Name],
                v[sxs.Name]
                );
            i++;
        }
    }
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H2&gt;&amp;nbsp;&lt;/H2&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;Pairwise variation generation is an important tool in your toolbox as a test author. TestApi provides a simple facility for combinatorial variation generation. We will of course be evolving this facility, but do let us know if you have specific scenarios or requirements you'd like to see supported.&lt;/P&gt;
&lt;SCRIPT type=text/javascript&gt;
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
&lt;/SCRIPT&gt;

&lt;SCRIPT type=text/javascript&gt;
try {
var pageTracker = _gat._getTracker("UA-11119465-1");
pageTracker._trackPageview();
} catch(err) {}&lt;/SCRIPT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9884004" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>TestApi v0.3 Released!</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/07/23/9847064.aspx</link><pubDate>Fri, 24 Jul 2009 04:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9847064</guid><dc:creator>ivom</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9847064.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9847064</wfw:commentRss><description>&lt;p&gt;I am happy to announce that we have just released the third preliminary version of TestApi -- the testing API library. This version introduces some fairly significant changes and new features:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;New name spaces (under Microsoft.Test) and new binary names; &lt;br&gt;&lt;/li&gt;&lt;li&gt;New source code organization;&lt;br&gt;&lt;/li&gt;&lt;li&gt;A fairly comprehensive acceptance tests suite (using xUnit);&lt;/li&gt;&lt;li&gt;Fault Injection APIs for managed code (using CLR profiler technology);&lt;/li&gt;&lt;li&gt;Combinatorial Variation Generation API (using the PICT algorithm);&lt;/li&gt;&lt;li&gt;A redesigned Application Control API;&lt;/li&gt;&lt;li&gt;Updates to the Visual Verification API;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Updated samples and documentation; new conceptual documents;&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;We will be blogging in detail about some of the features in v0.3 in the coming weeks.&lt;br&gt;&lt;p&gt;TestApi is a policy-free API library, delivering Microsoft testing technology in an easy to use package. It can be used from within any tool (VSTS, NUnit, xUnit, etc.) or environment to automate the testing for desktop and in-browse applications on Windows. &lt;/p&gt;&lt;p&gt;TestApi v0.3 is available on &lt;a href="http://testapi.codeplex.com" target="_blank" mce_href="http://testapi.codeplex.com"&gt;http://testapi.codeplex.com&lt;/a&gt;. Thanks for all your feedback. &lt;a href="mailto:testapi@microsoft.com?subject=Feedback%20on%20TestApi%20v0.3" mce_href="mailto:testapi@microsoft.com?subject=Feedback on TestApi v0.3"&gt;Keep it coming!&lt;/a&gt; :)&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9847064" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Win32/default.aspx">Win32</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>WPF Application Quality Guide v0.5 Released!</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/04/28/9574933.aspx</link><pubDate>Wed, 29 Apr 2009 06:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9574933</guid><dc:creator>ivom</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9574933.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9574933</wfw:commentRss><description>&lt;p&gt;I am happy to announce that we have released CTP 5 of the “WPF Application Quality Guide” – our single-stop document for WPF application and component developers and testers.&lt;/p&gt;  &lt;p&gt;CTP 5 comes with the following new and updated content:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;New content:      &lt;ul&gt;       &lt;li&gt;“Considerations for WPF Browser Applications” &lt;/li&gt;        &lt;li&gt;“Integration and Scenario Testing” &lt;/li&gt;        &lt;li&gt;“XAML Editing Tools and Visual Studio Add-ins” &lt;/li&gt;        &lt;li&gt;“Building a WPF Application Test Suite by Using VSTS, NUnit, or xUnit”          &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Updated content:      &lt;ul&gt;       &lt;li&gt;Reading roadmap &lt;/li&gt;        &lt;li&gt;“Performance and Scalability Testing” &lt;/li&gt;        &lt;li&gt;“TestApi” &lt;/li&gt;        &lt;li&gt;“Debugging Tools” &lt;/li&gt;        &lt;li&gt;“Performance Profiling Tools” &lt;/li&gt;        &lt;li&gt;“WPF Application Design and Development Tools” &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The Guide is available &lt;a href="http://windowsclient.net/wpf/white-papers/wpf-app-quality-guide.aspx"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt; and &lt;a href="http://download.microsoft.com/download/E/7/C/E7C9F85B-2DB5-4B96-B74D-9DAC42E754B0/WPF_Application_Quality_Guide_CTP5.doc"&gt;here as a DOC file&lt;/a&gt;. Big kudos to Anne Gao on our team, who has been PM-ing all releases of the guide to date.&lt;/p&gt;  &lt;p align="center"&gt;***&lt;/p&gt;  &lt;p&gt;Those of you who have been following the Guide have seen it evolve from its first CTP (&lt;a href="http://download.microsoft.com/download/7/7/0/770a52ec-75cb-4b81-b061-ef8873728612/WPF_Application_Quality_Guide_-_CTP1.doc"&gt;link&lt;/a&gt;) of 20 or so pages to its present size of more than 80 pages. &lt;/p&gt;  &lt;p&gt;Any 80-page document is tricky to grok, so we have been thinking of reorganizing the content and potentially splitting the content into two documents – one on client application development and testing fundamentals and one on WPF specifics. We prefer to do any edits based on user feedback, so please let us know of the current organization and content of the document and share your ideas on how we could improve both.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9574933" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/XAML/default.aspx">XAML</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>TestApi v.0.2 Released!</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/04/24/9566644.aspx</link><pubDate>Fri, 24 Apr 2009 15:53:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9566644</guid><dc:creator>ivom</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9566644.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9566644</wfw:commentRss><description>&lt;p&gt;I am excited to announce that we have just released the second preliminary version of &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; – the testing API library – on &lt;a href="http://codeplex.com/testapi"&gt;&lt;strong&gt;http://codeplex.com/testapi&lt;/strong&gt;&lt;/a&gt;! &lt;/p&gt;  &lt;p&gt;The v.0.2 package includes the following additions and modifications:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Improved command-line parsing APIs &lt;/li&gt;    &lt;li&gt;Improved visual verification APIs      &lt;ul&gt;       &lt;li&gt;A new tolerance map visual verifier in SnapshotToleranceMapVerifier &lt;/li&gt;        &lt;li&gt;New operations on snapshot (And and Or) allowing you to mask &lt;/li&gt;        &lt;li&gt;A new Snapshot.FromWindow(...) constructor with ability to include and exclude the window chrome in snapshots. &lt;/li&gt;        &lt;li&gt;Improved visual verification internals &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;New application control APIs, enabling in-proc and out-of-proc automation of client applications &lt;/li&gt;    &lt;li&gt;Expanded conceptual documentation &lt;/li&gt;    &lt;li&gt;CHM API documents (in addition to the HTML documents) &lt;/li&gt;    &lt;li&gt;Addition of NUnit and xUnit usage samples (for all of the non-VS crowd out there) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Check out the package and let us know of any feedback.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9566644" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Win32/default.aspx">Win32</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>Introduction to TestApi – Part 2: Command-Line Parsing APIs</title><link>http://blogs.msdn.com/ivo_manolov/archive/2008/12/17/9230331.aspx</link><pubDate>Thu, 18 Dec 2008 01:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9230331</guid><dc:creator>ivom</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9230331.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9230331</wfw:commentRss><description>&lt;p&gt;Command-line parsers remind me of linked lists in C++: everybody has written several at various points in their careers. While everybody should write each of those at least once, I doubt that many people out there are particularly excited about writing and re-writing fundamental data structures on a regular basis – it gets old very quickly. Not to mention that doing so is error-prone and decreases the maintainability of a world that’s already hard to maintain.&lt;/p&gt;  &lt;p&gt;That’s why modern-day frameworks such as .NET provide standard implementations of the common data structures. And that’s why &lt;a href="http://codeplex.com/testapi" target="_blank"&gt;&lt;strong&gt;TestApi&lt;/strong&gt;&lt;/a&gt; provides a reusable command-line parsing APIs via the &lt;strong&gt;CommandLineDictionary&lt;/strong&gt; and &lt;strong&gt;CommandLineParser&lt;/strong&gt; classes, the latter being a type-safe layer on top of the former. Obviously, these are not test APIs per se – they are general utility APIs that happen to be more often used when writing tests.&lt;/p&gt;  &lt;p&gt;A few quick examples follow. &lt;/p&gt;  &lt;h2&gt;Simple Command-Line Parsing&lt;/h2&gt;  &lt;p&gt;As seen from the first example below, extracting command-line parameters that are primitives is easy. Primitive command-line parameters are either boolean (e.g. the “verbose” flag below), or a key-value pair, that one can extract with the indexer of the &lt;strong&gt;CommandLineDictionary&lt;/strong&gt; instance (see the “testId” key below), just as one would expect from a Dictionary.&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;pre&gt;&lt;font color="#008000"&gt;// 
// EXAMPLE #1: Parsing a command-line such as &amp;quot;RunTests.exe /verbose /testId=123&amp;quot;
// 
&lt;/font&gt;
using System;
using Microsoft.Test;

public class Program 
{ 
    public static void Main(string[] args) 
    { 
        CommandLineDictionary d = new CommandLineDictionary(args);

        bool verbose = &lt;font style="background-color: yellow"&gt;d.ContainsKey(&amp;quot;verbose&amp;quot;)&lt;/font&gt;;
        int testId = Int32.Parse(&lt;font style="background-color: yellow"&gt;d[&amp;quot;testId&amp;quot;]&lt;/font&gt;);
                
&lt;font color="#008000"&gt;        // use the parsed command-line parameters&lt;/font&gt;
    }
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;By default flags/keys are indicated with the forward slash (“/”) character and values are indicated with the equals character (“=”), but the user can override that upon initialization of of the CommandLineDictionary object:&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;pre&gt;&lt;font color="#008000"&gt;// 
// EXAMPLE #1b: Parsing a command-line such as &amp;quot;RunTests.exe –verbose –testId:123&amp;quot;
// 
&lt;/font&gt;
...
        CommandLineDictionary d = new CommandLineDictionary(args, &lt;font style="background-color: yellow"&gt;'-', ':'&lt;/font&gt;);
...&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Finally, you one can use the &lt;strong&gt;ToString&lt;/strong&gt; method to get a string representation of the command-line arguments.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Command-Line Argument Structures&lt;/h2&gt;

&lt;p&gt;Another common pattern when dealing with command-line arguments is populating a structure which contains all parsed arguments. The &lt;strong&gt;CommandLineParser&lt;/strong&gt; class makes this easy:&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;pre&gt;&lt;font color="#008000"&gt;// EXAMPLE #2:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly typed arguments are populated&lt;/font&gt;
public class CommandLineArguments
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }
}

CommandLineArguments a = new CommandLineArguments();
&lt;font style="background-color: yellow"&gt;CommandLineParser.ParseArguments(a, args);&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Type-Safe Commands&lt;/h2&gt;

&lt;p&gt;A third common approach is forming strongly-typed commands from the command-line parameters. This is common for cases when the command-line looks as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;some-exe&amp;#160; COMMAND&amp;#160; parameters-to-the-command&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The parsing in this case is a little bit more involved:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create one class for every supported command, which derives from the &lt;strong&gt;Command&lt;/strong&gt; abstract base class and implements an expected &lt;strong&gt;Execute&lt;/strong&gt; method. &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;Pass an expected command along with the command-line arguments to &lt;strong&gt;CommandLineParser.ParseCommand&lt;/strong&gt; – the method will return a&amp;#160; strongly-typed Command instance that can be Execute()-d.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&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;pre&gt;&lt;font color="#008000"&gt;// EXAMPLE #3:
// Sample for parsing the following command-line:
// Test.exe &lt;font style="background-color: yellow"&gt;run&lt;/font&gt; /runId=10 /verbose 
// In this particular case we have an actual command on the command-line (“run”), 
// which we want to effectively de-serialize and execute.&lt;/font&gt;
public class RunCommand : Command
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }

   public override void Execute()
   {
      &lt;font color="#008000"&gt;// Implement your &amp;quot;run&amp;quot; execution logic here.&lt;/font&gt;
   }
}

&lt;font style="background-color: yellow"&gt;Command c = new RunCommand();
CommandLineParser.ParseArguments(c, args); 
c.Execute();&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Besides the parsing logic, CommandLineParser provides a few additional helper methods. One of them is &lt;strong&gt;CommandLineParser.PrintCommandUsage&lt;/strong&gt;, which prints the usage for specific commands (or all supported commands) to the console.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;The command-line parsing APIs released with &lt;strong&gt;&lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; &lt;/strong&gt;provide a simple and “layered” access to the command-line. Strictly speaking these APIs are not test APIs, but have nevertheless been included in &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; as tests often have a need of parsing parameters on the command-line. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9230331" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Win32/default.aspx">Win32</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item><item><title>Introduction to TestApi – Part 1: Input Injection APIs</title><link>http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx</link><pubDate>Tue, 16 Dec 2008 06:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9223397</guid><dc:creator>ivom</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9223397.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9223397</wfw:commentRss><description>&lt;p&gt;I am starting a series of posts introducing some of the facilities available in &lt;a href="http://codeplex.com/testapi" target="_blank"&gt;&lt;strong&gt;TestApi 0.1&lt;/strong&gt;&lt;/a&gt;, a test and utility API library, which we recently released on CodePlex. Most of this content is already available in the documentation provided with the library. &lt;/p&gt;  &lt;p&gt;The first post is on input injection – a fairly common activity in UI testing.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;General Notes&lt;/h2&gt;  &lt;p&gt;Input injection is the act of simulating user input. In general, there are several ways to simulate user input, in the following progressively increasing levels of realism:&lt;/p&gt;  &lt;ol type="A"&gt;   &lt;li&gt;&lt;b&gt;Direct method invocation&lt;/b&gt;: A test programmatically triggers events by directly calling methods on the target UI element. For example, a test can call the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.buttonbase.ispressed.aspx"&gt;Button.IsPressed&lt;/a&gt; method to simulate pressing a WPF button. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Invocation using an accessibility interface (UIA, MSAA, etc.)&lt;/b&gt;: A test programmatically triggers events by calling methods on an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.aspx" target="_blank"&gt;AutomationElement&lt;/a&gt; instance that represents the target UI element. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Simulation using low-level input&lt;/strong&gt;: A test simulates input by using low-level input facilities provided by the host operating system. Examples of such facilities on Windows are the &lt;a href="http://msdn.microsoft.com/en-us/library/ms646310.aspx"&gt;SendInput Win32 API&lt;/a&gt; and the &lt;a href="http://msdn.microsoft.com/en-us/library/ms645536(VS.85).aspx"&gt;Raw Input Win32 API&lt;/a&gt;, which inject input directly into the OS input stream. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Simulation using a device driver&lt;/strong&gt;: A test uses a device driver to simulate input at the device-driver level. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Simulation using a robot&lt;/strong&gt;: A test controls a robot to simulate direct human interaction with an input device (for example, pressing keys on a keyboard). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Technique A is framework-specific; what works for WPF does not work for Windows Forms and vice versa. Technique B is less framework-specific than A, but still has limitations, because some frameworks differ in their implementations of the required accessibility interfaces. Techniques C and D are OS-specific. Technique D is significantly more difficult to implement and deploy than C, without a corresponding increase in its level of realism. Technique E is universal, albeit much slower and much more expensive than the other options.&lt;/p&gt;  &lt;p&gt;The TestApi library provides facilities both for B (through the &lt;b&gt;AutomationUtilities&lt;/b&gt; class) and for C (through the &lt;b&gt;Mouse&lt;/b&gt; and &lt;b&gt;Keyboard&lt;/b&gt; classes), which are the most generally useful techniques of input simulation.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Examples&lt;/h2&gt;  &lt;p&gt;The &lt;b&gt;AutomationUtilities&lt;/b&gt; class provides wrappers for common UIA operations, such as discovery of UI elements. The first example below demonstrates how to discover and click a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.button.aspx"&gt;WPF Button&lt;/a&gt; in a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.window.aspx"&gt;WPF Window&lt;/a&gt;, by using the &lt;strong&gt;AutomationUtilities&lt;/strong&gt; class and the &lt;strong&gt;Mouse&lt;/strong&gt; class.&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;pre&gt;&lt;font color="#008000"&gt;//
// EXAMPLE #1
// This code below discovers and clicks the Close button in an About dialog box, thus
// dismissing the About dialog box.
//&lt;/font&gt;

string aboutDialogName = “About”;
string closeButtonName = “Close”;

AutomationElementCollection aboutDialogs = AutomationUtilities.FindElementsByName(
    AutomationElement.RootElement,
    aboutDialogName);

AutomationElementCollection closeButtons = AutomationUtilities.FindElementsByName(
    aboutDialogs[0],
    closeButtonName);

&lt;font color="#008000"&gt;//
// You can either invoke the discovered control, through its invoke pattern...
//&lt;/font&gt;

InvokePattern p = 
    closeButtons[0].GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
p.Invoke();

&lt;font color="#008000"&gt;//
// ... or you can handle the Mouse directly and click on the control.
//&lt;/font&gt;

Mouse.MoveTo(closeButton.GetClickablePoint());
Mouse.Click();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The second example below demonstrates how to discover a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.textbox.aspx" target="_blank"&gt;TextBox&lt;/a&gt; instance and type in it, using the &lt;strong&gt;Mouse&lt;/strong&gt; and &lt;strong&gt;Keyboard&lt;/strong&gt; classes as wrappers of common mouse and keyboard operations:&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;pre&gt;&lt;font color="#008000"&gt;//
// EXAMPLE #2
// Discover the location of a TextBox with a given name.
//&lt;/font&gt;

string textboxName = “ssnInputField”;

AutomationElement textBox = AutomationUtilities.FindElementsByName(
    AutomationElement.RootElement,
    textboxName)[0];

Point textboxLocation = textbox.GetClickablePoint();

&lt;font color="#008000"&gt;//
// Move the mouse to the textbox, click, then type something
//&lt;/font&gt;

Mouse.MoveTo(textboxLocation);
Mouse.Click();

Keyboard.Type(“Hello world. ”);
Keyboard.Press(Key.Shift);
Keyboard.Type(“hello, capitalized world.”);
Keyboard.Release(Key.Shift);&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Mouse&lt;/strong&gt; and &lt;strong&gt;Keyboard&lt;/strong&gt; classes in the TestApi library can be used for automating of any application, running on Windows. The classes are completely policy- and context-free – their usage is not dependent on a specific test framework or on a specific test workflow. TestApi provides full source code and XML documentation for these classes, so you can either integrate them in your own projects or reference the pre-built DLLs.&lt;/p&gt;

&lt;p&gt;Note that, even though Mouse, Keyboard and AutomationUtilities make the life of the test automation developer quite a bit easier, UI testing is tricky and should be avoided whenever possible. It’s always preferable to design your application as a multi-tier application, with a “thin” UI layer, so that you can bypass the UI in most of your tests.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9223397" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Testing/default.aspx">Software Testing</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/Software+Test+Automation/default.aspx">Software Test Automation</category></item></channel></rss>