2. “Hello, World” Extension for Coded UI Test

This is the second post in this series on the extensibility of Coded UI Test. If you have not read the first post on the Introduction to Coded UI Test Extensibility, please do so now to understand this post better. In this blog, we will walk-through the steps to create a “Hello, World” extension for Coded UI Test.

Write “Hello, World” extension

  1. Create a new C# Class Library project with name UITestHelloWorldPackage.
  2. Add reference to following two Coded UI Test assemblies using the “.NET” tab in the “Add Reference” dialog –
    • Microsoft.VisualStudio.TestTools.UITest.Common.dll
    • Microsoft.VisualStudio.TestTools.UITest.Extension.dll
  3. Rename the file Class1.cs (class Class1) to HelloWorldPackage.cs (class HelloWorldPackage).
  4. Open HelloWorldPackage.cs, delete the existing code and add the code given below –
 using System;using System.Diagnostics;using Microsoft.VisualStudio.TestTools.UITest.Common;using Microsoft.VisualStudio.TestTools.UITest.Extension;// Attribute to denote that this assembly has UITest extensions.[assembly: UITestExtensionPackageAttribute("HelloWorldPackage",           typeof(UITestHelloWorldPackage.HelloWorldPackage))]namespace UITestHelloWorldPackage{    internal class HelloWorldPackage : UITestExtensionPackage    {        public override object GetService(Type serviceType)        {            Trace.WriteLine("Hello, World");            return null;        }        public override void Dispose()        {        }        public override string PackageDescription        {            get { return "Sample Extension for Coded UI Test"; }        }        public override string PackageName        {            get { return "Hello World Extension"; }        }        public override string PackageVendor        {            get { return "Sample by Microsoft Corporation"; }        }        public override Version PackageVersion        {            get { return new Version(1, 0); }        }        public override Version VSVersion        {            get { return new Version(10, 0); }        }    }}

Build & Deploy the extension

Build and deploy the binaries to " %CommonProgramFiles%\Microsoft Shared\VSTT\10.0\UITestExtensionPackages" directory. To deploy, you use following commands –

  • md " %CommonProgramFiles%\Microsoft Shared\VSTT\10.0\UITestExtensionPackages"
  • For 32 bit - xcopy /y " %~dp0\bin\Debug\UITestHelloWorldPackage.* " " %CommonProgramFiles%\Microsoft Shared\VSTT\10.0\UITestExtensionPackages\*.* "
  • For 64 bit - xcopy /y " %~dp0\bin\Debug\UITestHelloWorldPackage.* " " %CommonProgramFiles (x86) %\Microsoft Shared\VSTT\10.0\UITestExtensionPackages\*.* "

Note – The above assumes you are building Debug build which is default in VS. Also, if you are using Windows Vista or higher, you will need to do above steps from CMD window with administrative privilege to access " %CommonProgramFiles% ".

For deploying, another alternative if for some reason the author does not want to copy to the predefined directory is to add following in registry –

  • Create “HKLM\Software\Microsoft\VisualStudio\10.0\TeamTest\UITest\UITestExtensionPackages” key.
  • Under this, create a key with your extension name like “HelloWorldPackage” here. Set the default value of this key to full path of the extension. For example, “C:\MyDir\MyExtension.dll”.

Verify the extension

At this point, you have created your first Coded UI Test extension that writes “Hello, World” in the trace file. We will take a look at the code more closely in a while but before that let us verify that the extension is getting loaded and working as expected. To do so, follow the steps below -

  1. Using the steps mentioned in this blog, enable logging for Coded UI Test.
  2. Launch new VS and create a new Coded UI Test.
  3. Record some steps and generate code. Close the Coded UI Test Builder.
  4. Go to " %temp%\UITestLogs\CodedUITestBuilder\LastRun" directory and view UITestLog.html. Among other entries, you will see “Hello, World” string here too.  The below picture shows the output.  Note - There could be multiple “Hello, World” string because the extension is called once for each extension point.

image

Understanding the extension code

Now that we have verified that the extension is working properly, let us understand the code by breaking into sections.

Adding UITestExtensionPackageAttribute assembly attribute
 [assembly: UITestExtensionPackageAttribute("HelloWorldPackage",           typeof(UITestHelloWorldPackage.HelloWorldPackage))]

The UITestExtensionPackageAttribute assembly level attribute informs the Coded UI Test tool that this assembly contains one or more extensions. The assembly attributes are metadata that can be read quickly without fully loading the assembly and this helps the tool in performance. Here the first parameter to the attribute is just any string identifier and the second parameter is the type that implements the UITestExtensionPackage class.

