使用 MSTEST 在多个浏览器上运行 selenium

发布于 2024-12-02 20:17:59 字数 258 浏览 1 评论 0原文

我使用 selenium 并使用 mstest 来驱动它。我的问题是我希望我的整个套件能够在 3 种不同的浏览器(IE、Firefox 和 Chrome)上运行。

我不明白的是如何在套件级别上数据驱动我的测试或如何使用不同的参数重新运行套件。

我知道我可以向所有测试添加一个数据源,并针对多个浏览器运行单独的测试,但随后我必须为每个测试复制数据源的两行,我认为这不是很好的解决方案。

那么有人知道我如何数据驱动我的程序集初始化吗?或者是否有其他解决方案。

Im using selenium and using mstest to drive it. My problem is i want my entire suite to run against 3 different browsers(IE,Firefox and chrome).

What i can't figure out is how to data drive my test on a suite level or how to rerun the suite with different paramateres.

I know i can add a datasource to all my tests and have the individual test run against multiple browsers but then i would have to duplicate the 2 lines for the datasource for every single test which i don't think is very good solution.

So anybody knows how i can data drive my assembly initialize? or if there's another solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉酒的小男人 2024-12-09 20:17:59

这就是我所做的。这种方法的好处是它适用于任何测试框架(mstest、nunit 等),并且测试本身不需要关心或了解有关浏览器的任何信息。您只需确保方法名称仅在继承层次结构中出现一次。我已经使用这种方法进行了数百次测试,它对我很有效。

  1. 让所有测试继承基测试类(例如BaseTest)。
  2. BaseTest 将所有驱动程序对象(IE、FireFox、Chrome)保存在一个数组中(在下面的示例中为 multiDriverList)。
  3. BaseTest中有以下方法:

    public void RunBrowserTest( [CallerMemberName] string methodName = null )
    {              
        foreach( IDriverWrapper driverWrapper in multiDriverList ) //浏览器驱动程序列表 - Firefox、Chrome 等。您需要实现此功能。
        {
            var testMethods = GetAllPrivateMethods( this.GetType() );
            MethodInfo dynMethod = testMethods.Where(
                    TM=> ( FormatReflectionName( tm.Name ) == 方法名 ) &&
                      ( FormatReflectionName( tm.DeclaringType.Name ) == declaringType ) &&
                      ( tm.GetParameters().Where( pm => pm.GetType() == typeof( IWebDriver ) ) != null ) ).Single();
            //运行具有相同名称的私有方法,但采用单个 IWebDriver 参数
            dynMethod.Invoke( this, new object[] { driverWrapper.WebDriver } ); 
        }
    } 
    
    //helper方法获取层次结构中的所有私有方法,在上面的方法中使用
    私有 MethodInfo[] GetAllPrivateMethods( 类型 t )
    {
        var testMethods = t.GetMethods( BindingFlags.NonPublic | BindingFlags.Instance );
        if( t.BaseType != null )
        {
            var baseTestMethods = GetAllPrivateMethods( t.BaseType );
            testMethods = testMethods.Concat( baseTestMethods ).ToArray();
        }
        返回测试方法;
    }
    
    //从通用方法中删除格式
    字符串 FormatReflectionName( 字符串 nameIn )
    {            
        return Regex.Replace( nameIn, "(`.+)", match => "" );
    }
    
  4. 使用方法如下:

    <前><代码>[测试方法]
    公共无效RunSomeKindOfTest()
    {
    运行浏览器测试(); //在基类中调用上面步骤3中的方法
    }
    私有无效 RunSomeKindOfTest( IWebDriver 驱动程序)
    {
    //测试。每个浏览器都会调用此方法,在每种情况下传递适当的驱动程序
    ...
    }

