Chapter 24

Coded User Interface Testing

What's In This Chapter?

  • Understanding how you can use coded UI tests to create automated functional tests
  • Learning how to create a coded UI test from scratch, or from existing action recordings
  • Learning techniques for making coded UI tests more robust

Wrox.com Code Downloads for this Chapter

The wrox.com code downloads for this chapter are found at www.wrox.com/remtitle.cgi?isbn=1118314081 on the Download Code tab. The files are in the Chapter 24 download folder and individually named as shown throughout this chapter.

In Chapter 23, you learned about the support that Visual Studio 2012 has for manual testing. Manual tests are relatively cheap to author, which makes them well-suited for testing your application while it's undergoing regular changes. As the user interface (UI) undergoes churn (perhaps because of usability feedback, or additional features being implemented), it's easy to update manual test cases to reflect those changes. After all, a manual test is essentially just a textual list of steps.

The downside of manual tests is that, by definition, they require human intervention to execute and validate. As an application grows, it may become cost-prohibitive to run every manual test for every build you're testing. The desire is to use automated tests that can be run routinely to help ensure application integrity, without requiring ongoing human testing resources. Visual Studio 2012 enables you to create coded UI tests, which are designed for functional UI testing.

A coded UI test provides a mechanism to automatically execute and validate a test case. Unlike most other automated tests (such as unit tests), a coded UI test operates at the user-interface layer and “drives” the application in much the same manner as a human sitting in front of a mouse and keyboard would. You can program a coded UI test to validate elements of the UI at various points during the test to confirm that the application is behaving properly. For example, is the checkout total accurately reflected in the correct location on a form after adding a given number of items to the shopping cart?

You can author coded UI tests in C# or Visual Basic, and Visual Studio provides tools to help auto-generate much of this required code. Note that coded UI tests require that the application being tested was built using one of the supported technologies—for example, Windows Presentation Foundation (WPF), Windows Forms, HTML/AJAX, and so on. See the “Supported Technologies” section later in this chapter for more information.

In this chapter, you learn how to work with coded UI tests. You start by creating a simple coded UI test using the Coded UI Test Builder and adding some validation logic. Next, you parameterize this test to run multiple times using different sets of input data. Lastly, you discover how you can create coded UI tests using action recordings, which can be generated while running manual tests.

Creating Coded UI Tests Using the Coded UI Test Builder

