<?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 : TestApi</title><link>http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx</link><description>Tags: TestApi</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>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 3: Visual Verification APIs</title><link>http://blogs.msdn.com/ivo_manolov/archive/2009/04/20/9557563.aspx</link><pubDate>Tue, 21 Apr 2009 01:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9557563</guid><dc:creator>ivom</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9557563.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9557563</wfw:commentRss><description>&lt;p&gt;Visual Verification (VV) is the act of verifying that your application or component is displayed correctly on screen. The &lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; library provides a set of VV APIs. This post discusses these APIs.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Avoid It If You Can&lt;/h2&gt;  &lt;p&gt;First and foremost, I want to emphasize that &lt;strong&gt;visual verification is a test technique that should be used with caution&lt;/strong&gt;. It is difficult to do correctly and any extensive use typically results in hard-to-maintain test codebases. Here are a few things to consider before you embark on VV test development:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The UI of an application tends to change a lot during development. If you use visual verification extensively, you may end up in a situation where you have to update a large number of visual verification tests on a daily basis, which is a waste of effort. &lt;/li&gt;    &lt;li&gt;There are small differences in rendering between different video cards on different versions of the OS and of .NET. These differences are particularly pronounced in font rendering. &lt;/li&gt;    &lt;li&gt;Before employing any form of UI verification, one should always review the underlying application architecture. Extensive need for UI testing is typically indicative of poorly architected systems, lacking proper view-model separation, so it’s almost always better to invest in proper system architecture than in extensive UI testing. &lt;/li&gt;    &lt;li&gt;Whenever possible, attempt to do analytical visual verification i.e. one that does not employ the use of master images. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The WPF test team has gone through several iterations of cleaning up and retiring unnecessary visual verification tests in an attempt to speed up and stabilize our test suite.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;General Concepts&lt;/h2&gt;  &lt;p&gt;The core VV terminology is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Snapshot&lt;/b&gt;: A pixel buffer used for representing and evaluating screen image data. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Verifier&lt;/b&gt;: An oracle object which determines whether a snapshot passes against specified inputs. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Actual&lt;/b&gt;: The snapshot being evaluated. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Master&lt;/b&gt;: The reference data (image) which is used to evaluate the actual snapshot. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Tolerance&lt;/b&gt;:&lt;b&gt; &lt;/b&gt;The accepted bounding range based on which the actual snapshot will be accepted as valid. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The general VV workflow is:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Capture some screen content. &lt;/li&gt;    &lt;li&gt;Generate an expected snapshot (e.g. load a master image from disk, etc.) &lt;/li&gt;    &lt;li&gt;Compare the actual snapshot to the expected snapshot and generate the difference (diff) snapshot. &lt;/li&gt;    &lt;li&gt;Verify the diff using a verifier. &lt;/li&gt;    &lt;li&gt;Report test result. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;TestApi Visual Verification Technology&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://codeplex.com/testapi"&gt;TestApi&lt;/a&gt; provides the following VV technology:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Snapshot&lt;/strong&gt;: this class represents image pixels in a two-dimensional array for use in VV. Every element in the array represents a pixel in a given [row, column] of the image. A Snapshot object can be instantiated from a file (&lt;strong&gt;Snapshot.FromFile&lt;/strong&gt;), or captured from screen (&lt;strong&gt;Snapshot.FromWindow&lt;/strong&gt; and &lt;strong&gt;Snapshot.FromRectangle&lt;/strong&gt;). Snapshot also exposes image cropping (&lt;strong&gt;Snapshot.Crop&lt;/strong&gt;), resizing, diff-ing (&lt;strong&gt;Snapshot.CompareTo&lt;/strong&gt;) masking (&lt;strong&gt;Snapshot.And&lt;/strong&gt;) and merging operations (&lt;strong&gt;Snapshot.Or&lt;/strong&gt;) operations.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Verifiers:&lt;/strong&gt; the library provides a set of verifiers that can be used to verify a (diff) snapshot. &lt;strong&gt;SnapshotColorVerifier&lt;/strong&gt; reports passing if       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Various utilities&lt;/strong&gt;: example of these are the Histogram class, providing basic functionality for handling image histograms &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Examples&lt;/h2&gt;  &lt;h3&gt;SnapshotColorVerifier&lt;/h3&gt;  &lt;p&gt;With these prolegomena out of the way, let’s look at some code. The first example below demonstrates master visual verification using a basic color verifier, which ensures that the difference between the master snapshot and the actual snapshot is within a defined tolerance:&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;// 1. Capture the actual pixels from a given window&lt;/font&gt;
Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100));

