I've been thinking for a while to share about some thoughts I have about using Coded UI stuff for web automation with c# without using the wizard stuff. So, without wasting much time, for those who prefer some hands-on let's go about how to start it off with Visual Studio 2010 or Visual Studio 2012.
First and Foremost I assume a few things that the reader is already aware of VS2010, c# (Of course if you have an idea of any object oriented language, getting to know others isn’t tough.).
Also I assume that the user believes the application he/she has can be automated (This of course can be subjective, so I won’t drag on this) after doing enough research on the product,technology it uses etc… J Let's get on with our stuff now...
1. Launch Visual Studio
2. Create a new Test Project.. (File->New Project->Visual c#->Test -> Project_23). Click Ok
3. From the 'Test' menu, click 'New Test', select 'Coded UI Test' , Provide a 'Test Name', click Ok
4. Click 'Cancel' for the Generate code for Coded UI Test dialog.
What we'll do over here is that... we'll come up with a generic approach for our automation.
-> Have a couple of xml files for saving configuration stuff, Test Case (e.g., config.xml,TestCases.xml)
-> A generic class file that would contain our frequently used methods (GenericFunctions.cs)
-> Obviously, the c# file which would contain the tests (MyTestMethods.cs) . Let's dive in...
Step1: Create an XML file for loading Test Cases, Configuration...
a) TestCases.xml
<?xml version='1.0' encoding='utf-8' ?>
<cases>
<!-- Test Case 1 and it's related parameters go here -->
<testcase id='1' title='Test Case 1: Verify whether a user can be added from the Web application'>
<params>
<firstname>John</firstname>
<lastname>Smith</lastname>
<address> Midtown </address>
<city> New York</city>
<state> New York</state>
<zipcode>232323</zipcode>
</params>
</testcase>
<!-- Test Case 2 and it's related parameters go here -->
<testcase id='2' title='Test Case 2: Verify whether a user can be removed from the Web application'>
<params>
</params>
</testcase>
</cases>
b) config.xml (the file that contains the configuration stuff)
<?xml version='1.0' encoding='utf-8' ?>
<root>
<params>
<hosturl>http://www.google.com</hosturl>
<reportFile>FinalSummary</reportFile>
<rfextension>html</rfextension> <!--report file extension-->
</params>
</root>
Step 2: Create a generic class file to maintain the common functions that may get used frequently
From the Solution Explorer, Right Click on the project, Add New Item, select ‘Class’, Provide a name ‘e.g., GenericFunctions’, Save
Over here, we’ll just write a function that gets all test data above as a collection of dictionary items
namespace demotest
{
class GenericFunctions
{
//Gets all Test Data from cases.xml given the test case id interms of a dictionary
public Dictionary<string, object> getTestData(int testcaseid)
{
int tcid = testcaseid;
string fn = getTestCaseFile();
XmlDocument xd = new XmlDocument();
xd.Load(fn);
XmlNodeList nodelist = xd.SelectNodes("/cases/testcase"); // get all <testcase> nodes
Dictionary<string, object> testdata = new Dictionary<string, object>();
foreach (XmlNode node in nodelist)
{
if (Convert.ToInt32(node.Attributes.GetNamedItem("id").Value) == tcid)
{
XmlNode n = node.SelectSingleNode("params");
for (int i = 0; i < n.ChildNodes.Count; i++)
{
testdata.Add(n.ChildNodes.Item(i).Name, n.ChildNodes.Item(i).InnerText);
}
}
}
return testdata;
}
//Gets all Test Configuration Data from main.xml in terms of a dictionary
public Dictionary<string, object> getConfigData()
{
string fn = getConfigFile();
XmlDocument xd = new XmlDocument();
xd.Load(fn);
XmlNodeList nodelist = xd.SelectNodes("/root"); // get all <testcase> nodes
Dictionary<string, object> configdata = new Dictionary<string, object>();
foreach (XmlNode node in nodelist)
{
XmlNode n = node.SelectSingleNode("params");
for (int i = 0; i < n.ChildNodes.Count; i++)
{
configdata.Add(n.ChildNodes.Item(i).Name, n.ChildNodes.Item(i).InnerText);
}
}
return configdata;
}
//gets the current working directory
public string getCurrentDir()
{
string fileDir = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
if (fileDir.EndsWith("\\bin\\Debug"))
{
fileDir = fileDir.Replace("bin\\Debug", "");
}
return fileDir;
}
//Get the Path to cases.xml which contains the Test Data related to Test Cases
public string getTestCaseFile()
{
string fn = getCurrentDir() + "\\TestCases.xml";
fn = Path.GetFullPath(fn);
return fn;
}
//Get the Path to main.xml which contains information about the configuration settigs
public string getConfigFile()
{
string fn = getCurrentDir() + "\\config.xml";
fn = Path.GetFullPath(fn);
return fn;
}
}
}
We can just access the test data for each test cases as listed below. The objective is to get the test case data as a collection once you specify the test case id.
GenericFunctions gf = new GenericFunctions(); // Get an instance of our custom class to invoke common methods
Dictionary<string, object> testdata = gf.getTestData(1); //gets all the data from Test Case - 1
MessageBox.Show(“First Name: “+Testdata[“firstname"].toString()); //gets the value specified for firstname
MessageBox.Show(“City: ”+Testdata[“city"].toString())
Step 3: Create a Coded UI Test and get ahead with the hand-coding stuff
1. In Solution Explorer, right-click on your project, point to Add, and then click Coded UI Test. (Provide a name TestCases.cs)
2. Click ‘Cancel’ for the ‘Generate Code for Coded UI Test’ dialog
Now, your will see the c-sharp code window similar to the one given below…
We can just rename the method; add our Custom names as shown below
Now, you can start spying the controls for their properties and start with the automation stuff… Let’s see it for Add User…
Over here, we search for the textbox with id “firstname”, set the value as we have in the xml
w.r.t the Test Case id “1”:
You can also search for controls using regular expressions, they come handy very often.. e.g.,
monthSummaryTable.SearchProperties.Add(HtmlTable.PropertyNames.InnerText, "Month Summary", PropertyExpressionOperator.Contains);
Similarly, you can spy for the other fields using the spy control that comes with the Coded UI Test builder and simulate /perform other actions… For e.g., once we are done with all text fields let’s assume that we need to click the ‘Save’ Button.
Imagine that you get a message saving ‘User Saved/Added successfully' in a span tag once the action is performed, we can check for the message as:
Your Test’s will look something like this in the Test List Editor.
Also, You can actually customize printing your reports to HTML,XML or whatever format you wish by writing your own methods as well. If you have any comments, suggestions, questions please do post them...
Credits:
http://blogs.msdn.com/b/anutthara/archive/2009/08/19/using-regular-expressions-to-locate-controls-in-coded-ui-test.aspx