This is what I did. The benefit of this approach is that it will work for any test framework (mstest, nunit, etc) and the tests themselves don't need to be concerned with or know anything about browsers. You just need to make sure that the method name only occurs in the inheritance hierarchy once. I have used this approach for hundreds of tests and it works for me.

  1. Have all tests inherit from a base test class (e.g. BaseTest).
  2. BaseTest keeps all driver objects (IE, FireFox, Chrome) in an array (multiDriverList in my example below).
  3. Have the following methods in BaseTest:

    public void RunBrowserTest( [CallerMemberName] string methodName = null )
    {              
        foreach( IDriverWrapper driverWrapper in multiDriverList ) //list of browser drivers - Firefox, Chrome, etc. You will need to implement this.
        {
            var testMethods = GetAllPrivateMethods( this.GetType() );
            MethodInfo dynMethod = testMethods.Where(
                    tm => ( FormatReflectionName( tm.Name ) == methodName ) &&
                      ( FormatReflectionName( tm.DeclaringType.Name ) == declaringType ) &&
                      ( tm.GetParameters().Where( pm => pm.GetType() == typeof( IWebDriver ) ) != null ) ).Single();
            //runs the private method that has the same name, but taking a single IWebDriver argument
            dynMethod.Invoke( this, new object[] { driverWrapper.WebDriver } ); 
        }
    } 
    
    //helper method to get all private methods in hierarchy, used in above method
    private MethodInfo[] GetAllPrivateMethods( Type t )
    {
        var testMethods = t.GetMethods( BindingFlags.NonPublic | BindingFlags.Instance );
        if( t.BaseType != null )
        {
            var baseTestMethods = GetAllPrivateMethods( t.BaseType );
            testMethods = testMethods.Concat( baseTestMethods ).ToArray();
        }
        return testMethods;
    }
    
    //Remove formatting from Generic methods
    string FormatReflectionName( string nameIn )
    {            
        return Regex.Replace( nameIn, "(`.+)", match => "" );
    }
    
  4. Use as follows:

    [TestMethod]
    public void RunSomeKindOfTest()
    {
        RunBrowserTest(); //calls method in step 3 above in the base class
    }
    private void RunSomeKindOfTest( IWebDriver driver )
    {
        //The test. This will be called for each browser passing in the appropriate driver in each case
        ...            
    }     
    
爱人如己 2024-12-09 20:17:59

为此,我们编写了一个围绕 webdriver 的包装器,并使用基于属性的 switch 语句来选择浏览器类型。

这是一个片段。使用 DesiredCapability,您可以告诉网格要针对哪些浏览器执行。

switch (Controller.Instance.Browser)
            {
                case BrowserType.Explorer:
                    var capabilities = DesiredCapabilities.InternetExplorer();
                    capabilities.SetCapability("ignoreProtectedModeSettings", true);
                    Driver = new ScreenShotRemoteWebDriver(new Uri(uri), capabilities, _commandTimeout);
                    break;
                case BrowserType.Chrome:
                    Driver = new ScreenShotRemoteWebDriver(new Uri(uri), DesiredCapabilities.Chrome(), _commandTimeout);
                    break;
            }

To do this, we wrote a wrapper around webdriver and we use a switch statement based on a property to select the browser type.

Here's a snippet. Using the DesiredCapabilities, you can tell grid which browsers to execute against.

switch (Controller.Instance.Browser)
            {
                case BrowserType.Explorer:
                    var capabilities = DesiredCapabilities.InternetExplorer();
                    capabilities.SetCapability("ignoreProtectedModeSettings", true);
                    Driver = new ScreenShotRemoteWebDriver(new Uri(uri), capabilities, _commandTimeout);
                    break;
                case BrowserType.Chrome:
                    Driver = new ScreenShotRemoteWebDriver(new Uri(uri), DesiredCapabilities.Chrome(), _commandTimeout);
                    break;
            }
神妖 2024-12-09 20:17:59

这个想法更适合自动化 CI 场景而不是交互式 UI,但您可以使用 runsettings 文件并声明一个参数:

<?xml version='1.0' encoding='utf-8'?>
<RunSettings>
    <TestRunParameters>
        <Parameter name="SELENIUM_BROWSER" value="Firefox" />
    </TestRunParameters>
</RunSettings>

您的测试类上需要一个 TestContext

public TestContext TestContext { get; set; }

然后在 MSTest 中,当您初始化驱动程序时,您可以检查您要运行哪个浏览器

switch (TestContext.Properties["SELENIUM_BROWSER"]?.ToString())
{
    case BrowserType.Chrome:
        return new ChromeDriver();
    case BrowserType.Edge:
        return new EdgeDriver();
    case BrowserType.Firefox:
        return new FirefoxDriver();
}

然后您将运行测试套件 n 次,每个运行设置文件运行一次

This idea is better for an automated CI scenario rather than interactive UI, but you can use a runsettings file and declare a parameter in that:

<?xml version='1.0' encoding='utf-8'?>
<RunSettings>
    <TestRunParameters>
        <Parameter name="SELENIUM_BROWSER" value="Firefox" />
    </TestRunParameters>
</RunSettings>

You'll need a TestContext on your Test class

public TestContext TestContext { get; set; }

Then in your MSTest when you initialise the Driver you can check which browser you want to run

switch (TestContext.Properties["SELENIUM_BROWSER"]?.ToString())
{
    case BrowserType.Chrome:
        return new ChromeDriver();
    case BrowserType.Edge:
        return new EdgeDriver();
    case BrowserType.Firefox:
        return new FirefoxDriver();
}

You would then run the suite of tests n times, once for each runsettings file

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文