&lt;font color="#008000"&gt;// 2. Load the reference/master data from a previously saved file&lt;/font&gt;
Snapshot expected = Snapshot.FromFile(&amp;quot;Expected.png&amp;quot;));

&lt;font color="#008000"&gt;// 3. Compare the actual image with the master image
//    This operation creates a difference image. Any regions which are identical in 
//    the actual and master images appear as black. Areas with significant 
//    differences are shown in other colors.&lt;/font&gt;
Snapshot difference = actual.CompareTo(expected);

&lt;font color="#008000"&gt;// 4. Configure the snapshot verifier - It expects a black image with zero tolerances
&lt;/font&gt;SnapshotVerifier v = new SnapshotColorVerifier(Color.Black, new ColorDifference());

&lt;font color="#008000"&gt;// 5. Evaluate the difference image&lt;/font&gt;
if (v.Verify(difference) == VerificationResult.Fail)
{
    &lt;font color="#008000"&gt;// Log failure, and save the diff file for investigation&lt;/font&gt;
    actual.ToFile(&amp;quot;Actual.png&amp;quot;, ImageFormat.Png);
    difference.ToFile(&amp;quot;Difference.png&amp;quot;, ImageFormat.Png);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This approach works fine if you are evaluating&amp;#160; the correctness of an application logo or some other application art. You may find that you will need to increase the tolerance a bit to accommodate differences in GPU rendering, but in general the SnapshotColorVerifier provides all the functionality you need.&lt;/p&gt;

&lt;h3&gt;SnapshotHistogramVerifier&lt;/h3&gt;

&lt;p&gt;A somewhat more sophisticated approach involves using of image histograms (see &lt;a href="http://en.wikipedia.org/wiki/Image_histogram"&gt;this link&lt;/a&gt; for a good introduction to the subject). An image histogram is a histogram that represents the frequency of pixels with a certain brightness. One can define a histogram that represents his/her expectation of the “proximity of the match” between the actual and expected snapshots. &lt;/p&gt;

&lt;p&gt;For example, one can define a histogram semantically equivalent to the following statement:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;“When I compare the actual snapshot to the expected snapshot (both of 320 pixels), I expect no more than 30 pixels with color channel difference of 1, no more than 10 pixels with color channel difference of 2, and zero pixels with higher differences.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This histogram would look as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_6.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/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_thumb_2.png" width="446" height="334" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p align="center"&gt;&lt;strong&gt;Figure 1&lt;/strong&gt;&amp;#160; Image Histogram&lt;/p&gt;

&lt;p align="center"&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Such form of verification is done by using the &lt;strong&gt;SnapshotHistogramVerifier&lt;/strong&gt; and the &lt;strong&gt;Histogram&lt;/strong&gt; classes, as demonstrated in the sample 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;pre&gt;&lt;font color="#008000"&gt;// Take a snapshot, compare to the master image and generate a diff&lt;/font&gt;
Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100));
Snapshot expected = Snapshot.FromFile(&amp;quot;Expected.png&amp;quot;));
Snapshot difference = actual.CompareTo(expected);

&lt;font color="#008000"&gt;// Load the quality histogram from disk and use it to verify the diff&lt;/font&gt;
SnapshotVerifier v = new SnapshotHistogramVerifier(Histogram.FromFile(&amp;quot;ToleranceHistogram.xml&amp;quot;));