One way of recording a coded UI test is to use the Coded UI Test Builder. By using the Test Builder, you can record a given path through an application, usually by emulating a scenario that you expect a user to perform. Along the way, you can add validation logic to ensure that the application is behaving correctly. The Test Builder is responsible for generating source code (in C# or Visual Basic) that represents the coded UI test. You can then customize this source code, such as to parameterize inputs and expected outputs for creating a data-driven test.

Setting up the Sample Application

The tutorial presented here utilizes a very simple WPF-based calculator. You can download this sample from this book's website at www.wrox.com. A version of the calculator written using Windows Forms is also available for you to try, although the source code and screenshots in this chapter match that of the WPF version.

Begin by opening the solution for the SimpleWPFCalculator application. Press F5 to launch the application. This is a very primitive application, but it serves as a good example for learning how to work with coded UI tests. To use the application, simply enter an integer into each textbox and click the buttons corresponding to each math operation to generate the respective results, as shown in Figure 24.1. (In this example, the Subtract button was clicked.)

Create a desktop shortcut for your application to make it easier to launch when you are creating your tests. From within Windows Explorer, browse to the project directory where you unzipped the sample application. Open the SimpleWPFCalculatorinDebug folder and right-click the SimpleWPFCalculator.exe file. Choose Create Shortcut and then drag the shortcut that is generated onto your computer's desktop. Confirm that double-clicking this shortcut launches the WPF calculator application.

Create a Test Project

Next, you need a test project in which to house your coded UI tests. Click File ⇒ New ⇒ Project, which displays the New Project dialog shown in Figure 24.2. Select Visual C# ⇒ Test ⇒ Coded UI Test Project. Name your project CodedUITestProject and click OK when finished.


Note
You may also choose Visual Basic as the language for your test project, but the sample code in this chapter shows a C# test project.

Your first coded UI test, CodedUITest1.cs, is created as part of your new project. The dialog shown in Figure 24.3 displays, providing you with options for generating your test.

This first option, Record Actions, Edit UI Map or Add Assertions, launches the Coded UI Test Builder. This enables you to record a coded UI test from scratch by navigating through the application in the same manner that a user might. In the “Creating Coded UI Tests Using Action Recordings” section, later this chapter, you find out how to convert existing manual test cases into coded UI tests by selecting the second option in this dialog.

For now, choose the first option and click OK. Visual Studio now minimizes to make room for you to begin recording your test.

Coded UI Test Builder

The Coded UI Test Builder now appears in the lower right of your screen, as shown in Figure 24.4. The Test Builder is, as the name implies, a tool that can help you construct your coded UI tests. It is responsible for both recording actions you perform (for example, clicking buttons, typing text, and so on), and for identifying controls and their properties that you want to validate.

Minimize any open applications so that you can clearly see your desktop and the shortcut to the WPF calculator application that you created earlier. However, don't launch the shortcut yet. Click the Record button (the circle inside of a square on the left end of the toolbar) of the Test Builder when you are ready to begin recording your test.

The Test Builder should now resemble Figure 24.5, which indicates that it is recording your actions. At any time, you can click Pause (the leftmost button) to instruct Test Builder to stop recording your actions, and click the Record button again when you are ready to resume.


Note
When you begin recording, Test Builder captures any and all actions you perform, even if they aren't part of the application you are trying to test. For example, if you are recording a test and you respond to an instant message, or click the Start menu to launch an unrelated application, these actions are captured. This might result in unnecessary playback steps when executing your coded UI tests and could even cause your tests to fail unexpectedly. For this reason, you should take care to close unrelated applications prior to recording your tests so you can make clean recordings. You can also pause the Test Builder if you must perform unrelated actions during a test. Just be sure you do not interact with the application being tested while the Test Builder is paused. Doing so could cause the application you are testing to get into a state other than what it was in when you paused the Test Builder, and, hence, subsequent steps you record might fail on playback.

You are now ready to begin recording the coded UI test by using the application in the same manner you would expect a user to. Launch the WPF calculator application by double-clicking the desktop shortcut you created earlier. Type 20 in the first textbox, then type 10 in the second textbox, and click the Add button.

You can visually inspect the actions that the Test Builder has captured by clicking Show Recorded Steps (the second button from the left) of the Test Builder. The window shown in Figure 24.6 appears, showing you an easy-to-read list of the steps you have performed while recording your test. Note that you can pin this window if you'd like to have it remain visible while you are recording. You can also right-click and delete any unwanted actions that you may have recorded accidentally.

At this point in your test, you are ready to add some validation logic to confirm that the result of your addition operation is correct. But, before you add an assertion, you should convert the steps you have performed so far into source code. Do so by clicking Generate Code (the rightmost button) within the Test Builder.

The dialog shown in Figure 24.7 prompts you for the name of the method you want to create within your coded UI test. You should use descriptive method names to make it easier to understand your generated code. Type EnterDataAndClickAdd; optionally you can provide a description which will be added as a comment to the source code that you generate. Click Add and Generate when you are ready to resume building your coded UI test. The Test Builder converts your recorded steps into source code, which is added to your Visual Studio project files. You will inspect this code later.

You can now add assertion logic to validate the properties of one or more controls. The Test Builder enables you to easily select the control you want to validate. Do so by clicking and dragging the crosshair icon from the Test Builder onto the bottommost textbox of the calculator. As you hover over controls and windows of your desktop and applications, notice that they become highlighted to indicate which control you are selecting. After you have selected the bottommost textbox of the calculator, release your mouse button.

The properties for the textAnswer textbox you have selected are displayed as shown in Figure 24.8.

You can use the up/down/left/right arrows of this dialog to navigate through the control hierarchy. You don't need to do so for this test, but this is helpful for controls that are difficult to select using the crosshairs, or invisible controls (such as a panel that may be used a container for other controls).

For some controls, such as context menus, you may notice that they are difficult to select. For example, a context menu might disappear once you drag it over the control. In these cases, you can simply hover your mouse pointer over the control you are trying to capture, then press Ctrl+I. This will highlight the selected control and show its properties in the Coded UI Test Builder.

For this test, you want to confirm that the number 30 (the sum of 20 plus 10) is properly displayed in the textbox. In the list of properties for this control, you see that the Text property of the UITextAnswerEdit control in your UI Map currently has a value of 30. Highlight this row, then click Add an Assertion (the second button from the left on the toolbar). The dialog box in Figure 24.9 displays, enabling you to define the behavior of your assertion. Click the Comparator dropdown to examine your assertion choices. Accept the default value (AreEqual) for Comparator and the current value (30) for Comparison Value. You should also add a value for the message that is displayed if the assertion fails. This is very helpful when you are diagnosing failed tests later on, especially if you have many assertions in your tests. Click OK when finished. The Test Builder displays a message indicating that your assertion has been added.

You can examine all the controls that have been captured as part of your coded UI test by clicking Show UI Control Map (the leftmost button on the toolbar). The UI Control Map is built by the Test Builder. It contains information about all of the controls necessary to interact with and validate the application you are testing. Figure 24.10 shows the controls that you have added so far.

The Test Builder assigns names to your controls based on the type of control and its control name. For example, the textAnswer control is be named UITextAnswerEdit.


Note
If you don't see meaningful names for your controls, or you can't locate the controls at all, it might be due to one or more of the following factors. The first might be because the application you are testing was built using an unsupported technology, or a mixture of technologies (some of which are unsupported). For example, if you are testing a web application which has an embedded Flash object, you will be able to identify controls on the web page but not within the Flash object. See “Supported Technologies” later in this chapter for more information. If you are finding unique controls but the names are not meaningful (e.g., textbox1, button1, etc.) then this likely indicates that the developers building the application you are testing haven't taken the time to provide meaningful names to the controls. You should consider having a discussion with them to explain to them why it might be helpful to have consistent naming conventions for the controls within the application, which can in turn improve the readability and maintainability of the tests you are writing. Finally, if you are testing a web application, some controls might simply not have any names at all since you are not always required to name a control using HTML. This is another reason for your application developers to start assigning unique, meaningful names to the controls within your application.

The controls in the UI Control Map are organized hierarchically; for this application, notice that UIDemoCalculatorWPFWindow is a parent control of the rest of the controls in this application. You can click on any control in this tree to examine its properties. These properties, along with the relative location of a control within the control hierarchy, are used by your coded UI test to find the correct control to use during test playback.

Click Generate Code from within the Test Builder (the rightmost button) to codify the assertion you just added. The dialog shown in Figure 24.11 displays, prompting you to name the method that corresponds to your assertion. Name the method AssertAdd, optionally provide a meaningful comment, and click Add and Generate. The Test Builder now converts the assertion you defined into C# and inserts this into your test project.


Note
The dialog you encountered in Figure 24.9 may at first appear to be duplicative of the dialog you encountered in Figure 24.11. The difference is subtle, and one which will become clearer as you work with more coded UI tests. Essentially, Figure 24.11 asks you to define a method in your code which is responsible for validating all of the assertions you added earlier. In this example, you are only adding one assertion (to confirm that the textAnswer control has a text value equal to 30). But you could have added additional control properties to validate by repeating the process you went through with Figure 24.9. For example, you might have wanted to also validate that the textAnswer control has its ReadOnly value set to True.

Now, click the Record button (leftmost button) in the Test Builder again to resume recording your test case. Click the Subtract button in the calculator, and then click Generate Code (the rightmost button) in the Test Builder. Name this method ClickSubtract and click Add and Generate.

Now, add another assertion by following the same steps you followed earlier. After dragging the crosshair onto the bottommost textbox in the calculator, you see the expanded UI Control Map. The UITextAnswerEdit control should be highlighted. Select the Text property and add an assertion stating that this property should now be equal to 10. Click Generate Code and name the assertion AssertSubtract.

Repeat these steps for the multiplication and division functions. Name the methods for clicking those buttons ClickMultiply and ClickDivide, respectively. Name the corresponding assertions AssertMultiply and AssertDivide. When you are finished, close the Test Builder, which returns you to Visual Studio. You can always return to the Test Builder in the future by clicking Test ⇒ Generate Code for Coded UI Test.

Generated Code

From within Visual Studio, you can now examine the code that was generated by the Test Builder while you were recording your test actions and assertions. The CodedUITestMethod1() method within the CodedUITest1.cs file is the main execution harness for your test, and calls all of the action and assertion methods you defined earlier, as shown here:

[TestMethod]
public void CodedUITestMethod1()
{
 this.UIMap.EnterDataAndClickAdd();
 this.UIMap.AssertAdd();
 this.UIMap.ClickSubtract();
 this.UIMap.AssertSubtract();
 this.UIMap.ClickMultiply();
 this.UIMap.AssertMultiply();
 this.UIMap.ClickDivide();
 this.UIMap.AssertDivide();
}

To better understand what each underlying method is actually doing, you can examine the partial class file named UIMap.Designer.cs. Right-click the EnterDataAndClickAdd method call and select Go to Definition. This method is defined as follows (some comments have been removed in the following text):

public void EnterDataAndClickAdd()
{
 WpfEdit uITextInput1Edit = this.UIDemoCalculatorWPFWindow.UITextInput1Edit;
 WpfEdit uITextInput2Edit = this.UIDemoCalculatorWPFWindow.UITextInput2Edit;
 WpfButton uIAddButton = this.UIDemoCalculatorWPFWindow.UIAddButton;

 ApplicationUnderTest uIDemoCalculatorWPFWindow = ApplicationUnderTest.Launch(
this.EnterDataAndClickAddParams.UIDemoCalculatorWPFWindowExePath,
this.EnterDataAndClickAddParams.UIDemoCalculatorWPFWindowAlternateExePath);

 uITextInput1Edit.Text = this.EnterDataAndClickAddParams.UITextInput1EditText;

 uITextInput2Edit.Text = this.EnterDataAndClickAddParams.UITextInput2EditText;

 Mouse.Click(uIAddButton, new Point(50, 16));
}

This method is responsible for performing four distinct actions, as defined by the actions you recorded earlier. This method will first launch the application, then enter values into two textboxes, then click on the Add button. Notice, however, that the parameters for this method are defined elsewhere in this file. Scroll down to the class named EnterDataAndClickAddParams (not the virtual class of the same name):

public class EnterDataAndClickAddParams
{
 public string UIDemoCalculatorWPFWindowExePath = 
 "C:\Users\Brian\Desktop\ UITestingDemoApps\
SimpleWPFCalculator\bin\Debug\SimpleWPFCalculator.exe";

 public string UIDemoCalculatorWPFWindowAlternateExePath = "%USERPROFILE%\
DesktopUITestingDemoApps\SimpleWPFCalculator\bin\Debug\
SimpleWPFCalculator.exe";

 public string UITextInput1EditText = "20";

 public string UITextInput2EditText = "10";
}

The reason that the parameters are separated from the actual method doing the work is that this makes it easier to override the parameters with new values. This is very important when creating data-driven tests that will run multiple times, using different values each time. You do this later in this chapter.

Notice that there are two slightly different values defined to describe from where the application under test will be launched, UIDemoCalculatorWPFWindowExePath and UIDemoCalculatorWPFWindowAlternateExePath. Whenever possible, Visual Studio looks for ways to make your tests more robust so that they are less prone to accidental failure resulting from changes to your application or test environment. The actual values you have for your test vary, based on where you stored your application. But, for this example, notice that Visual Studio stored both the absolute path to the executable and the relative path based on the %USERPROFILE% environment variable. This makes your tests more fault-tolerant in the event that your executable changes locations later on.

Also, notice that the Test Builder interpreted your test actions as launching an application executable, instead of double-clicking that application's shortcut on your desktop. This is also a way of making your test more fault-tolerant. In the future, you might decide to delete or move the shortcut to the executable, but you are less likely to move the actual executable itself. Recording tests can be a relatively expensive investment, so Visual Studio uses tricks like this to make it less likely that you must re-record your tests later on.


Note
You should refrain from making changes directly to the UIMap.Designer.cs file. Because this is a designer-generated file, any changes you make here might be overwritten later on as you refine your test. Instead, Visual Studio provides a UI Map Editor that you learn about later in this chapter.

Notice also that in the EnterDataAndClickAdd() method there is a Mouse.Click call which passes a Point(X,Y) value as an argument. This sometimes confuses people who are new to coded UI tests because they assume that coded UI tests are driven by fixed X and Y coordinates. They further wonder whether or not resizing a form or moving controls later on will cause their tests to break. But in fact, coded UI tests use the properties of controls from your UI map to locate controls, not their X and Y coordinates.

The Point(X,Y) value is used by the Mouse.Click method to control the position within a control that a mouse click is made. For most controls (such as the WPF Button being used in this application) it doesn't matter where a click is registered—the end result is the same. There are only a few controls where the position of a click makes a difference. One such example is a SplitButton control, such as the one you click when you are going to shut down or sleep your Windows PC. But for most controls, this value does not affect your test. In most cases you can feel free to resize or move controls around your forms or web pages without worrying about breaking your tests.


Note
For a deeper explanation of how coded UI tests use search and filter properties to locate controls, see http://tinyurl.com/SearchAndFilter.

Running Your Test

You are now ready to run your test and confirm that everything was properly recorded. Do so by returning to the CodedUITest1.cs file and right-clicking anywhere within the CodedUITestMethod1() code block. Select Run Tests. Avoid using your mouse or keyboard while the test runs. If you have recorded your test properly, the calculator will launch, the values 20 and 10 are inserted into the textboxes, and each of the four operation buttons are exercised. When finished, the test results are displayed in the Test Explorer window (Test ⇒ Windows ⇒ Test Explorer) as shown in Figure 24.12.

Congratulations! You have now authored your first coded UI test. But what if you want to test values other than 20 and 10? One approach would be to author new tests, each with their own values. But this would be very time-consuming. A better solution is to create a data-driven test by binding the values for this test case to a database, or a CSV or XML file.

Creating a Data-Driven Test

The process of creating a data-driven coded UI test is very similar to that of creating a data-driven unit test. You can use a database, CSV file, or XML file to drive your coded UI tests with different values. For each row of data, your coded UI test are run once.

The sample application for this chapter includes an XML dataset named CalcData.xml. The contents of this file are as follows:

<?xml version="1.0" encoding="utf-8"?>
<DataContextData>
 <DataContextRow InputValue1 ="10"
 InputValue2 ="2"
 ExpectedAddAnswer ="12"
 ExpectedSubtractAnswer="8"
 ExpectedMultiplyAnswer="20"
 ExpectedDivideAnswer="5"/>
 <DataContextRow InputValue1 ="20"
 InputValue2 ="10"
 ExpectedAddAnswer ="30"
 ExpectedSubtractAnswer="10"
 ExpectedMultiplyAnswer="200"
 ExpectedDivideAnswer="2"/>
</DataContextData>

Start by adding the CalcData.xml file to your project. Right-click your CodedUITestProject from within Solution Explorer and select Add ⇒ Existing Item. You may need to change the file filter to show All Files (*.*). Browse to the CalcData.xml file and click Add to add it to your project.

Next, you need to make this file a deployment item. Change the properties for this file in Solution Explorer. Set Build Action to Content, and set Copy to Output Directory to Copy if Newer. This ensures that the XML file is available alongside the DLL for your test.

Next you need to add DataSource and DeploymentItem attributes to your coded UI test method. Change the [TestMethod] attribute preceding the CodedUITestMethod1() method to the following:

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\
CalcData.xml", "DataContextRow", DataAccessMethod.Sequential),
DeploymentItem("CalcData.xml"), TestMethod]

