Building Data-Driven Coded UI Tests (CUIT) Using A CSV File

October 13, 2012 — Leave a comment

Data-Driven Coded UI Tests are great at testing screens with data permutations. In this example I am using data stored in a CSV file as a Data Source.

The application under test is a simple WPF login screen.

Login Screen

Get the code @ https://github.com/brisebois/Coded.UI.Test.Demoware

The following is the content of my UserData.csv. Depending on your system’s culture you may need to replace ‘;’ characters generated by Excel by ‘,’ characters.

User,Password
Alexandre,P@ssword
Etienne,P@ssword
DotNetMontreal,P@ssword

The DataSource attribute can be used to to pull data from Test case in TFS, SQL Express, CSV, Excel and XML.

The following DataSource definition is for a CSV file, which runs the test in a Random order.

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
    "|DataDirectory|\\UserData.csv",
    "UserData#csv",
     DataAccessMethod.Random)), 
DeploymentItem("UserData.csv")]

The following uses the same file but runs the tests in a Sequential order.

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
    "|DataDirectory|\\UserData.csv",
    "UserData#csv",
    DataAccessMethod.Sequential),
DeploymentItem("UserData.csv")]

The following test will execute once for each row (user) found in the CSV file. For this to work be sure the CSV is copied to the output folder.

/// <summary>
/// Given Valid Data Driven Credentials When I Login 
/// I Expect That The Login Window Will Disapear
/// </summary>
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
    "|DataDirectory|\\UserData.csv",
    "UserData#csv",
    DataAccessMethod.Random)]
public void GivenValidDataWhenILoginIExpectThatTheLoginWindowWillDisapear()
{

    string fileName = string.Format(@"{0}LoginWpfApplication.exe", path);
    using (ApplicationUnderTest.Launch(fileName))
    {
      container.UIMap.ClickOnLogin();
      var loginWindow = container.Get<LoginWindowIUMap>();

      string userName = TestContext.DataRow["User"].ToString();
      Keyboard.SendKeys(loginWindow.UILoginWindow.UIUserNameTextboxEdit, userName);
      Keyboard.SendKeysDelay = 10;

      loginWindow.TypeUsername();

      string password = TestContext.DataRow["Password"].ToString();
      loginWindow.TypeUserPasswordParams.UIPasswordTextboxEditText  = password;
      loginWindow.TypeUserPassword();

      loginWindow.ClickLogin();

      UILoginWindow uiLoginWindow = loginWindow.UILoginWindow;

      bool loginWindowNotExit = uiLoginWindow.WaitForControlNotExist(10000);
      Assert.IsTrue(loginWindowNotExit);
    }
}

The data from the DataSource  is accessible through the TestContext.The data items can be retreived from the DataRow by key.

        string userName = TestContext.DataRow["User"].ToString();

Once a value is retrieved, you will need to override the UIMap default value for the specific UI Action as follows.

        loginWindow.TypeUsernameParams.UIUserNameTextboxEditText = userName;

Then call the UI Action to use the newly overridden value.

        loginWindow.TypeUsername();

For masked fields and other special text controls, you can use SendKeys to write into the them. Furthermore, you can adjust the delay between each keystroke.

       Keyboard.SendKeys(loginWindow.UILoginWindow.UIUserNameTextboxEdit, userName);
       Keyboard.SendKeysDelay = 10;

Using the DataSource opens tons of possibilities. Some may be tempted to create more complexes test scenarios which could cover more than a single golden path. I strongly recommend against tests that cover multiple outcomes based on data. They can rapidly become hard to maintain and can easily give false positives. Instead try to create simple tests that test for a single outcome. Doing so will effectively result in more tests, but the true outcome will be tests that do what they say they do. These tests will document requirements that are expected to be implemented and help rapidly spot regressions. 

DataSource Examples


Excel

[DataSource("System.Data.Odbc", 
    "Dsn=Excel Files;" +
    "Driver={Microsoft Excel Driver (*.xls)};" +
    "dbq=|DataDirectory|\\Data.xls;" +
    "defaultdir=.;" +
    "driverid=790;" +
    "maxbuffersize=2048;" +
    "pagetimeout=5;" +
    "readonly=true", 
    "Sheet1$", 
    DataAccessMethod.Sequential)]


Test case in Team Foundation Server

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", 
    "http://vlm13261329:8080/tfs/DefaultCollection;Agile", 
    "30", 
    DataAccessMethod.Sequential)]


XML

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", 
    "|DataDirectory|\\data.xml", 
    "Iterations", 
    DataAccessMethod.Sequential), 
    DeploymentItem("data.xml")]


SQL Express

[DataSource("System.Data.SqlClient", 
    "Data Source=.\\sqlexpress;" +
    "Initial Catalog=tempdb;" +
    "Integrated Security=True", 
    "Data", 
    DataAccessMethod.Sequential)]

No Comments

Be the first to start the conversation!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.