📜 ⬆️ ⬇️

Time for Coded UI Tests

In this article I will try to tell you in detail about working with Coded UI Test, one of the many innovations of Visual Studio 2010, as well as mentioning the problems I encountered.

We will not waste time and immediately begin testing.


I already have a simple WPF application, the interface of which will be subjected to testing. It is a form with a button, two textboxes for data entry and another for output.
image
')
Create a new test project using Visual Studio 2010.
image

Add a new Coded UI test. This can be done either through Solution Explorer, or through the Test item in the main menu.
We are invited to enter the file name and choose which test project to add it to.
image

After clicking OK, the following window will appear.
image

We are offered to either write down the sequence of actions using the special tool Coded UI Test Builder, or use the ready-made sequence.
We are interested in the first option. OK. In the lower right corner of the screen, Coded UI Test Builder has opened.
image

On it, except for closing and help, only 4 buttons. About them in order.

Start recording.
image

View recorded steps.
image

Using this button, we can change the user interface map (the map contains all user interface controls displayed in the application under test). And add a statement (assert).
image

And finally generate the code.
image

For now, close Test Builder and go back to the studio.

Links to the following basic assemblies are automatically added to the project.
image

As well as an empty file CodedUITest1.cs. We will add test methods to it. Open it and create a StartApp () method in which our application will run. To start Test Builder again, click the right mouse button inside the method.

Note: the code will be generated in the line in which the menu will be called. However, if we launch Test Builder by right-clicking on the method name, the new code will be generated above the old code.

image

The attribute [TestInitialize] says that the code marked with it will be called each time the test method is run.

Exe-file of my application is on the desktop. Click Start Recording and run the application.
Let's look at the recorded actions.
image

We see that we received exactly what we wanted and now we can generate the code (In this case, the recording will automatically be interrupted).

Enter a name for the method.
image

That's what we did.
image

Here, UIMap is a property through which we will access written methods, comparisons, and user interface controls.

Before we look at the implementation of the StartRecordedMethod() method, we StartRecordedMethod() look again at Solution Explorer.
image

We have 3 new files:


Now let's look at the implementation of the method we recorded in the UIMap.Designer.cs file
image

There is nothing complicated here, ApplicationUnderTest is a standard class inherited from UITestControl. The parameters of the Launch method are simply string variables that are automatically generated, it is easy to verify this.
image

But there is a nuance.

If I put my application in a folder and try to record its launch, we will get a slightly different effect.
image

If you think about it a little, then everything falls into place. My application belongs to an open window (folder) and no longer the application starts to be recorded (as such, although it will also happen), and Double Click on the element belonging to the recordable window.

In order not to bother with this, we can easily describe launching an application manually, either by creating the appropriate method in the UIMap.cs file, or directly in the test method in the CodedUITest1.cs file as shown below.
image

Similarly, we write the closure of the application and mark the method with the attribute [TestCleanup], the attribute indicates that this method will be run every time after the end of each method in the test.
image

Let's look at the implementation of the CloseAppRecordedMethod() method.
image

The interaction takes place with the help of the static Click method of the class Mouse , as parameters to which the object (control) and click coordinates relative to the object are passed.

It's time to record the interaction with the interface of our application.

Create the InterfaceTestMethod() method in the CodedUITest1.cs file and mark it with the [TestMethod] attribute

We act according to a proven scheme =)
image

Click on the code generation button and specify the name, I will call the InterfaceTestRecordedMethod() method
image

Let's look at the implementation.
image

Here we see another standard class for interacting with the Keyboard interface. Through the static SendKeys method, we report about pressing the tab key.

Our test is almost ready. What is missing is some kind of verification =)

We implement it. Add a check for TextBox, in which the result is displayed, after clicking on the button. Make it simple enough.

Again, open the UI Test Builder from the InterfaceTestMethod() method and click on the third button to the left (adding an assertion). I will say a few words about the interface of the opened window.
image

All that is available to us at the moment is a button in the upper left corner. By clicking it we will see the list of controls on our user interface map. It will contain only those elements that participated in writing actions to the InterfaceTestRecordedMethod() method. Selecting any item in the list, on the right we will see its properties. The “Add assertion” elements and the two elements to the right of it will also become active (using the first one, you can update the list of properties, and with the second, you can change the currently selected item).

Note: To be able to view all the properties, you must run the application under test.

We do not need the control element (TextBox3) on the map, of course. To add it, we need to hold the left mouse button and drag the “sight” to our TextBox. The item will be marked with a blue frame and added to the list of items, then click Add control to UI Control Map (Alt + C) to add an item to the map.
image

Note: here we can rename and delete the selected item.

To add an assertion, select the property of interest and click Add Assertion.
image

A dialog will appear in which we will be asked to choose the type of statement and the expected value for comparison.
image

Generate the code. I will call the ResultAssertEqualMethod() method.
image
image

Implementation:
image

Normal Assert, the first parameter (expected value) to which the variable with the value “Visual Studio 2010, Hey!” Is passed, and the second (actual value) property Text of our control.

Note: this approach has a big minus. When automatically generating methods that include statements, we are not able to pass additional parameters to static methods (for example, AreEqual() ). But we can do everything on our own in the UIMap.cs file or in CodedUITest1.cs.
image

All is ready. You can run! (Although no one forbade doing this before).


The results are not long in coming.
image

Everything would be fine, but what if we want to use an external data source to be used in our test? Everything is very simple. To do this, follow these steps.

Open the Test View and select our test method.
image

We will show the properties of the method, among them we are interested in Data Connection String. Click on the dot to the right of the property. The Wizard opens and prompts you to select the type of data source.
image

I have a pre-prepared XML file, so I’ll choose option 3. And click Next>

Content of my xml file:
image

We specify the path to the file and we can immediately see the data set. And again click Next>
image

Choose a table, Next>
image

And we are kindly offered to add a file to the project. We agree.
image

Our test method is marked with the following attributes:
image

Now the data from my XML file is available through TextContext . But we still need to pass them in some way to the InterfaceTestRecordedMethod() and ResultAssertEqualMethod() methods. These methods are implemented in the UIMap.Designer.cs file, so we cannot change them. More precisely, we can, but not for long (until the next code generation).

Let's go the other way.

We use another innovation, the Navigate To function, and look for the methods generated by Builder.

image
To pass parameters to methods that record a sequence of actions, the class XXX Params generated, where XXX is the name of the method.

image
And for passing parameters to the approval method - XXX EpectedValues .

Let's go back to our InterfaceTestMethod() test method and change it as follows:
image

Run the test.
image

Note: if you are attentive enough, you might have noticed that in spite of the two data sets for the test, the result is that 3 of 3 are done:
image
This is due to the fact that the test with all data sets is also considered a test.

A couple of times by clicking on the test result, you can get a more detailed report.
image

Well that's all. The test was successfully passed, but I promised to tell you about the problems I encountered.
Here they are:

It was originally supposed to make the output of the result not in the TextBox, but in the MessageBox.
But what happened with the different contents of MessageBox:
image

Each time a new control was created on the UI Map. Those. if I took data from the same XML without adding an element with this data to the map, then the test would fail. Agree, it is not very convenient =)

You cannot write a sequence of actions and add assert to one method using the UI Test Builder, which is also not very convenient.

And finally, I was unable to delete the method generated by the UI Test Builder with a recorded sequence of actions.

UPD: Test project can be downloaded here .

Source: https://habr.com/ru/post/97012/


All Articles