This line specifies the name and relative path of the file, the type of data source (such as CSV or XML), and how the rows of data should be accessed (Sequential or Random).


Note
Previous releases of Visual Studio featured a Data Source Wizard that simplified the process of creating the DataSource and DeploymentItem attributes. Unfortunately, this functionality was removed in Visual Studio 2012 when Microsoft overhauled the testing framework. Microsoft has indicated that it would like to re-implement this functionality in a future version of Visual Studio, or possibly as an update to Visual Studio 2012, but at the time of writing there are no specific roadmap details available for this functionality.
If you have access to an older version of Visual Studio, you might want to use it to generate DataSource and DeploymentItem definitions that you can learn from and apply to your testing projects in Visual Studio 2012. For more information on these and other attributes that you can use to configure and extend your tests, see http://aka.ms/UTNamespace.

You can now begin overriding the parameters that you recorded earlier by data-binding them to your XML data source. The architecture of coded UI tests makes it easy to do this from within one central location—the CodedUITest1.cs file. Modify the CodedUITest1 method by inserting the following highlighted lines.

this.UIMap.EnterDataAndClickAddParams.UITextInput1EditText =
TestContext.DataRow["InputValue1"].ToString();
this.UIMap.EnterDataAndClickAddParams.UITextInput2EditText =
TestContext.DataRow["InputValue2"].ToString();

