Help us learn about your current experience with the documentation. Take the survey.

编写端到端测试的风格指南

本文档描述了在 GitLab 中使用 GitLab QA 项目编写端到端(E2E)测试时使用的约定。

本指南是对主要测试标准和风格指南的扩展。如果本指南定义的规则与主要指南相矛盾,则以本指南为准。

click_go_to_ 的选择

何时使用 click_

当选择单个链接进行导航时,使用 click_

例如:

def click_add_badge_button
  click_element 'add-badge-button'
end

从测试的角度来看,如果我们想检查选择链接或按钮(单个交互)是否按预期工作,我们希望测试的读取方式为:

  • 选择特定元素
  • 验证操作已执行

何时使用 go_to_

当与多个元素交互以进入页面时,使用 go_to_

例如:

def go_to_applications
  click_element('nav-item-link', submenu_item: 'Applications')
end

go_to_ 非常符合与多个元素交互的定义,因为它更像是一个包含多个交互的元导航操作。

注意,在上面的例子中,在选择 'nav-item-link' 之前,另一个元素被悬停。

我们可以创建这些方法作为辅助方法来抽象多步导航。

元素命名约定

向页面添加新元素时,拥有一致的元素命名约定非常重要。

我们遵循一个基于匈牙利表示法的大致简单公式。

公式: element :<描述符>_<类型>

  • 描述符: 对元素的自然语言描述。在登录页面上,这可能是 usernamepassword
  • 类型: 页面上用户可以看到的通用控件。
    • -button
    • -checkbox
    • -container: 包含其他元素但不呈现可见内容本身的元素。例如,一个包含第三方编辑器的元素,但它本身不是编辑器,因此不包含编辑器的内容。
    • -content: 包含向用户显示的文本、图像或任何其他内容的任何元素。
    • -dropdown
    • -field: 文本输入元素。
    • -link
    • -modal: 弹出模态对话框,例如确认提示。
    • -placeholder: 内容加载时出现的临时元素。例如,在获取讨论时显示的替代讨论的元素。
    • -radio
    • -tab
    • -menu_item

如果列出的类型都不合适,请打开合并请求以向列表添加适当的类型。

示例

正确

view '...' do
  element 'edit-button'
  element 'notes-tab'
  element 'squash-checkbox'
  element 'username-field'
  element 'issue-title-content'
end

错误

view '...' do
  # `'-confirmation'` 应该是 `'-field'`。是什么类型的确认?复选框确认?没有真正的方法来消除歧义。
  # 适当的替代方案是 `element 'password-confirmation-field'`
  element 'password-confirmation'

  # `'clone-options'` 太模糊。如果它是下拉菜单,应该是 `'clone-dropdown'`。
  # 如果它是复选框,应该是 `'clone-checkbox'`
  element 'clone-options'

  # 这个 url 是如何显示的?是文本框?还是简单的 span?
  # 如果它是页面上的内容,应该是 `'ssh-clone-url-content'`
  element 'ssh-clone-url'
end

块参数命名

为了在使用 .perform 方法时对页面和资源的命名有标准,我们使用 snake_case(全小写,单词用下划线分隔)形式的页面对象名称。请参见下面的好坏示例。

虽然我们大多数情况下倾向于遵循标准,但如果名称不明确,使用常用缩写(例如 mr)或其他替代方案也是可以接受的。这可以包括附加 _page,如果它有助于避免混淆或使代码更具可读性。例如,如果页面对象名为 New,将块参数命名为 new 可能会造成混淆,因为该名称用于实例化对象,因此 new_page 是可接受的。

我们选择不使用 page,因为它会遮蔽 Capybara DSL,可能导致混淆和错误。

示例

正确

Page::Project::Members.perform do |members|
  members.do_something
end
Resource::MergeRequest.fabricate! do |merge_request|
  merge_request.do_something_else
end
Resource::MergeRequest.fabricate! do |mr|
  mr.do_something_else
end
Page::Project::New.perform do |new_page|
  new_page.do_something
end

错误

Page::Project::Members.perform do |project_settings_members_page|
  project_settings_members_page.do_something
end
Page::Project::New.perform do |page|
  page.do_something
end

除了拥有标准化的优势外,遵循这个标准还能让我们编写更简短的代码行。