Data Import using Visual Studio Test Framework
Purpose: The purpose of this document is to illustrate how to use Visual Studio Test Framework to import data into Microsoft Dynamics AX 2012
Challenge: For the purposes of POC (Proof of Concept) or testing in you need to import business data into Microsoft Dynamics AX 2012 with minimum effort without knowing the specifics of the data model and business logic, you can do it via User Interface with help of Visual Studio Test Framework
Solution: Using Microsoft Visual Studio Test Project you can create a Coded UI Test that tests whether the User Interface for an application functions correctly. Coded UI Test performs actions on the user interface controls for an application and verifies that specified controls display the correct values. However in this scenario we’ll use coded UI test, specifically Data Driven Coded UI Test, to automate tedious manual task of entering the data into the system via User Interface
Diagram
Walkthrough: Data Driven Coded UI Test
Create Test project
TestProject1
Add Coded UI Test
Generate Code for Coded UI Test: Record actions, edit UI map or add assertions
Coded UI Test Builder
Start recording
Now we will go through the usual process of customer creation in Microsoft Dynamics AX 2012 while recording all the actions
You can pause recording and then resume it if required
Once done we’ll give a name to the method. For example, CustomerImport
You can record actions for more methods if required. For example, for import of vendors, etc
The system will generate all necessary code for you
Source code
{
#region Variable Declarations
WinMenuItem
uICustomerMenuItem = this.UIMicrosoftDynamicsAXDWindow.UIHomeTabWindow.UINewGroup.UICustomerMenuItem;
WinEdit
uINameEdit = this.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit;
WinClient
uICustomergrouplookupbClient = this.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergrouplookupbClient;
WinCell
uIItem10Cell = this.UIItem1usmfWindow.UIItemWindow.UIGridTable.UIRow1Row.UIItem10Cell;
WinButton
uISaveandcloseButton = this.UICustomer1usmfNewRecoWindow.UIItemWindow2.UISaveandcloseButton;
#endregion
// Click
'Customer' menu item
Mouse.Click(uICustomerMenuItem,
new Point(35,
40));
// Click 'Name'
text box
Mouse.Click(uINameEdit,
new Point(23,
0));
// Type 'Alex Customer' in 'Name' text box
uINameEdit.Text = this.CustomerImportParams.UINameEditText;
// Click
'Customer group lookup button' client
Mouse.Click(uICustomergrouplookupbClient,
new Point(4,
8));
// Click '10'
cell
Mouse.Click(uIItem10Cell,
new Point(43,
11));
// Click 'Save
and close' button
Mouse.Click(uISaveandcloseButton,
new Point(66,
10));
} |
[GeneratedCode("Coded
UITest Builder", "10.0.40219.445")]
public class CustomerImportParams
{
#region Fields
/// <summary>
/// Type 'Alex Customer' in
'Name' text box
/// </summary>
public string
UINameEditText = "Alex Customer";
#endregion
} |
XML
<?xml version="1.0"?>
<UITest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="" Id="d7c9b5a2-9a9b-4562-a65e-678e9d87ba78" AssemblyVersion="10.0.40219.445" Version="1.0" xmlns="http://schemas.microsoft.com/VisualStudio/TeamTest/UITest/2010">
<Configuration>
…
<Configuration />
<InitializeActions />
<ExecuteActions>
<MouseAction UIObjectName="UIMap.UIMicrosoftDynamicsAXDWindow.UIHomeTabWindow.UINewGroup.UICustomerMenuItem">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="35" Y="40" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<MouseAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="23" Y="0" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<SetValueAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit">
<ParameterName />
<Value Encoded="false">Alex Customer</Value>
<Type>String</Type>
</SetValueAction>
<MouseAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergrouplookupbClient">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="4" Y="8" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<MouseAction UIObjectName="UIMap.UIItem1usmfWindow.UIItemWindow.UIGridTable.UIRow1Row.UIItem10Cell">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="43" Y="11" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<MouseAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow2.UISaveandcloseButton">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="66" Y="10" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<TestStepMarkerAction MarkerInformation="CustomerImport">
<ParameterName />
<StepId>-1</StepId>
<Direction>Start</Direction>
<Outcome />
<Disabled>false</Disabled>
<WorkItemId>0</WorkItemId>
<MarkerRegionType>Action</MarkerRegionType>
</TestStepMarkerAction>
</ExecuteActions>
<CleanupActions />
<OnErrorActions />
<Maps>
…
</Maps>
<ValueMap>
<ParameterList />
</ValueMap>
</UITest>
|
Please note that XML will be different depending on how I enter a data. Below I describe a difference between using a lookup for data selection versus keying in the data
Option 1 – Lookup
<MouseAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergrouplookupbClient">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="4" Y="8" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
<MouseAction UIObjectName="UIMap.UIItem1usmfWindow.UIItemWindow.UIGridTable.UIRow1Row.UIItem10Cell">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Location X="43" Y="11" />
<WheelDirection>0</WheelDirection>
<ActionType>Click</ActionType>
<MouseButton>Left</MouseButton>
</MouseAction>
|
Option 2 – Key in
<SendKeysAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit">
<ParameterName />
<ModifierKeys>None</ModifierKeys>
<IsGlobalHotkey>false</IsGlobalHotkey>
<Text Encoded="false">{Tab}</Text>
</SendKeysAction>
<SetValueAction UIObjectName="UIMap.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergroupEdit">
<ParameterName />
<Value Encoded="false">10</Value>
<Type>String</Type>
</SetValueAction>
|
Now we can run the test and the system will create a customer for us
Result in Microsoft Dynamics AX 2012
We can technically create one more customer by changing the code appropriately
Source code
[GeneratedCode("Coded
UITest Builder", "10.0.40219.445")]
public class CustomerImportParams
{
#region Fields
/// <summary>
/// Type 'Alex Customer 2'
in 'Name' text box
/// </summary>
public string
UINameEditText = "Alex Customer 2";
#endregion
} |
Result in Microsoft Dynamics AX 2012
In fact we are interested in creating multiple customers at once
For these purposes we can introduce a loop
Source code
public void CustomerImport()
{
#region Variable Declarations
WinMenuItem
uICustomerMenuItem = this.UIMicrosoftDynamicsAXDWindow.UIHomeTabWindow.UINewGroup.UICustomerMenuItem;
WinEdit
uINameEdit = this.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit;
WinClient
uICustomergrouplookupbClient = this.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergrouplookupbClient;
WinCell
uIItem10Cell = this.UIItem1usmfWindow.UIItemWindow.UIGridTable.UIRow1Row.UIItem10Cell;
WinButton
uISaveandcloseButton = this.UICustomer1usmfNewRecoWindow.UIItemWindow2.UISaveandcloseButton;
#endregion
int i;
for (i = 2; i <= 10; i++)
{
// Click
'Customer' menu item
Mouse.Click(uICustomerMenuItem,
new Point(35,
40));
// Click
'Name' text box
Mouse.Click(uINameEdit,
new Point(23,
0));
// Type 'Alex CustomerN' in 'Name' text box
uINameEdit.Text = this.CustomerImportParams.UINameEditText
+ i.ToString();
// Click
'Customer group lookup button' client
Mouse.Click(uICustomergrouplookupbClient,
new Point(4,
8));
// Click '10'
cell
Mouse.Click(uIItem10Cell,
new Point(43,
11));
// Click
'Save and close' button
Mouse.Click(uISaveandcloseButton,
new Point(66,
10));
}
} |
[GeneratedCode("Coded
UITest Builder", "10.0.40219.445")]
public class CustomerImportParams
{
#region Fields
/// <summary>
/// Type 'Alex Customer' in
'Name' text box
/// </summary>
public string
UINameEditText = "Alex Customer";
#endregion
} |
Result in Microsoft Dynamics AX 2012
This approach will work if all our customers will have uniform/similar name
However when we really want to do is to import customers based on a file. For example, we have CSV (Comma Separated Value) file with a list of customers
For these purposes we will introduce Data Driven Coded UI Test
Please find more info about Data Driven Coded UI Test here: http://msdn.microsoft.com/en-us/library/ee624082.aspx
CSV File
Name
Alex Customer2
Alex Customer3
Alex Customer4
Alex Customer5
Alex Customer6
Alex Customer7
Alex Customer8
Alex Customer9
Alex Customer10
|
Source code
[DeploymentItem("Customers.csv"),
DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
"C:\\Users\\Administrator\\Documents\\Visual Studio
2010\\Projects\\TestProject\\TestProject\\Customers.csv", "Customers#csv",
DataAccessMethod.Sequential),
TestMethod]
public void CodedUITestMethod1()
{
// To generate
code for this test, select "Generate Code for Coded UI Test" from the
shortcut menu and select one of the menu items.
// For more information
on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
string name = TestContext.DataRow[0].ToString();
this.UIMap.CustomerImport(name);
} |
public void CustomerImport(string
_name)
{
#region Variable Declarations
WinMenuItem
uICustomerMenuItem = this.UIMicrosoftDynamicsAXDWindow.UIHomeTabWindow.UINewGroup.UICustomerMenuItem;
WinEdit
uINameEdit = this.UICustomer1usmfNewRecoWindow.UIItemWindow.UINameEdit;
WinClient
uICustomergrouplookupbClient = this.UICustomer1usmfNewRecoWindow.UIItemWindow1.UICustomergrouplookupbClient;
WinCell
uIItem10Cell = this.UIItem1usmfWindow.UIItemWindow.UIGridTable.UIRow1Row.UIItem10Cell;
WinButton
uISaveandcloseButton = this.UICustomer1usmfNewRecoWindow.UIItemWindow2.UISaveandcloseButton;
#endregion
// Click
'Customer' menu item
Mouse.Click(uICustomerMenuItem,
new Point(35,
40));
// Click 'Name'
text box
Mouse.Click(uINameEdit,
new Point(23,
0));
// Type 'Alex Customer' in 'Name' text box
uINameEdit.Text
= _name;// this.CustomerImportParams.UINameEditText;
// Click
'Customer group lookup button' client
Mouse.Click(uICustomergrouplookupbClient,
new Point(4,
8));
// Click '10'
cell
Mouse.Click(uIItem10Cell,
new Point(43,
11));
// Click 'Save
and close' button
Mouse.Click(uISaveandcloseButton,
new Point(66,
10));
} |
Note: Please note that all changes to your test to enable it to use a data source for the parameters will be made to your test's source code file (i.e. CodedUITest1.cs). You cannot modify the code in the UIMap.Designer.cs file.
Result in Microsoft Dynamics AX 2012
Remark: Please note that in order for Coded UI Test to interact with desktop the computer running the test should not be locked during test execution time. Otherwise you will see the following error: “Automation engine is unable to playback the test because it is not able to interact with the desktop. This could happen if the computer running the test is locked or its remote session window is minimized.”
Summary: This document describes how to use Visual Studio Test Framework to import data into Microsoft Dynamics AX 2012 for the purposes of POC or testing by automation of data entry via User Interface. You can organize parallel import of data by running multiple instances of the test at the same time from different clients or investigate how to potentially make use of Load Test Visual Studio Test Framework. Please note that the recommended tool for data import in Microsoft Dynamics AX 2012 is Data Import Export Framework which provides number of standard templates for main business entities and documents, ability to use various entity types (Entity, Composite Entity, Table) and extend it for custom data.
Tags: Microsoft Dynamics ERP, Microsoft Dynamics AX 2012, Data Migration, Data Import, Data Conversion, Test Automation, Visual Studio Test Framework, Data Driven Coded UI Test.
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the concepts and describe the examples.
Thanks for this!!!
ReplyDeleteBTW, this post doesn't seem to open in IE
Hi Beebe4!
ReplyDeleteI use IE10 and can see all the content properly
/Alex
Coded UI testing for .NET application
ReplyDelete