this.UIMap.EnterDataAndClickAdd();
this.UIMap.AssertAddExpectedValues.UITextAnswerEditText =
TestContext.DataRow["ExpectedAddAnswer"].ToString();
this.UIMap.AssertAdd();

this.UIMap.ClickSubtract();
this.UIMap.AssertSubtractExpectedValues.UITextAnswerEditText =
TestContext.DataRow["ExpectedSubtractAnswer"].ToString();
this.UIMap.AssertSubtract();

this.UIMap.ClickMultiply();
this.UIMap.AssertMultiplyExpectedValues.UITextAnswerEditText =
TestContext.DataRow["ExpectedMultiplyAnswer"].ToString();
this.UIMap.AssertMultiply();

this.UIMap.ClickDivide();
this.UIMap.AssertDivideExpectedValues.UITextAnswerEditText =
TestContext.DataRow["ExpectedDivideAnswer"].ToString();
this.UIMap.AssertDivide();

The code you added now overrides the values from each of the respective ExpectedValues methods within the UIMap.Designer.cs file by data binding the values to the corresponding columns within your XML data source.

Run your test again by right-clicking within your test method and selecting Run Tests. Your coded UI test now executes twice—once for each row of the XML data source. When finished, the test results panel of the Test Explorer window should indicate that 3/3 tests have passed successfully. This includes each data row, as well as the overall test, as shown in Figure 24.13.