Implementing UITestExtensionPackage class

    internal classHelloWorldPackage : UITestExtensionPackage

All Coded UI Test extensions need to have an entry point as a class deriving from the UITestExtensionPackage class. Once the tool identifies an assembly as an extension using the attribute mentioned above, it creates the class implementing the UITestExtensionPackage abstract class and calls GetService() method on it to get the actual extension points.

The GetService() method
 public override object GetService(Type serviceType)

The GetService() method returns the appropriate service or the extension point as asked. For example, if this package is implementing UITechnologyManager extension point, then when GetService() is called with typeof(UITechnologyManager) , it should return the instance of class that implements this service or extension point. In the above example, we are not implementing any of the extension points and hence we are always returning null.

The Dispose() method
 public override void Dispose()

The Dispose() method, like elsewhere in .NET, is used to do any resource cleanup. For more info, refer MSDN on IDisposable.

Other properties of the class
 public override string PackageDescriptionpublic override string PackageNamepublic override string PackageVendorpublic override Version PackageVersionpublic override Version VSVersion

These properties are used in identifying the extension and provided information on the same to the user in case of error etc.

Debugging the extension

Debugging the extension is like debugging any other class library project – attach to the appropriate process and set breakpoints. The process during playback is QTAgent32.exe and during recording\assertion\code generation is CodedUITestBuilder.exe. Note that you have to launch the builder and then attach to it. Alternatively, you can use this trick to always attach to CodedUITestBuilder.exe as soon as it is launched or use Debugger.Break() API to break at appropriate point. Many a times, debugging extension issue for recording\playback scenario on the same machine could be tricky because while debugging you are changing machine states (like active window) which recording and playback are sensitive to. In such cases, Remote Debugging is better option.

The complete code for this walk-through is attached as UITestHelloWorldPackage.zip .

From “Hello, World”, move on to a more complete sample in the next blog.

UITestHelloWorldPackage.zip

Comments

  • Anonymous
    September 19, 2010
    is there any way to debug the extension program with breakpoint to check my extension logic?

  • Anonymous
    September 19, 2010
    Please refer the last section on debugging. Thanks

  • Anonymous
    May 01, 2011
    is there any way to access fpSpread control row and column values using coded UI?

  • Anonymous
    May 09, 2011
    I don't know what is fpSpread control.

  • Anonymous
    May 19, 2011
    Hi, how can i implement extensiblity for third party control, i could not see any samples or examples.

  • Anonymous
    May 19, 2011
    i mean how can we implement extensibility for third party windows control?

  • Anonymous
    May 23, 2011
    No, I don't have any more samples.

  • Anonymous
    December 19, 2011
    Hi Gautam Thanks for the excellent series of extensibility in Coded UI Tests! When I read this blog post I got curious about using the registry to reference extension assemblies. We are building extensions in order to test our system and the custom controls we built. One advantage is that this solution affects both MTM and CUIT’s when it comes to recording/playback. When it comes to package extensions, I would be glad to see a solution where I don’t have to push the assemblies to the tester’s machines for installations and for updates. So my question is: do you know if it is possible to use the registry setting described above to point out a drop folder on the network? Also, I haven’t been able to get the registry setting to work on my machine pointing out a local folder. Thanks /Michael

  • Anonymous
    January 05, 2012
    @Michael - Sorry for the delay in reply.  I need to understand this more and may be loop in more folks to help you out here.  I suggest you use the "Email Blog Author" link at the top right of this post to send me detail mail. Thanks.

  • Anonymous
    September 21, 2012
    Hi Gautam. I wanted to say I do not see the Hello, World showing as you indicate in my trace file.  What I do get is: W, 5268, 18, 2012/09/21, 11:11:57.333, 12316073092, CodedUITestBuilder.exe, AddEventHandler failed for element Name [2. “Hello, World” Extension for Coded UI Test - Gautam Goenka (MSFT) - Site Home - MSDN Blogs], ControlType [TabPage], NativeControlType [page tab], ClassName [Chrome_WidgetWin_1], RuntimeId [200066_0_[MSAA]Name='2. “Hello, World” Extension for Coded UI Test - Gautam Goenka (MSFT) - Site Home - MSDN Blogs' && ControlType='TabPage'] So I am not sure what I am doing wrong.   Can you help out?  Thanks

  • Anonymous
    October 29, 2012
    @Damon - It is difficult to say what is wrong.  Try the steps again to ensure you have not missed anything.