This article is contributed. See the original author and article here.
The following is the second on a series of articles by @Ali Youssefi that we will be cross-posting into this Test Community Blog. These articles were first published by Ali in the Dynamics community but since the topic is very related with Testing it makes sense to publish here as well.
If you didn’t get a chance to catch the first one of the series, please have a look here: Test Automation and EasyRepro: 01 – Overview and Getting Started
Otherwise, please read ahead!
EasyRepro is an open source framework built upon Selenium allowing automated UI tests to be performed on a specific Dynamics 365 organization. This article will focus on designing and debugging unit tests. It will follow up on the first post’s sample unit test in depth as well as provide design and troubleshooting ideas.
If you haven’t already, you may want to clone the project that we used on the first article on this series (link above) from GitHub to DevOps then build locally and review any dependencies and/or test settings to run a simple test.
Reviewing the Open Account Sample Unit Test in depth
When working with the sample unit tests you’ll soon find that while extremely helpful you’ll need to modify or extend these tests to work with your customizations of the platform. The sample unit tests provide a great starting off point and can help us better understand how to work with the EasyRepro framework. Let’s review the UCITestOpenActiveAccount unit test line by line.
WebClient and XrmApp objects
The WebClient is derived from the BrowserPage class and injected into the XrmApp object. The WebClient contains mainly internal methods used by the XrmApp and platform element references such as OnlineLogin, Navigation, Grid, etc as shown in the unit tests above. Typically you will not be interacting with this object until you need to extend the framework.
The XrmApp is the primary way of navigating and commanding the platform. When opened you’ll see the WebClient passed into each object used in the unit tests. Review this object to better understand each of the area of the platform you can work with in your unit tests.
As you can see, each of the commands in the Open Account unit test are represented by elements related to Dynamics. These elements include commands related to the object such as working with entity forms and navigating around the platform. Each element can be explored to determine what functionality can be achieved from the framework natively.
Let’s review each one of the commands in the Open Account unit test to better understand what they are doing and where we may need to modify to better meet our requirements.
The Login method typically involves two paths: One using the standard Microsoft Office login and one that redirects to your organization’s sign in page.
The first line shows passing in the URI of the organization, the username and password. How to set these values is covered in the first post in this series Test Automation and EasyRepro: 01 – Overview and Getting Started.
The second shows how to incorporate your organization’s sign in page. Each sign in page is unique and will require understanding how to work with Selenium and the DOM of the page to input and submit these credentials. This will be covered in the Designing Tests towards Customization section.
Once the Login method has completed we will redirected to our default application in the organization. The next command details moving to another UCI application.
Open UCI App
The OpenApp method uses the UCIAppName class to navigate to a specific UCI app. The standard platform applications such as Sales Hub and Customer Service Hub, as well as others, are available in the class. I’ll cover how to extend to a custom UCI app in the Designing Tests towards Customization section.
Open Sub Area
OpenSubArea introduces the first navigation into the sitemap of the Unified Interface. This method expects two parameters, the first identifying which area to open and the second which subarea to click. These string values are case sensitive.
The Search method is used on the Grid object to search using the Quick Find view. Wildcard characters can be added here to simulate a user looking for values like or starting with specific characters if desired. For our unit test as long as we have the sample data in the organization we should pull up the Adventure Works (sample) record in the result set.
The final navigation command in the unit test is to open the first record in the Grid using OpenRecord. As long as we pulled up the Adventure Works (sample) in our results this will open the first record based on the index of the rows in the view. If the index is outside of the bounds an exception will be thrown.
Finally we have reached the end of the unit test. The final command here is a method called ThinkTime. This is used to simulate a user waiting for a period of time, in this case 3 seconds. This is a useful method to allow elements to render for use with the framework.
Designing Tests towards Customization
Adding custom UCI applications
In our sample unit test we are navigating to the Sales Hub Unified Interface but there maybe times where you will need to navigate to a specific custom application. A simple way to do so, assuming the UCI app shows in the user’s drop down when logged in, is to add to the UCIAppName class.
In the example above a new string has been added to the class called ‘PfeCustomApp’. The OpenApp method will search for an UCI app with called ‘PFE Custom App’. This can then be used in single or many unit tests.
Searching and reviewing results in a Grid
In our sample unit test we knew what to expect due to sample data in our organization. However when implementing your own unit tests you may want perform additional tasks like counting the number of results are returned, sort the records in the view, switch the view, etc.
Above is an image from the Object Browser showcasing the native EasyRepro functionality for the Grid object. To Search use the Search method. For reviewing results look to the GetGridItems method to extract the grid items which we can iterate through.
Changing Forms and Referencing Fields
Going back to the UCITestOpenActiveAccount unit test as described above we searched for the Adventure Works (sample) record in clicked on the first record in the Quick Find view. We just touched on actions that can be performed on the view, now let’s look at what can be done once we are inside the record.
When the Adventure Works (sample) record is opened we now can shift gears to working with the Entity object. The Entity object includes functionality such as but not limited to:
· Assigning the record to another user or team
· Working with field values
· Working with Sub Grids
· Switching Forms
· Switching Processes
For now let’s stick with changing forms and working with field values.
Start by navigating to the OpenRecord method and adding a new line. Here we will add SelectForm(“<name of your form>”). This works with the form selector and allows us to change the form based on the name.
Working with Field Values
When working with most fields on the form the actions a user will perform are to clear out a value, read a value or update a value. In the below image I’ve added a line using the GetValue method. This returns me the current value which can be used for validation or other concerns. When referencing a field it is important to reference by its schema name and not display name. For instance on Account instead of using ‘Account Name’ I’m using ‘name’.
To clear out a value you simply have to use ClearValue and pass in the schema name.
Finally to set a value you use the SetValue method passing in the schema name of the control (unless working with a complex type field).
When you begin to extend and debug the sample unit tests towards your customization you may run questions regarding how the test is running, who its running as, how to handle unforeseen issues, etc. For this section we will talk through some common scenarios that come up and how to address them.
My Unit Test is performing unexpected actions, what can I do?
One of the key benefits of browser automation is that we can watch the unit test in action, halt the execution, and examine the current state of the platform. One of the first steps in doing this is to run the unit test in what’s called Non Headless Mode.
Running Unit Tests in Non Headless Mode
Headless Mode is what tells the unit test if we want to run the test with a GUI or not. Simply stated this will allow us to watch the browser launch and perform the actions or simply run in the background.
In the first post in this series we touched on the TestSettings object and how it tells our unit test how we want it to run. In this object is the class called BrowserOptions and within this is a property called Headless. To turn headless mode on or off, set this value to true (on) or false (off).
My Unit Test needs to run as a specific user, what can I do?
By default to run our EasyRepro unit tests (at least for the online platform) we must provide some credentials that determine who we run our tests as. This helps us identify and troubleshoot issues related to authentication and authorization. However sometimes due to your organization’s setup you may have pass through authentication which will attempt to run the unit tests as the user you are logged into your machine with.
Running Unit Tests in Incognito Mode
Going back to the TestSettings object and inside of BrowserOptions we find a property called PrivateMode. By setting this property to true we can run in “Incognito” or “InPrivate” or whateevr terminology your browser of choice uses. This helps us ensure we are using the credentials we provided as well as not assuming any cached settings are applied.
My Unit Test needs to check form or grid values, what can I do?
If you have worked with the Visual Studio Unit Testing tools in the past you are probably familiar with the Assert class. This class allows a test designer to add assertions to ensure the actions performed are accurate. EasyRepro provides us the ability to check for form or grid values and elements which can then be used to with the Assert class.
Using the Assert class
Below is an example of checking if the number of results from our search is not equal to a single result. This could be helpful to determine if duplicates exist as well as other scenarios.
Exploring the Sample Unit Tests
At this point you should have enough experience to begin exploring the other sample unit tests available in the Microsoft.Dynamics365.UIAutomation.Sample project. These tests show how to interact with popular elements like Business Process Flows, Quick Create forms and Command Bar actions.
Each element has its own unique capabilities and should cover most of what you will need to automate testing in the platform. However you may come across a need to extend EasyRepro to account for specific use cases which we will cover in the next post in the series Extending and Working with XPath.
This article focuses on a specific unit tests and exploring line by line what each command does. While this covers a significant amount of interaction with the EasyRepro framework it really is only one test case. Take time to review as many of the sample unit tests as possible. Some test I find beneficial are:
We hope you guys are enjoying this series of articles on EasyRepro, please don’t hesitate to leave any comments below!
Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.