与单元测试不同,功能测试通常不能自然地隔离,因为每个测试通常在执行前一个测试后需要状态。
例如,要测试实体删除或更新等基本CRUD操作,必须先创建它。虽然我们可以通过将实体创建代码提取到单独的方法来防止代码重复,但是不清楚如何处理重复调用实体创建测试或任何其他依赖测试。随着测试次数的增加,这些重复调用会显着降低时间执行和可读性。
一个直观的解决方案是将所有这些相互依赖的测试合并为一个,但它更难以本地化错误。
到目前为止,我所阅读的信息主要是关于单元测试,我认为它并不完全符合功能/验收,尤其是网页浏览器测试的需求。
具体来说,目前我正在使用JUnit测试,通过Selenium WebDriver API与内存数据库中的webapp交互。
有些人会为这个问题推荐哪些最实用的东西?
答案 0 :(得分:1)
理想情况下,您的AUT将提供在不执行UI的情况下创建数据的功能。 Web服务会很棒,但您可以直接注入数据库(如果可能的话)。
然后,测试设置将通过此“后门”在所需状态下创建数据。
这样做的好处是;
构建器模式可用于抽象数据创建(http://www.natpryce.com/articles/000714.html )。这样就可以使您的测试设置真正具有表现力,并且对于您尝试创建和测试的场景非常明显。
显然,您可能希望E2E测试通过UI证明操作之间的集成,但这可以限制为一小部分,然后使用数据创建处理任何复杂场景或组合测试。
答案 1 :(得分:0)
如何分离重复操作的逻辑(如CRUD)和测试本身的最佳方法是使用Selenium Page Objects,让我向您展示一个示例
public class EntityPage {
private WebDriver driver;
@FindBy(css = "someLocator")
private WebElement someElement
public EntityPage(WebDriver driver) {
this.driver = driver;
}
public void editEntity(Entity entity) {
// some WebDriver code to edit entity
}
public void addEntity(Entity entity) {}
// so and so forth...
}
现在想象一下,每个处理实体的东西都可以创建这个类的实例,并且可以轻松地重复使用所有这些方法进行实体操作。比如像这样
@Test
public void testAddEntity() {
Entity e = new Entity("name");
EntityPage page = PageFactory.initElements(driver, EntityPage.class);
page.addEntity(e);
Assert.assertTtrue(page.isEntityPresent(e));
page.deleteEntity(e);
}
您可以看到测试变得更易读,更易于维护。