[UPDATED] Adding Timers to Coded UI tests running in Load Tests


I have uploaded a sample App and Coded UI test project for the app with the below code in it. This sample also shows a couple of examples of how to wait for events and how to randomly pick values from screen items. Enjoy and please send feedback.

By default, Visual Studio does not expose timers for collecting times for individual steps inside Coded UI tests. However, you can use the following trick to capture step timers for Coded UI tests WHEN they are executed as part of a load test. If you are not interested in running the Coded UI test under load, then create the load test with the settings to only have a single user and a single iteration.

First, let me explain the code. Visual Studio Unit tests expose a ContextTimer that can be used when the unit test is executed as a part of a load test. In Visual Studio 2010 and earlier, you could also use this when running the unit test by itself. However, the product group removed that feature in 2012 and above. The workaround is to check to see if the unit test is running in the context of a load test, and if so, then use the timers. For a Coded UI test, create a new instance of the context in the UIMap class, set the timers appropriately, then pass in a reference to the context from the CodedUI TestMethod.

Step 1

Add a TestContext object to the Coded UI’s main UIMap.Designer.cs file at the root of the “UIIMap” class:

        // ----- ADDED BY GEOFFGR ----

        publicTestContext TestContext




                return testContextInstance;




                testContextInstance = value;



        privateTestContext testContextInstance;




Step 2

Add a BeginTimer prior to the call you want to measure. Add an EndTimer after the call. If the call is asynchronous, you also need to add an appropriate “ControlReady” event.

            if (TestContext.Properties.Contains("$LoadTestUserContext")) //running as load test



             //<CodedUI Call HERE>


            if (TestContext.Properties.Contains("$LoadTestUserContext")) //running as load test





Step 3

Add a line in the TestMethod to initialize the TestContext object you added in step 1.

    this.UIMap.TestContext = TestContext;




Step 4

Create a load test and set the appropriate properties to execute it only one time:







Comments (4)
  1. robert tonnessen says:

    You cannot debug your tests outside of a load test while the context timers are in place from visual studio 2012. The framework throws an exception.  In order to debug your tests either use a find and replace to comment out or instead replace the begin timer and end timer lines with calls to a method that in turn calls those methods.  This gives you a single place to comment out.

  2. geoffgr says:

    Thanks for the feedback. I will dig into this as I do not recall running into the issue. However, the idea of extending the Begin/End timer calls with a single method is nice. I will update my sample project and re-post it with that method.

  3. geoffgr says:

    Robert, I just tried this again on my system and I was able to debug the coded UI test directly in Visual Studio without any issues. I know that BeginTimer and EndTimer are not supported in Unit Tests, but with the code I add around it to check for a load test, that code never gets fired during the debug and does not appear to interrupt the testing. I am attaching a sample WPF application and Coded UI project for you (and others) to play with. If you can get some more specifics about the error you get, I will be happy to look at it.

  4. Charlesdwm says:

    This approach is working on my installation of VS2012, and allows me to have the timers in my unit test and to run it as a single user without putting it in a load test. Removing the functionality in VS 2012 was NOT the best decision by Microsoft, in my opinion. I have found some cases where a timer in unit tests still does not work in VS 2013, but then sometimes it will work in 2013. In any case, in VS 2012, "unit test timers" are consistently broken but the above line of code provides a workaround.

Comments are closed.

Skip to main content