if (v.Verify(difference) == VerificationResult.Fail)
{
    &lt;font color="#008000"&gt;// Log failure, and save the actual and diff images for investigation&lt;/font&gt;
    actual.ToFile(&amp;quot;Actual.png&amp;quot;, ImageFormat.Png);
    difference.ToFile(&amp;quot;Difference.png&amp;quot;, ImageFormat.Png);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The histogram file is just a XML file with the following schema:&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;&amp;lt;histogram&amp;gt;
  &amp;lt;tolerance&amp;gt;
    &amp;lt;point x=&amp;quot;0&amp;quot; y=&amp;quot;0.87500&amp;quot; /&amp;gt;
    &amp;lt;point x=&amp;quot;1&amp;quot; y=&amp;quot;0.09375&amp;quot; /&amp;gt;
    &amp;lt;point x=&amp;quot;2&amp;quot; y=&amp;quot;0.03125&amp;quot; /&amp;gt;
    &amp;lt;point x=&amp;quot;3&amp;quot; y=&amp;quot;0&amp;quot; /&amp;gt;
    &amp;lt;point x=&amp;quot;4&amp;quot; y=&amp;quot;0&amp;quot; /&amp;gt;
    ...
    &amp;lt;point x=&amp;quot;254&amp;quot; y=&amp;quot;0&amp;quot; /&amp;gt;
    &amp;lt;point x=&amp;quot;255&amp;quot; y=&amp;quot;0&amp;quot; /&amp;gt;
  &amp;lt;/tolerance&amp;gt;
&amp;lt;/histogram&amp;gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This visual verification approach was pioneered in the WPF test organization about 6 years ago by Marc Cauchy and Pierre-Jean Reissman.&lt;/p&gt;

&lt;h3&gt;SnapshotToleranceMapVerifier&lt;/h3&gt;

&lt;p&gt;However, none of the two approaches above work particularly well for evaluation of a typical application window, containing controls, text, etc. Such windows tend to have regions that need different tolerance settings. For example, consider the application window below:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_8.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/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_thumb_3.png" width="520" height="342" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p align="center"&gt;&lt;strong&gt;Figure 2&lt;/strong&gt;&amp;#160; Sample Application Window&lt;/p&gt;

&lt;p&gt;If you try to perform master based visual verification, you will hit 2 issues:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The non-client area of the window (the window frame) will tend to be slightly different between different runs of the application. It will also depend on environment factors such as the desktop wall-paper. 
    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;Some regions of the client area of the window will also tend to exhibit significant variance between runs of the application. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Issue (1) is easy to resolve, using &lt;strong&gt;Snapshot.FromWindow(...)&lt;/strong&gt; and excluding the non-client area from the capture. Issue (2), however, is a bit more involved. Here are the expected, actual and diff snapshots of the client-area of the application.&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-expected_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="Master0-expected" border="0" alt="Master0-expected" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-expected_thumb.png" width="504" height="304" /&gt;&lt;/a&gt;&amp;#160;&lt;strong&gt;Figure 3a&lt;/strong&gt;&amp;#160; Expected Client-Area Snapshot&lt;/p&gt;

&lt;p align="center"&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-actual_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="Master0-actual" border="0" alt="Master0-actual" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-actual_thumb.png" width="504" height="304" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="center"&gt;&lt;strong&gt;Figure 3b&lt;/strong&gt;&amp;#160; Actual Client-Area Snapshot&lt;/p&gt;

&lt;p align="center"&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-difference_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="Master0-difference" border="0" alt="Master0-difference" src="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/Master0-difference_thumb.png" width="504" height="304" /&gt;&lt;/a&gt;&amp;#160;&lt;strong&gt;Figure 3c&lt;/strong&gt;&amp;#160; Difference Snapshot&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/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/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/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_thumb.png" width="504" height="304" /&gt;&lt;/a&gt;&lt;strong&gt; Figure 3d&lt;/strong&gt;&amp;#160; Difference Snapshot – Completely Black Pixels Are Replaced With Pink&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The differences between the expected snapshot and the actual snapshot are difficult to see on Figure 3c, so on Figure 3d I have replaced purely black pixels with pink.&lt;/p&gt;

&lt;p&gt;It is not surprising that most of the variation occurs around the text regions in the application window (ClearType renders differently on different machines).&amp;#160; So it may make sense to increase the tolerance (or completely mask away) those regions, providing of course we are not specifically interested in their rendering. &lt;/p&gt;

&lt;p&gt;In order to achieve that, we use the &lt;strong&gt;SnapshotToleranceMapVerifier&lt;/strong&gt; class. Here’s an example:&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;// Take a snapshot, compare to the master image and generate a diff&lt;/font&gt;
Snapshot actual = Snapshot.FromWindow(hwndOfYourWindow, );
Snapshot expected = Snapshot.FromFile(&amp;quot;Expected.png&amp;quot;));
Snapshot difference = actual.CompareTo(expected);

