How To: Get same test running under different environments

A while back, I got following question from a user of Coded UI Test 

We want to run the same test across multiple environments to ensure everything is still working correctly.

Dev-> Test -> UAT -> STAGE

We want to run these tests after each deploy to each environment. Each environment has as a different URL, username and password.

How can I achieve this without changing the recording or code everytime?

Well, there are number of different ways to achieve this.  One is to use environment variables to parameterize the playback code.  Let us take an example – my test is to login to Hotmail. Here I want to parameterize 3 variables – the Hotmail server, the username and the password.  I can do so by adding something like the code below to UIMap.cs file.

 public UIMap()
{
    // Bind the parameters using Environment Variables.
    string testServer =
        Environment.GetEnvironmentVariable("TestServer");
    string testUserName =
        Environment.GetEnvironmentVariable("TestUserName");
    string testUserPassword =
        Environment.GetEnvironmentVariable("TestUserPassword");

    if (!string.IsNullOrEmpty(testServer))
    {
        // Change only the server name part of the URL as
        // rest is independent of the environment.
        UriBuilder urlBuilder =
            new UriBuilder(this.LoginToHotmailParams.Url);
        urlBuilder.Host = testServer;
        this.LoginToHotmailParams.Url = urlBuilder.Uri.ToString();
    }

    if (!string.IsNullOrEmpty(testUserName))
    {
        this.LoginToHotmailParams.UIWindowsLiveIDEditText =
            testUserName;
    }

    if (!string.IsNullOrEmpty(testUserPassword))
    {
        // Password is always encrypted by the recorder.
        // So encrypt the clear text password before setting.
        this.LoginToHotmailParams.UIPasswordEditPassword =
            Playback.EncryptText(testUserPassword);
    }
}

Generally, only the server name part of the URL changes across environments and hence I have used just that to parameterize.

For password, you could have clear text & set it via Playback.EncryptText() API shown above OR, you could have encrypted password and use it directly.  For encryption you can write separate program that gives you encrypted one from clear text using the Playback.EncryptText() API. Note that how secure encrypted password is depends on the key used for encryption.  The encryption key can be set using Playback.PlaybackSettings.SetEncryptionKeyLocation() API.  If you don’t call this API, the default key is used which makes encryption not really unbreakable.  Most users are typically ok with using default encryption key because these are test accounts and “everybody already know the password”.  However, if you really want to ensure that the test account password is protected, use different encryption key that is placed on a network share and the access to the network share is controlled via Windows.