You can now maintain the CalcData.xml file within your test project to add new rows of data. These rows will be used during future test runs, thus providing you with an easy way to grow your test coverage. Any time you make changes to CalcData.xml, you need to rebuild your solution (Build ⇒ Build Solution) in order to deploy the updated file.

Failing Tests

You can force your test to fail by changing the values in the CalcData.xml file. Try changing the value for the first instance of ExpectedAddAnswer from 12 to 14. Click Build ⇒ Build Solution and then run your test again. The test fails as shown in Figure 24.14.

For coded UI tests with multiple assertions, it can be useful to know more about exactly which assertion caused the test to fail. If you entered a message as shown in Figure 24.9 when you defined your assertion then it displays here, providing you with more information about why the test failed. If you didn't provide additional details in Figure 24.9 then you would only know that the expected value of 14 does not match the actual value of 12, and you might need to spend time investigating what those values are meant to represent in the UI of your application.

Because your test ran with multiple iterations of data (from your XML file) only the first iteration failed. The second iteration passed as expected.


Note
Note that a test iteration fails and aborts immediately after the first assertion within a given test iteration has failed. For example, if you see a message that the AssertAdd() assertion failed, you still won't know whether or not the subtraction/multiplication/division operations are working properly. If you require more granular reporting of your test runs, it is advisable to create multiple coded UI tests, each verifying one unit of functionality.

