Monday, March 14, 2011

Config Files

So for this post, I thought I would cover a pretty common problem people have with Selenium....how to get config files working! In my experience, most selenium coders don't have a developer's background, and may not know how to setup a standard App.config file.

When we compile our visual studio project, we end up getting a .dll we open with nUnit.  This is fine, we open the file, run the tests, and yell at the developers just like normal.  However, what if we want to change something about our tests?  Maybe we want to run them against a different environment, or we want to use a different username and password.  We normally would have to go back into visual studio, change the values, recompile, and run again.

However, nUnit automatically looks for a config file with our dll.  We can use this file to store our paramaters we want to change, and not have to recompile to modify our tests.  We could also have several different config files pre-generated, for different environments, users, browsers, languages, or whatever.   The file is saved as xml, so it is editable in any text editor.

Before we go into the file itself you should know that nUnit looks for a config file with your project name + .config.  So if our project is SeleniumTests.dll, it will look in the same directory for a file named SeleniumTests.dll.config.


So lets get started.  To add the config file, in Visual Studio right click on the project and select "Add New Item", and then select Application Configuration File.  Now that we have the file, we need to add our data into it.  So we want to add a new section called appSettings inside the <configuration> tag.  So it will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
</configuration>

Now, all our variables can be stored inside the appSettings section, as follows:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
    <add key="envUrl" value="http://www.google.com/"/>
    <add key="browser" value="*firefox"/>
</appSettings>
</configuration>

We now have two variables created, one with our environment url, and the other with the browser to launch.

The last step is to be able to access our new variables.  The code itself is simple, however I would recommend creating a "Common" class that contains these global variables, that way all of your tests can access them.  In addition, the use of standard get/set commands allows you to use more complicated logic or setup permissions for your variables.

public static class Common
{
   public static int envUrl{ get ConfigurationManager.AppSettings["envUrl"]; set { envUrl= value; } }
 }

So at this point we have a Common.envUrl variable we can get/set.  We're done, right?  Technically yes, but it can be a pain to have to constantly be updating a config file.  Maybe you need to update five variables depending on what environment you are in.  The quickest way to solve this issue is to set sectionGroups.


In our example, we have added the ability to point our tests to different URL's through the Common.envUrl variable.  However, maybe there are other things that need to change as well when we change environments.  Using groups we can specify subsections to switch between without having to edit/delete values.

We define our sectionGroups in the configSections in our config file, then specify the data for each section later.  In the following example, I am defining a timeout value, and my username/password unique for two different environments.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="Environments">
      <section name="qa" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="prod" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </sectionGroup>
  </configSections>
<Environments>
    <qa>
      <add key="timeout" value="120000"/>
      <add key="userName" value ="testuser1"/>
      <add key="password" value ="password1"/>
  </qa>
    <prod>
      <add key="timeout" value="60000"/>
      <add key="username" value ="produser1"/>
      <add key="password" value ="password2"/>
  </prod>
  </Environments>
</configuration>

We can now get the section and serialize it as a NameValueCollection. 

private static NameValueCollection envSettings = ConfigurationManager.GetSection("Environments") as NameValueCollection;

Now we can access our variables with the envSettings object like this:

envSettings.username, envSettings.password, envSettings.timeout.

No comments:

Post a Comment