【问题标题】:How do I run my NUnit test cases using Selenium to run against different environments?如何使用 Selenium 运行我的 NUnit 测试用例以针对不同的环境运行?
【发布时间】:2013-03-27 21:02:38
【问题描述】:

我使用 Selenium 编写了 NUnit 测试用例来测试 Web 应用程序。我想针对不同的环境(例如 QA、Staging 和生产)运行相同的测试用例,实现这一目标的最简单方法是什么?

【问题讨论】:

  • 一个配置文件?..但是为什么你的环境在 UAT 和生产之间会有本质上的不同呢?

标签: unit-testing selenium nunit


【解决方案1】:

NUnit 支持参数化测试装置以及参数化测试。所以第一件事是,您是要针对不同的环境运行特定的测试,还是要针对两种环境重新运行整个测试夹具?

我问是因为这个问题的答案决定了您将在哪里传递参数(环境)。如果您只想重新运行整个测试夹具,您应该在测试夹具级别传递环境,即创建参数化的测试夹具。如果您只想针对这些环境运行特定测试,则必须将其传递给每个单独的测试用例。下面是一个例子,说明我是如何做同样的事情的:

首先创建一种方法来定义测试可以“附加”到什么“环境”。我建议也许将它推入 app.config 并有一个“设置”类和一个枚举:

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"; } }
}

上面的“一些 url”将从您的配置文件中读取或硬编码,但请随意。

我们现在有了一个环境的概念,它是 URL,但它们没有以任何方式链接在一起或相关。理想情况下,您希望为其提供枚举的“QA”值,然后它会为您整理出 URL。

接下来创建一个基础测试夹具,您的所有测试夹具都可以从该夹具继承,以保持当前环境。我们还创建了一个Dictionary,现在将环境值与它的 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;
    }
}

您可能可以使用反射来计算出哪个 URL 映射到什么 enum 值。

太棒了,我们有一个可以运行的环境。以管理员身份登录您的站点的示例测试:

public class LoginToSite
{
    [Test]
    public void CanAdministratorSeeAdministratorMenu()
    {
        // go to the site
        driver.Navigate().GoToUrl("production site");
        // login as administrator
    }
}

我们如何让它转到特定的 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; }

    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()
            {
            }
}

我们的基类现在可以告诉我们,这取决于我们所处的环境,要转到哪个页面...

所以我们现在有了这个测试,继承自我们的基础:

public class LoginToSite : BaseTestFixture
{
    [Test]
    public void CanAdministratorSeeAdministratorMenu()
    {
        // go to the site
        driver.Navigate().GoToUrl(CurrentEnvironmentURL);
        // login as administrator
    }
}

但是,这很好,但是上面的代码无法编译...为什么?我们实际上还没有给它一个环境,所以我们必须传递一个...

[TestFixture(Environment.QA)]
public class LoginToSite : BaseTestFixture
{
    [Test]
    public void CanAdministratorSeeAdministratorMenu()
    {
        // go to the site
        driver.Navigate().GoToUrl(CurrentEnvironmentURL);
        // login as administrator
    }
}

太好了,它现在已经传入了环境,URL 等的检查现在都在后台为你完成了......但是这个 仍然 不会编译。由于我们使用继承,我们必须有一个构造函数来为我们传递它:

    public LoginToSite(Environment currentEnvironment)
    {
        CurrentEnvironment = currentEnvironment;
    }

等等。

至于具体的测试用例,这个就简单一点,拿我们之前的测试用例:

public class LoginToSite
{
    [TestCase(Environment.QA)]
    public void CanAdministratorSeeAdministratorMenu(Environment environment)
    {
        // go to the site
        driver.Navigate().GoToUrl("production site");
        // login as administrator
    }
}

哪个会在环境中传递到那个特定的测试用例。然后,您将需要一个新的 Settings 类来为您进行环境检查(以与我之前类似的方式):

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));
    }
}

【讨论】:

  • 感谢您的回答。这对我帮助很大。我应该更具体一点。我想为我们的 QA 人员找到一种方法来运行我的回归工具。所以对我来说最好的方法是在每个环境中使用configuration files。所以我在我们的共享文件夹上创建了多个名为“QA”和“Production”的文件夹,然后复制了我的 test.dll 和 test.dll.config。所以他们可以在他们的盒子上安装 NUnit,然后根据他们想要运行回归测试的环境打开基于相应文件夹的 dll。
【解决方案2】:

最好的方法是对所有函数使用变量而不是硬编码链接。以便在需要更改环境时进行更改。一种更简单的方法是从记事本/excel 文件中读取链接。

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多