问题
I have written NUnit test cases using Selenium to test a web application. And I would like to run the same test cases against different environments (e.g. QA, Staging, & Production) What's the easiest way to achieve that?
回答1:
NUnit supports parametrised test fixtures as well as parametrised tests. So the first thing is that are you going to want to run specific tests against different environments, or is it the entire test fixture will be rerun for both environments?
I ask because the answer to this determines where you will pass the parameter (the environment). If you are just wanting to rerun the whole test fixture, you should pass the environment in at a test fixture level, that is to create parametrised test fixtures. If you want to run only particular tests against those environment, you'll have to pass it in to each individual test case. An example is below of how I've gone about the same sort of thing:
First create a way to define what 'environment' the tests can 'attach' to. I'd suggest perhaps shoving this into the app.config and have a 'Settings' class and an enum to go with it:
public enum Environment
{
QA,
Production,
Hotfix,
Development
}
public class Settings
{
public static string QAUrl { get { return "some url"; } }
public static string ProductionUrl { get { return "some url"; } }
public static string HotfixUrl { get { return "some url"; } }
public static string DevUrl { get { return "some url"; } }
}
The above "some url" would be read from your configuration file or hardcoded, however you please.
We've now got a concept of an environment, and it's URL, but they are not linked together or related in any way. You would ideally want to give it the 'QA' value of your enum and then it will sort out the URL for you.
Next create a base test fixture that all your test fixtures can inherit from, which keeps hold of the current environment. We also create a Dictionary
that now relates the environment value to it's URL:
public class BaseTestFixture
{
private Dictionary<Environment, string> PossibleEnvironments
{
get
{
return new Dictionary<Environment, string>()
{
{ Environment.QA, Settings.QAUrl },
{ Environment.Production, Settings.ProductionUrl },
{ Environment.Hotfix, Settings.HotfixUrl },
{ Environment.Development, Settings.DevelopmentUrl },
}
}
}
private Environment CurrentEnvironment { get; set; }
public BaseTestFixture(Environment environment)
{
CurrentEnvironment = environment;
}
}
You could probably use Reflection to have it work out what URL's map to what enum
value's.
So cool, we've got an environment we can run against. A sample test to go to login as an administrator to your site:
public class LoginToSite
{
[Test]
public void CanAdministratorSeeAdministratorMenu()
{
// go to the site
driver.Navigate().GoToUrl("production site");
// login as administrator
}
}
How do we get this to go to the specific URL? Let's modify our base class a little...
public class BaseTestFixture
{
private Dictionary<Environment, string> PossibleEnvironments
{
get
{
return new Dictionary<Environment, string>()
{
{ Environment.QA, Settings.QAUrl },
{ Environment.Production, Settings.ProductionUrl },
{ Environment.Hotfix, Settings.HotfixUrl },
{ Environment.Development, Settings.DevelopmentUrl },
}
}
}
private Environment CurrentEnvironment { get; set; }
protected string CurrentEnvironmentURL
{
get
{
string url;
if (PossibleEnviroments.TryGetValue(CurrentEnviroment, out url))
{
return url;
}
throw new InvalidOperationException(string.Format("The current environment ({0}) is not valid or does not have a mapped URL!", CurrentEnviroment));
}
}
public BaseTestFixture(Environment environment)
{
CurrentEnvironment = environment;
}
public BaseTestFixture()
{
}
}
Our base class now can tell us, depending on what environment we are in, what page to go to...
So we now have this test, inheriting from our base:
public class LoginToSite : BaseTestFixture
{
[Test]
public void CanAdministratorSeeAdministratorMenu()
{
// go to the site
driver.Navigate().GoToUrl(CurrentEnvironmentURL);
// login as administrator
}
}
However, that's great, but the above won't compile...why? We are not actually giving it an environment yet so we must pass one in...
[TestFixture(Environment.QA)]
public class LoginToSite : BaseTestFixture
{
[Test]
public void CanAdministratorSeeAdministratorMenu()
{
// go to the site
driver.Navigate().GoToUrl(CurrentEnvironmentURL);
// login as administrator
}
}
That's great, it now has the environment passed in, the checking of the URL etc are all done in the background for you now...however this still won't compile. Since we are using inheritance, we have to have a constructor to pass it down for us:
public LoginToSite(Environment currentEnvironment)
{
CurrentEnvironment = currentEnvironment;
}
Et voilà.
As for specific test cases, this is a little easier, taking our test case from earlier:
public class LoginToSite
{
[TestCase(Environment.QA)]
public void CanAdministratorSeeAdministratorMenu(Environment environment)
{
// go to the site
driver.Navigate().GoToUrl("production site");
// login as administrator
}
}
Which would pass in the environment into that specific test case. You would then need a new Settings
class of some sort, to do the environment checking for you (in a similar way as I did before):
public class EnvironmentHelper
{
private static Dictionary<Environment, string> PossibleEnvironments
{
get
{
return new Dictionary<Environment, string>()
{
{ Environment.QA, Settings.QAUrl },
{ Environment.Production, Settings.ProductionUrl },
{ Environment.Hotfix, Settings.HotfixUrl },
{ Environment.Development, Settings.DevelopmentUrl },
}
}
}
public static string GetURL(Environment environment)
{
string url;
if (PossibleEnviroments.TryGetValue(environment, out url))
{
return url;
}
throw new InvalidOperationException(string.Format("The current environment ({0}) is not valid or does not have a mapped URL!", environment));
}
}
回答2:
Best way would be to use variables instead of hard coded links for all functions. So that it can be changed when needed to change the environment. An easier approach would be to read links from a notepad/excel file .
来源:https://stackoverflow.com/questions/15649819/how-do-i-run-my-nunit-test-cases-using-selenium-to-run-against-different-environ