使用数据驱动测试用例与 MBUnit/Gallio 进行并行测试
我一直在使用 Selenium Grid 阅读有关 Selenium 2 的 RemoteWebDriver
的大量内容。目前,我的测试是使用 [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
}
}
这一切都很好很好,但是...如果我想从可以从 XML 反序列化的序列化 TestData 对象加载此测试数据,该怎么办?
我也对使用 RemoteWebDriver
感兴趣,我已经使用过它,但与仅使用 IWebDriver driver = new FireFoxDriver();
相比,它仍然不稳定,但是忽略这些问题,我真的很想多次运行测试用例......同时。这让我想到了并行测试的问题。
我知道 MBUnit 可以处理这个问题,它是 Gallio 的一部分,我也研究过 PUnit,它是 Nunit 的扩展,但它还有很长的路要走。所以我决定坚持使用 MbUnit。
这使我能够使用属性[Parallelizable]
运行TestFixtures。因此,如果我编译我的项目并将项目 dll 加载到 Gallio TestRunner GUI 中,我可以同时运行 4 个测试用例,这反过来又会打开 4 个浏览器同时运行每个测试,同时也提供了对站点进行压力的能力当所有 4 个测试都在运行时。 (显然,这将增加到使用 selenium RemoteWebDriver 和 Selenium Grid 在多台计算机上运行数百个浏览器。
这里有人知道我可以加载 xml 序列化对象集合的方法,生成新的 TestFixture 对象,它可以具有 [Parallelized]
属性添加到测试装置的顶部,并在从 a 加载 1 - 10 个 .xml 文件后让它们同时运行,例如: C:\TestCase 目录?
我的想法是加载所有这些,然后让 Selenium Grid 处理浏览器会话,并运行连接到主 selenium 网格集线器的 1 - 5 个 Selenium 节点
。 Selenium Grid 当我找不到允许我生成 Test Fixture
的框架时,其中包括 [SetUp]
[TearDown]
[Test]
以及根据从 TestCase .xml 文件加载的内容将某些测试条件设置为测试属性的能力。
例如,如果 TestCase .xml 文件有一个失败的元素,那么我如何加载这个 .xml 文件并在我的 TestFixture 的 [Test] 上设置一个属性,或者将 TestCase .xml 测试描述映射到 [Test(Description = "")]
运行时属性。
我已经知道 selenium webdriver 的功能、页面对象设计模式、用于屏幕截图的 selenium 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
}
}
也许我以错误的方式进行这个设计。关于并行化这些的最佳方法有什么建议吗?
I've been doing a lot of reading up on RemoteWebDriver
for Selenium 2 using Selenium Grid. At the moment my tests are generated in the Test()
using the [Test]
Attribute.
I have a TestCriteria
class that I fill with information and then use the Selenium WebDriver 'Page Object Design Pattern' as a way of 'controlling' how this data is entered into my tests.
So, I have a simple criteria object, for example:
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
Then use this information in a LoginPage object.
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
}
}
Now, with this sort of structure I am able to create some good method chaining in my Tests once I have the test data, things like my Credentials object, Data that needs to be filled in on other pages etc.
[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
}
}
This is all well and good, but...what If i wanted to LOAD in this test data from a serialised TestData object which can be deserialised from XML.
I'm also interested in using RemoteWebDriver
, which I have already used however is still flakey compared to using just IWebDriver driver = new FireFoxDriver();
, however ignoring these matters, I would really like to run a TESTCASE more than once...at the same time. Which brings me to the question of parallel testing.
I understand MBUnit can handle this which is part of Gallio, I had also looked into PUnit which is an extension of Nunit but it still has a long way to come. So I have decided to stick with MbUnit.
This gives me the ability to run the TestFixtures with the attribute [Parallelizable]
. So if I compile my project and load in the project dll into Gallio TestRunner GUI I can run 4 test cases at the same time, which in return opens up 4 browsers running each test at the same time, also giving the ability to stress the site while all 4 tests are running. (obviously this would be increased to run several hundred browsers on multiple machines using selenium RemoteWebDriver with Selenium Grid.
Does anyone here know a way where I can load in a collection of xml serialised objects, GENERATE new TestFixture objects which can have the [Parallelizable]
attribute added to the top of the test fixture and have them all run at the same time after loading in 1 - 10 .xml files from a, for example: C:\TestCase directory?
My idea is to have these all loaded in, and then have Selenium Grid handle the browser sessions with 1 - 5 Selenium nodes running connected to the main selenium grid hub.
I am just having a difficulty really taking advantage of Selenium Grid when I can not find a framework which allows me to generate a Test Fixture
, which includes a [SetUp]
[TearDown]
[Test]
and the ability to set certain test conditions to Test Attributes depending on what is loaded from the TestCase .xml file.
For example if a TestCase .xml file had an element which was fail then how can I load this .xml file in and set an attribute on my TestFixture's [Test] for this, or map the TestCase .xml Description of test to the [Test(Description = "")]
attribute at run time.
I already know the functionality of selenium webdriver, the page object design pattern, the selenium EventFiringWebDriver
functionality for screenshots.
How can i utilize the ability to load in several XML serialised TestCaseData, generate new TestFixture objects after these have been loaded?
Ideally I would like the [SetUp] of each TestFixture to setup the IWebDriver
because certain URLs would be different depending on what the TestCase.xml file would contain, for example of this test is to run on a UAT environment, Test environment, Pre-Production environment, I need to set this up before the test is run.
Does anyone have a basic example which uses these main concepts with Selenium Grid/Selenium WebDriver with the ability to run these Test Fixtures in parallel to utilise Selenium Grid functionality of running multiple browsers.
So something I am looking for in pseudo code.
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
}
}
Maybe I am going about this design the wrong way. Any suggestions please on the best way to parallelize these?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这个怎么样?
How about this?
好的解决方案。
但是在不同的浏览器中并行运行测试怎么样?
如果我在 [FixtureSetUp] 中初始化 IWebDriver,则浏览器将打开并运行测试,但出现错误(基本上是 NoSuchElement)。
good solution.
but what about run tests in parallel different browsers?
if I initialize IWebDriver in [FixtureSetUp] then browsers opened and run tests but with errors (basicly NoSuchElement).