# Style guide for writing end-to-end tests

> 原文：[https://docs.gitlab.com/ee/development/testing_guide/end_to_end/style_guide.html](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/style_guide.html)

*   [`click_` versus `go_to_`](#click_-versus-go_to_)
    *   [When to use `click_`?](#when-to-use-click_)
    *   [When to use `go_to_`?](#when-to-use-go_to_)
*   [Element naming convention](#element-naming-convention)
    *   [Examples](#examples)
*   [Block argument naming](#block-argument-naming)
    *   [Examples](#examples-1)

# Style guide for writing end-to-end tests[](#style-guide-for-writing-end-to-end-tests "Permalink")

本文档介绍了在 GitLab 上使用 GitLab QA 项目编写端到端（E2E）测试所使用的约定.

## `click_` versus `go_to_`[](#click_-versus-go_to_ "Permalink")

### When to use `click_`?[](#when-to-use-click_ "Permalink")

单击单个链接进行导航时，请使用`click_` .

E.g.:

```
def click_ci_cd_pipelines
  within_sidebar do
    click_element :link_pipelines
  end
end 
```

从测试的角度来看，如果我们要检查单击链接或按钮（单个交互）是否按预期工作，我们希望测试的内容为：

*   点击某个元素
*   验证操作是否发生

### When to use `go_to_`?[](#when-to-use-go_to_ "Permalink")

与多个元素进行交互以转到页面时，请使用`go_to_` .

E.g.:

```
def go_to_operations_environments
  hover_operations do
    within_submenu do
      click_element(:operations_environments_link)
    end
  end
end 
```

`go_to_`适合与多个元素进行交互的定义，因为它更多的是包含多个交互的元导航操作.

请注意，在上面的示例中，在单击`:operations_environments_link`之前，将鼠标悬停在另一个元素上.

> 我们可以创建这些方法作为抽象多步导航的助手.

## Element naming convention[](#element-naming-convention "Permalink")

在页面上添加新元素时，重要的是要有统一的元素命名约定.

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

*Formula*: `element :<descriptor>_<type>`

*   `descriptor` ：元素是什么的自然语言描述. 在登录页面上，可以是`username`或`password` .
*   `type` ：用户可以在页面上看到的通用控件.
    *   `_button`
    *   `_checkbox`
    *   `_container` ：包含其他元素但本身不显示可见内容的元素. 例如，其中具有第三方编辑器的元素，但它本身不是编辑器，因此不包含编辑器的内容.
    *   `_content` ：包含文本，图像或显示给用户的任何其他内容的任何元素.
    *   `_dropdown`
    *   `_field` ：文本输入元素.
    *   `_link`
    *   `_modal` ：弹出的模式对话框，例如确认提示.
    *   `_placeholder` ：加载内容时出现的临时元素. 例如，在获取讨论时显示的元素而不是讨论.
    *   `_radio`
    *   `_tab`
    *   `_menu_item`

*注意：如果列出的类型都不适合，请打开合并请求以将适当的类型添加到列表中.*

### Examples[](#examples "Permalink")

**Good**

```
view '...' do
  element :edit_button
  element :notes_tab
  element :squash_checkbox
  element :username_field
  element :issue_title_content
end 
```

**Bad**

```
view '...' do
  # `_confirmation` should be `_field`. what sort of confirmation? a checkbox confirmation? no real way to disambiguate.
  # an appropriate replacement would be `element :password_confirmation_field`
  element :password_confirmation

  # `clone_options` is too vague. If it's a dropdown menu, it should be `clone_dropdown`.
  # If it's a checkbox, it should be `clone_checkbox`
  element :clone_options

  # how is this url being displayed? is it a textbox? a simple span?
  # If it is content on the page, it should be `ssh_clone_url_content`
  element :ssh_clone_url
end 
```

## Block argument naming[](#block-argument-naming "Permalink")

为了对使用`.perform`方法时调用的页面和资源有一个标准，我们在`.perform`使用页面对象的[名称](https://en.wikipedia.org/wiki/Snake_case) （全部小写，单词之间用下划线分隔）. 请参阅下面的好与坏示例.

尽管在大多数情况下我们倾向于遵循该标准，但是只要名称不明确，也可以使用常见缩写（例如`mr` ）或其他替代方式. 如果有助于避免混淆或使代码更具可读性，则可以包括附加`_page` . 例如，如果一个页面对象被命名为`New` ，也可能是混淆命名块论点`new` ，因为这是用来实例化对象，所以`new_page`是可以接受的.

我们选择不只是使用`page`因为这会遮盖 Capybara DSL，从而可能导致混乱和错误.

### Examples[](#examples-1 "Permalink")

**Good**

```
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.peform do |new_page|
  new_page.do_something
end 
```

**Bad**

```
Page::Project::Members.perform do |project_settings_members_page|
  project_settings_members_page.do_something
end 
```

```
Page::Project::New.peform do |page|
  page.do_something
end 
```

> 除了采用标准的优点之外，通过遵循该标准，我们还编写了较短的代码行.