Finally, if you click the Output link for a test result you see any test attachments that were added during the test run. By default, the coded UI test runner automatically takes a screenshot of your running application and attaches that to your test results if a test fails. This can be helpful for reviewing failed tests later on to inspect the state of the application at the time of the test failure.

Taking Screenshots

You can also programmatically capture screenshots that can be saved to your test results. This can be useful even if a coded UI test passes because you can examine it later to see if there was anything that appeared incorrectly in the user interface for which you didn't explicitly code assertions.

The following code takes a screenshot of your WPF calculator application. It saves it to your test result as a file named AddResult.bmp. Add this immediately before the call to AssertAdd() in your test method:

Image pic = this.UIMap.UIDemoCalculatorWPFWindow.CaptureImage(); 
pic.Save(@"c:AddResult.bmp");
TestContext.AddResultFile(@"c:AddResult.bmp");

Alternatively, you can capture a screenshot of the entire desktop by replacing the first line in the preceding code with the following line:

Image pic = UITestControl.Desktop.CaptureImage();

Taking a screenshot of the entire desktop can be helpful if you are testing applications that utilize multiple windows at once. These screenshots are accessible by clicking the Output link from within the test results view of Test Explorer.

UI Map Editor


Note
You can conduct image comparisons within coded UI tests by following the steps outlined at http://tinyurl.com/ImageCompare. These steps utilize a free set of testing libraries known as TestApi, available at http://testapi.codeplex.com. TestApi provides several helpful libraries and tools, many of which you can access directly from your coded UI tests.

Earlier in this chapter you read about the UI Map, which is generated by the Test Builder, and you looked at the UIMap.Designer.cs partial class file where most of the logic for your coded UI test is written. But you also discovered that you should not make changes directly to that file because it is meant to be maintained by the Visual Studio designers, including the Test Builder, and any changes you make by hand might be overwritten later by the designer.

Visual Studio 2012 includes a built-in UI Map Editor that you can run by simply double-clicking the UIMap.uitest file from within Solution Explorer. The UI Map Editor opens as shown in Figure 24.15.

The panel on the left is the UI Actions panel and contains all the methods you created when you clicked Generate Code from within the Test Builder. These are listed in alphabetical order only and do not necessarily reflect the order in which they will be executed (if at all). The order in which these might be called is defined by your CodedUITestMethod1() method.

The UI Actions panel provides you with a few useful capabilities for maintaining your coded UI tests. You can delete entire methods or individual actions by selecting them and pressing delete. For example, maybe when you were recording your test you accidentally clicked a control or typed some text that you didn't mean to type. You can come back to this view to clean up your extra actions.

Another common use of the UI Actions panel is to split methods into smaller methods. For example, you might want to split the EnterDataAndClickAdd() method into three different methods—one to launch the application, another to enter some data, and a third to click the Add button. This gives you more flexibility when programming your test methods. To do this, you need to place your cursor on a row within the EnterDataAndClickAdd() method and then click Split into a New Method in the toolbar. Visual Studio alerts you that if you split this method, you need to manually update your test code within the CodedUITestMethod1() to call the new methods. You can also use the UI Actions panel to rename the new split methods to reflect what they do (such as LaunchApp(), EnterData(), and ClickAdd()).