&lt;font color="#008000"&gt;// Load the tolerance map. Then use it to verify the difference snapshot&lt;/font&gt;
Snapshot toleranceMap = Snapshot.FromFile(&amp;quot;ExpectedImageToleranceMap.png&amp;quot;);
SnapshotVerifier v = new SnapshotToleranceMapVerifier(toleranceMap);

if (v.Verify(difference) == VerificationResult.Fail)
{
    &lt;font color="#008000"&gt;// Log failure, and save the actual and diff images for investigation&lt;/font&gt;
    actual.ToFile(&amp;quot;Actual.png&amp;quot;, ImageFormat.Png);
    difference.ToFile(&amp;quot;Difference.png&amp;quot;, ImageFormat.Png);
}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The tolerance map that we use looks as follows:&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/ivo_manolov/WindowsLiveWriter/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_12.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/IntroductiontoTestApiPart3VisualVerifica_8E1B/image_thumb_4.png" width="504" height="304" /&gt;&lt;/a&gt;&lt;strong&gt; Figure 4&lt;/strong&gt;&amp;#160; Tolerance Map in “ExpectedImageToleranceMap.png”&lt;/p&gt;

&lt;p&gt;What appears pure black (0x00FFFFFF) is actually an off-black color (0x000A0A0A) to handle the small variations that appear as black dots on Figure 3d. Then we also have 4 regions with significantly higher tolerance to handle the variability of the text rendering.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;The visual verification API in TestApi provides a solid foundation for visual verification tests. As a general best practice, however, avoid visual verification as much as possible.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9557563" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ivo_manolov/archive/tags/TestApi/default.aspx">TestApi</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><item><title>TestApi v.0.1 Released</title><link>http://blogs.msdn.com/ivo_manolov/archive/2008/12/06/9181396.aspx</link><pubDate>Sat, 06 Dec 2008 21:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9181396</guid><dc:creator>ivom</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ivo_manolov/comments/9181396.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ivo_manolov/commentrss.aspx?PostID=9181396</wfw:commentRss><description>&lt;P&gt;On Friday, we released the first preliminary version of an experimental&amp;nbsp;library with test APIs,&amp;nbsp;named ... TestApi :). With this library, we are sharing internal&amp;nbsp;Microsoft testing technology with the developer and tester community.&lt;/P&gt;
&lt;P&gt;We wanted to keep the first release small and contained, so that it can be easily grasped and critiqued, but complete enough to provide actual user value and to clearly demonstrate the direction of this effort.&lt;/P&gt;
&lt;P&gt;In addition to the binaries and the source code, we have provided full documentation (both MSDN-style API documents and conceptual documents) as well as a couple of VSTS samples to get you started.&lt;/P&gt;
&lt;P&gt;Check out the release on &lt;A href="http://codeplex.com/TestApi" mce_href="http://codeplex.com/TestApi"&gt;&lt;STRONG&gt;http://codeplex.com/TestApi&lt;/STRONG&gt;&lt;/A&gt; and let us know what you think.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9181396" 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></item></channel></rss>