使用Test Automation Page Object Model,我们将页面链接在一起,如下所示:
WebDriver driver = new WebDriver()
HomePage homePage = new HomePage(driver);
LoginPage loginPage = homePage.GoToLoginPage();
WelcomePage welcomePage = loginPage.Login();
etc
etc
这样做的最大好处是,如果开发人员更改主页,使其不再链接到登录页面,我可以更新我的主页类,并在运行测试之前查看我需要更新的所有测试(有错误)。
然而,对于小黄瓜,上面的每一行将形成一个单独的“步骤”,因此是一个单独的方法。因此,如何进行这种连接?
是将页面对象类的实例(例如homePage,loginPage等)放入交叉小黄木语句持久存储(例如像specflow POCO或'World')的唯一方法吗?
好的,所以已经问过无数开发和测试自动化专家,似乎解决方案是继续链接[e.g. WelcomePage welcomePage = loginPage.loginWithValidUser(validUser)]
是要走的路。
要跨步骤保持页面对象的实例(例如上面的示例中的welcomePage),您可以使用依赖注入工具(在Ruby的黄瓜实现中创建类似于World扩展的功能)。
这里有更多信息:https://cukes.info/docs/reference/java-di
但是,大多数项目都将受益于依赖注入模块,以便更好地组织代码并在步骤定义之间共享状态。
更多信息来自SpecFlow(.net官方黄瓜实现):
http://specflow.org/getting-started/beyond-the-basics/
最后,我在这个领域创建了一个可以帮助人们的整个博客,因为小黄瓜/页面对象交互是我非常感兴趣的主题:
http://www.seligmanventures.com/dev-blog/test-automation-page-object-model-with-gherkin
对于大多数网站(可以使用url),在我看来,最好的做法是简单地使用url而不是动作来获取相同的url。
例如:
# Suggested by OP:
driver = Selenium::Webdriver.for :chrome, prefs: prefs
homepage = Homepage.new(driver)
login = homepage.go_to_login
welcome = login.log_in_as('dave4429')
# My Suggestion:
homepage = Url.new('/')
login = Url.new('/login')
welcome = Url.new('/welcome')
这意味着您从网址开始,而不是必须从主页开始每次测试。您仍然可以使用您建议的方法,但它们将在其他区域中使用,以确保用户可以通过除URL之外的其他方式访问该页面。
但是,这不是一站式解决方案。对于移动和桌面应用程序,您唯一的选择可能是通过主屏幕,在这种情况下,您建议的方法绝对是您的选择。
“页面对象本身不应该进行验证或断言。这是测试的一部分,应该始终在测试代码中,而不是在页面对象中。” - Selenium HQ
我给出的示例是一个非常基本的示例,我很可能将它们包装到模块和类中,以实现这样的编码:
google = Project::Pages::Google.new
google.search_for('Hello, World!')
expect(google.found_result?).to_equal(true)
编辑
除此之外,您似乎对Cucumber如何与Gherkin合作存在误解。
每步可以有多行代码,因为步骤本身就是步骤中操作的描述。
例如:
Given I am logged in as "dave4429"
When I have submitted the "Contact Us" form with the following data:
| [email protected] | David McBlaine | I want to find out more about your Data Protection services, can I talk to a staff member or get a PDF? |
Then an email should be sent to "[email protected]" with the details specified
“When”的定义可能如下所示:
When(/^I have submitted the "Contact Us" form with the following data:$/) do |table|
rows = table.raw
row = rows[0]
contact_us.fill_form({email: row[0], username: row[1], message: row[2]})
contact_us.submit_message
expect(browser.title).to_equal("Message Sent!")
end
这一切都取决于你在定义中分解了多少步骤。
编辑#2
我也很清楚你想要进行方法链接,这是contact_us.fill_form({email: row[0], username: row[1], message: row[2]}).submit_message
的方式,在使用我建议的技术时,这一点并不是不可能的,但是这个链接是否适用于每个页面,或者是否所有内容都应包含在一个类或模块中,只能根据您的需要来回答。
我只是认为这会对单个类产生过多影响,并且分解该类将允许对测试人员进行更多控制,并且将编写更少的冗余代码。
经过对此主题的大量讨论后,同样合理的替代方案是在使用带有小黄瓜的页面对象模式时不返回新页面的实例。您将失去通常使用POM链接的好处,但代码可以更好地阅读并且不那么复杂。发布这个替代答案,作为测试社区,我们可以投票选择哪种方法是人们的偏好。