You can insert delays between steps from here as well. By default, the coded UI test playback engine attempts to run tests as quickly as possible by examining the UI thread to determine if controls are ready to be interacted with. However, you may know that your application automatically refreshes some number of seconds after a form is initially loaded. To test the post-refresh status of the page you might want to use the Insert Delay Before button on the toolbar.

You can also use the Properties window (View ⇒ Properties Window) in Visual Studio to inspect additional parameters for any of the actions in the UI Actions panel. The available properties vary based on the type of action you have selected. For example, the action Type ‘20’ in ‘testInput1’ text box enables you to override the value 20 with a different value by entering it into the property grid. However if you have databound your test by following the instructions provided earlier in this chapter then this value is overridden by the values from your XML file.

Another useful property available on all actions is Continue on Error. By default, this is set to False for all actions—meaning that if an action fails, the test fails and execution for that test iteration is stopped. But sometimes you might want a test to try to keep executing even if a specific action fails. A good example of this is when the application you are testing occasionally presents additional dialogs that do not affect the end result of your test run. Your application might randomly present a dialog asking if you want to complete a customer satisfaction survey. In this case, you probably want an action in your test logic that clicks No and continues, but unless you enable Continue on Error for that action then your test might fail if it doesn't find the relevant No button to click in subsequent test runs.

The UI Control Map on the right side of the UI Map Editor is the same one you saw earlier in Figure 24.10. As you highlight various actions within the UI Actions pane notice that the relevant controls within the UI Control Map hierarchy are highlighted. You can also edit properties for these controls by accessing the Properties window within Visual Studio.

The actual properties available to you for a given control vary based on the type of control, and the type of application. For example, web applications use both search and filter properties to locate controls, whereas rich client applications such as WPF or Windows Forms only use search properties. Most of the time you probably don't need to change the properties for controls in your UI Map, although occasionally if the names of controls or their positions within your control hierarchy changes you may need to examine these properties.

Now that you know how to create a coded UI test from scratch by using the Test Builder, it's time to examine an approach of creating a coded UI test from an existing manual test.

Creating Coded UI Tests Using Action Recordings

Creating a coded UI test from an existing manual test can be less time-consuming than recording a coded UI test from scratch. If your team is already creating manual test cases and associated action recordings, you can benefit from these artifacts when creating your coded UI tests.

For this section, it is assumed that you know how to create manual tests and their associated action recordings. For more information about manual testing, see Chapter 23.

Start by creating a test like the one shown in Figure 24.16. For simplicity, this test only validates that the addition and subtraction functions of the calculator work properly. You can easily extend this test to support multiplication and division if you want. Also note that this test uses parameterized values for the inputs and expected results.

Now, run this manual test and create an action recording for it. Be sure to mark each test step as Pass while you are recording so that your actions are properly associated with each test step.

Now that the manual test has been created, along with an associated action recording, you are ready to convert this into a coded UI test. Create a new test project (or you can use the one you created earlier in this chapter). Right-click the project and add a coded UI test. The dialog shown in Figure 24.3 displays again. This time, select Use an Existing Action Recording.

The Work Items Picker shown in Figure 24.17 enables you to select the test case work item from which you want to create a coded UI test. Find and select the work item you created earlier for your manual test case and then click OK.


Note
The test case work item has a field called Automation Status. You might want to instruct your test team to set this value to Planned when manual test cases are ready for a developer to convert into a coded UI test. You can then create a query to use from the Work Items Picker to find test cases whose Automation Status is equal to Planned.

Visual Studio converts the action recording from your manual test into a coded UI test. The structure of this coded UI test resembles that of the one you created from scratch earlier, but there are a few key differences. Here is the code for CodedUITestMethod1:

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase",
"http://vsalm:8080/tfs/defaultcollection;FabrikamFiber", "97",
DataAccessMethod.Sequential), TestMethod]
public void CodedUITestMethod1()
{
 this.UIMap.Opencalculator();
 this.UIMap.Typeparam1andparam2intotextboxesParams.UITextInput1EditText =
TestContext.DataRow["param1"].ToString();
 this.UIMap.Typeparam1andparam2intotextboxesParams.UITextInput2EditText =
TestContext.DataRow["param2"].ToString();
 this.UIMap.Typeparam1andparam2intotextboxes();
 this.UIMap.ClickAdd();
 this.UIMap.ClickSubtract1();
}

Note
The path to your Team Foundation Server instance in the [DataSource] attribute varies from that listed here. Additionally, the ClickSubtract1 method above is named simply ClickSubtract if you are using a new test project instead of adding this coded UI test to the existing project you created earlier in this chapter (which already contains a ClickSubtract method).

