我一直在使用Selenium Grid对RemoteWebDriver
的Selenium 2进行大量阅读。目前,我的测试是使用Test()
属性在[Test]
中生成的。
我有一个TestCriteria
类,我填写了信息,然后使用Selenium WebDriver“页面对象设计模式”作为“控制”如何将这些数据输入我的测试的方式。
所以,我有一个简单的标准对象,例如:
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
然后在LoginPage对象中使用此信息。
public class LoginPage
{
[FindsByAnnotation]
public IWebElement UsernameField { get; set; }
[FindsByAnnotation]
public IWebelement PasswordField { get; set; }
[FindsByAnnotation]
public IWebelement SubmitButton { get; set; }
public HomePage Login(Credentials cred)
{
UsernameField.SendKeys(cred.user);
// code for login and return new HomePage object
}
}
现在,通过这种结构,我可以在测试数据中创建一些好的方法链接,例如我的凭据对象,需要在其他页面上填写的数据等。
[TestFixture]
public class TestFixture
{
private IWebDriver driver;
private TestCaseData data; // Which contains a Credentials object etc etc
[SetUp]
public void SetUp()
{
data = new TestCaseData()
{
Credentials = new Credentials()
{
Username = "username",
Password = "password"
}
// Other test case data objects can be populated here
};
driver = new FireFoxDriver();
}
[Test]
public void Test()
{
new LoginPage().Login(data.Credentials)
.NavigateToSearchPage()
.EnterSearchCriteria(data.SearchCritiera)
// etc
}
}
这一切都很好,但是......如果我想从序列化的TestData对象中加载这个测试数据,可以从XML反序列化。
我也对使用RemoteWebDriver
感兴趣,我已经使用了IWebDriver driver = new FireFoxDriver();
,但与仅使用[Parallelizable]
相比仍然很好,但是忽略了这些问题,我真的想运行TESTCASE而不是一次......同时。这让我想到了并行测试的问题。
我理解MBUnit可以处理这是Gallio的一部分,我也研究了PUnit这是Nunit的扩展,但它还有很长的路要走。所以我决定坚持使用MbUnit。
这使我能够使用属性[Parallelizable]
运行TestFixtures。因此,如果我编译我的项目并将项目dll加载到Gallio TestRunner GUI中,我可以同时运行4个测试用例,这反过来又会打开4个浏览器同时运行每个测试,同时也能够强调网站所有4个测试都在运行。 (显然,使用Selenium RemoteWebDriver和Selenium Grid在多台机器上运行数百个浏览器会增加这一点。
这里有没有人知道我可以加载一个xml序列化对象的集合,生成新的TestFixture对象,这些对象可以将Test Fixture
属性添加到测试夹具的顶部并让它们全部运行在从例如:C:\ TestCase目录加载1 - 10 .xml文件后的同一时间?
我的想法是将所有这些全部加载,然后让Selenium Grid处理浏览器会话,其中1-5个Selenium节点连接到主要的selenium网格集线器。
当我找不到允许我生成[SetUp]
的框架时,我真的很难利用Selenium Grid,其中包括[TearDown]
[Test]
{{1并且能够根据从TestCase .xml文件加载的内容为测试属性设置某些测试条件。
例如,如果TestCase .xml文件有一个失败的元素,那么我如何加载这个.xml文件并在我的TestFixture的[Test]上设置一个属性,或者将TestCase .xml测试描述映射到运行时的[Test(Description = "")]
属性。
我已经知道selenium webdriver的功能,页面对象设计模式,截图的硒EventFiringWebDriver
功能。
如何利用加载多个XML序列化TestCaseData的能力,在加载这些对象后生成新的TestFixture对象?
理想情况下,我希望每个TestFixture的[SetUp]设置IWebDriver
,因为某些URL会有所不同,具体取决于TestCase.xml文件将包含的内容,例如此测试将在UAT上运行环境,测试环境,预生产环境,我需要在测试运行之前进行设置。
有没有人有一个基本的例子,它使用Selenium Grid / Selenium WebDriver的这些主要概念,能够并行运行这些测试夹具,以利用运行多个浏览器的Selenium Grid功能。
所以我正在寻找伪代码。
public class Main()
{
// Load Testfixtures
List<TestCase> testCases = Deserialise("\\Some\\FolderLocation");
foreach(test in testCases)
{
// create NEW testFixture, not [Test]
// ability to attach parallel TestFixture
}
}
[Testfixture]
[Parallelizable]
public class TestFixture
{
public TestCase testCase { get; set; }
public IWebDriver driver { get; set; }
[SetUp]
public void SetUp()
{
if(testCase.Environment == "UAT")
{
driver = new FireFoxDrive()
driver.NavigateTo("http://localhost/uat/Login");
}
// What if the testCase.ShouldPass is false?
// How can i generate my [Test] with ExpectedException?
}
[Test]
public void Test()
{
// code here with page object method chaining passing in testCase data objects
}
}
也许我会以错误的方式进行这种设计。请问有关并行化这些问题的最佳方法吗?
答案 0 :(得分:1)
这个怎么样?
public class TestCase
{
public string Name { get; set; }
}
public static class TestCaseFactory
{
public static IEnumerable<TestCase> TestCases()
{
yield return new TestCase { Name = "one" };
yield return new TestCase { Name = "two" };
}
}
[Factory(typeof(TestCaseFactory), "TestCases"), Parallelizable]
public class DataDrivenFixture
{
private readonly TestCase testCase;
public DataDrivenFixture(TestCase testCase)
{
this.testCase = testCase;
}
[SetUp]
public void SetUp()
{
Console.WriteLine("SetUp " + testCase.Name);
}
[Test]
public void Test()
{
Console.WriteLine("Test " + testCase.Name);
}
}
答案 1 :(得分:0)
public static IEnumerable<TestCase> TestCases()
{
yield return new TestCase { Name = "internet explorer" };
yield return new TestCase { Name = "firefox" };
}
[FixtureSetUp]
public void SetUp()
{
Console.WriteLine("SetUp " + testCase.Name);
switch (testCase.Name)
{
case "internet explorer":
driver = new InternetExplorerDriver();
break;
case "chrome":
driver = new ChromeDriver();
break;
case "firefox":
driver = new FirefoxDriver();
break;
}
}