适当的功能/验收测试结构

时间:2012-05-10 15:05:08

标签: selenium structure functional-testing acceptance-testing jboss-arquillian

我目前正在为一个项目构建一个自动化的功能/验收测试套件,但是我没有很多编写这些类型测试的经验,所以我想得到一些正确构建它们的输入。具体来说,我正在使用Arquillian的Graphene扩展。

例如,假设我有3个测试,A,B和C.

TestA :测试登录应用程序中的帐户。因此,如果测试成功,浏览器应该在帐户的主页/信息页面上。

TestB :测试修改帐户的密码。这需要登录帐户,然后测试密码更改功能。

TestC :测试修改帐户的电子邮件。这将再次需要登录帐户,然后测试电子邮件更改功能。

如果TestA由于登录代码问题而失败,显然TestB和TestC也会失败,因为它们需要登录到帐户。

问题:自动功能/验收测试是否应该复制完成测试验证所必需的过程?在这种情况下,TestB和TestC需要在执行任何其他操作之前登录该帐户。每个测试应该明确地调用类似的东西:

/* ...initial test setup code here */
LoginPage.login(username, password);
assertTrue(onCorrectAccountPage);
AccountModification.changePassword(newPassword);

或者我应该使用某种方法将一个帐户模拟到可以由测试B和C使用的会话中,这样即使TestA(实际的登录测试)也不会失败?

由于这些是用户验收测试,我的想法是他们应该完全按照用户的方式进行操作并在必要时登录,但我不确定这是否是应该以不同方式处理的不必要的重复(即,处理像功能单元,类似于标准单元测试),我希望从这个领域有更多经验的人那里获得反馈。

提前致谢。希望我的问题不是太复杂。 :)

3 个答案:

答案 0 :(得分:4)

我个人已经这样做了,以便每个测试用例尽可能地复制用户操作,但是切掉需要的地方。例如,TestA:登录,转到正确的网站,转到它的管理系统,找到用户,并删除部分用户信息(如姓名),TestB:登录,转到正确的网站,转到它是管理系统,找到一个用户,并试图通过一个按钮完全删除用户。

TestA和TestB最终出现在同一页面 - 用户详细信息页面上。因此,在测试A中,我可以正确地完成所有操作,确切地说是用户如何操作,但在测试B中,我直接转到该用户的详细信息页面,而不是手动执行正确的导航。为什么呢?

节省时间,当测试A已经测试过时,我为什么要在测试B中重新进行导航?

请记住,测试不应相互依赖 - 如果所有三个测试都因为您无法登录而失败 - 这就是重点,您无法登录,因此您无法执行任何其他操作。

将其视为用户愿意。每个测试都有自己正在测试的用户可查看的功能,但如果您无法登录,则用户无法看到任何此类功能或对功能执行任何操作。如果我无法登录,我无法更改我的密码或电子邮件 - 所以逻辑上测试应该以同样的方式失败。

答案 1 :(得分:3)

这实际上是一个每个项目的问题,因为两者都是有效的方法,但在不同的情况下,应该更优先考虑。在一个大系统中,我更喜欢从开始到结束运行测试用例,无论重复步骤的频率如何(例如,我为每个测试登录)。我相信这就是Arran已经说过的话(+1!)。我通常这样做的原因是因为有时从前一个屏幕继承的状态可能会在以后导致错误,这就是自动化测试非常适合查找的事情。但是,通过这些,我确保测试数据对于引导步骤都是有效的,并且可以实现最快的解决方案。例如,登录应始终具有正确的用户和密码,然后在检查登录成功时,或者只是假设它应该稍后处理异常或者在页面上搜索易于识别的元素而不是复杂的“更重要”元素。

话虽如此,您还可以编写在一系列功能流中测试多个需求的测试。如果应该编写流程中断测试,则应确定整个任务失败的区域。我只建议小项目,或者由于缺乏资源,测试不是优先考虑。例如,运行登录的测试,选择一个项目,将其放入购物车,转到结账,付费将测试所有这些功能,并允许团队修复总体“过程”而不仅仅是几个,可能会断开连接,虫子。但是,我认为第一种方法更彻底但也需要更多时间(但值得经常这样做:))。

担心我的回答会变得太长而且阻碍 - 我不会在这里进一步探讨这个问题,但在这方面还有很多值得讨论的问题,我建议坐下来抽出你的意思尝试在应用程序中测试,无论是现在还是将来。这可能会非常具有启发性,并鼓励良好的测试结构和自动编写实践。希望这会有所帮助并且不会太长:)

答案 2 :(得分:1)

用户接受测试中,您不想模拟,但要尽可能接近最终用户使用系统的方式。

但是,单元测试口号one assert per test可以扩展到验收测试: 在TestA中,您的验证逻辑是关于断言正确登录:在TestB中,您不需要重复此验证,断言密码修改已正确处理。

在JUnit中,可以使用assumeTrue代替assertTrue。所以你的TestB会变成:

/* ...initial test setup code here */
LoginPage.login(username, password);
assumeTrue(onCorrectAccountPage);
AccountModification.changePassword(newPassword);

现在,如果assumeTrue失败,则会忽略测试。但是,您的TestA仍然会失败,告诉您和您的最终用户真正的问题是什么。