First, notice the attribute on this test method that is data-binding it to the parameter values stored in the test case work item you created. This means that you can update the test parameters centrally from within the work item without needing to maintain a separate database or XML file as you did earlier. This makes it easy for generalist testers (who may not work with source control within Visual Studio) to update test case data.

Next, notice that the names of the method calls in this test method match the text that was used for each test step in the manual test. This can make for cumbersome method names if you have verbose test steps, but it also makes it possible to see exactly which method call corresponds to each part of the test execution.

Finally, you may notice that this coded UI test doesn't contain any assertions yet. Manual tests rely on human beings to perform validation of the intended UI behavior, so, in order to automate validation steps, you must program the appropriate test logic.

Add a new line after the ClickAdd() method call. Right-click this empty line and select Generate Code for Coded UI Test ⇒ Use Coded UI Test Builder. Alternatively, you can access this menu via the Test menu.

The Coded UI Test Builder displays again as shown earlier in Figure 24.5. Open the calculator application and use the crosshair to select the bottommost textbox, as you did earlier. Add an assertion on the Text property of the UITextAnswerEdit textbox. The assertion should be Are Equal and the comparison value is empty (you override this value programmatically). Optionally, you can provide a meaningful value for Message on Assertion Failure if you want. After you have added this, click Generate Code and name your assertion method AssertAdd2. Click Add and Generate.


Note
The reason you are naming this method AssertAdd2 (as opposed to simply AssertAdd) is to avoid naming conflicts with the assertion method you created earlier in this chapter. If you are using a new test project, then this naming distinction is not necessary.

Add another assertion on the same control/property, but this time, name it AssertSubtract2. Close the Coded UI Test Builder when you are finished. Visual Studio opens again, and you will notice that two assert method calls have been added to your coded UI test method. Rearrange the method calls so that the assertions appear after their respective action method calls. When finished, your test method should contain the following lines:

this.UIMap.ClickAdd();
this.UIMap.AssertAdd2();
this.UIMap.ClickSubtract1();
this.UIMap.AssertSubtract2();

You now need to data-bind the parameters used by the assertions to the parameters stored within your test case. Add the following highlighted lines to your test method:

this.UIMap.ClickAdd();
this.UIMap.AssertAdd2ExpectedValues.UITextAnswerEditText =
TestContext.DataRow["sum"].ToString();
this.UIMap.AssertAdd2();

this.UIMap.AssertSubtract2ExpectedValues.UITextAnswerEditText =
TestContext.DataRow["difference"].ToString();
this.UIMap.ClickSubtract1();
this.UIMap.AssertSubtract2();

You can run your test by right-clicking within the test method and clicking Run Tests. Your test should run once for each data row within your test case's parameter value table. Try manipulating the parameters in your test case and run your coded UI test again to see the data-binding relationship.

If this were a real testing project, you might also want to spend some time refactoring the code in the duplicative Add and Subtract method calls into common methods for easier long-term maintenance. You can use the UI Map Editor to delete duplicate methods and then hand-edit the appropriate code UI test methods to call the correct methods. Many of the same best practices you know from maintaining complex applications apply when maintaining complex test projects.

You can also add your coded UI test as associated automation for the original manual test case. By associating the test case with the automated test, the automated test can be run as part of your test plan, and tracked along with the rest of your test cases. Chapter 23 provides more details on how to create this association.

Supported Technologies

Coded UI tests require that your application be built using one of several supported technologies. The coded UI testing framework requires that it understands the underlying technology so that it can interact with the application being tested. The list of supported technologies is expected to grow over time, and Visual Studio 2012 offers an extensibility framework to allow third parties to build their own testing providers. However, if your application uses a technology for which there is not a testing provider available, you are unable to author coded UI tests for it.


Note
For a complete list of supported technologies and caveats, consult the Visual Studio 2012 product documentation at http://aka.ms/TestAutomation

Summary

Coded UI tests provided a powerful way of crafting automated tests for functional UI testing of your applications. In this chapter, you saw how you can either create a coded UI test from scratch, by interacting with an application the way you expect a user would, or from an existing action recording from a manual test, thus leveraging some of the work already done by your testing team.

You also found out how you can enhance your coded UI tests by data-binding them to create multiple test runs out of the same set of test steps.

In Chapter 25, you see how you can use web performance tests to help speed up your web applications. You also find out how to simulate the results of hundreds (or even thousands) of users interacting with your web application by using Visual Studio's load-testing capabilities.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.134.154