【问题标题】:Running selenium against multiple browsers with MSTEST使用 MSTEST 对多个浏览器运行 selenium
【发布时间】:2011-11-10 11:00:00
【问题描述】:
我正在使用 selenium 并使用 mstest 来驱动它。我的问题是我希望我的整个套件能够针对 3 种不同的浏览器(IE、Firefox 和 chrome)运行。
我想不通的是如何在套件级别上驱动我的测试,或者如何使用不同的参数重新运行套件。
我知道我可以将数据源添加到我的所有测试中,并针对多个浏览器运行单独的测试,但是我必须为每个测试复制数据源的 2 行,我认为这不是很好的解决方案.
所以有人知道我如何通过数据驱动我的程序集初始化吗?或者是否有其他解决方案。
【问题讨论】:
标签:
selenium
mstest
webdriver
【解决方案1】:
这就是我所做的。这种方法的好处是它适用于任何测试框架(mstest、nunit 等),并且测试本身不需要关心或了解有关浏览器的任何信息。您只需要确保方法名称仅在继承层次结构中出现一次。我已经用这种方法进行了数百次测试,它对我很有效。
- 让所有测试都继承自基础测试类(例如 BaseTest)。
- BaseTest 将所有驱动程序对象(IE、FireFox、Chrome)保存在一个数组中(下面我的示例中的 multiDriverList)。
-
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 => "" );
}
-
如下使用:
[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
...
}
【解决方案2】:
为此,我们为 webdriver 编写了一个包装器,并使用基于属性的 switch 语句来选择浏览器类型。
这是一个sn-p。使用 DesiredCapabilities,您可以告诉网格要针对哪些浏览器执行。
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;
}
【解决方案3】:
这个想法更适合自动化 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 次,每个运行设置文件一次