From e1ab8fcf935ca48efcf6bef201253965cfbbab0f Mon Sep 17 00:00:00 2001 From: ian zhang Date: Tue, 17 Feb 2026 22:04:53 +0800 Subject: [PATCH] docs(zh-cn): update design strategies documentation for clarity Revised the design strategies documentation in Chinese to enhance clarity and accuracy. Key sections were translated and restructured to improve readability and understanding for Chinese-speaking users. - Updated overview and examples - Enhanced explanations of design patterns and strategies - Improved formatting for better presentation --- .../test_practices/design_strategies.zh-cn.md | 189 +++++++++--------- 1 file changed, 95 insertions(+), 94 deletions(-) diff --git a/website_and_docs/content/documentation/test_practices/design_strategies.zh-cn.md b/website_and_docs/content/documentation/test_practices/design_strategies.zh-cn.md index 0d379b4b4a36..55853e66c0ba 100644 --- a/website_and_docs/content/documentation/test_practices/design_strategies.zh-cn.md +++ b/website_and_docs/content/documentation/test_practices/design_strategies.zh-cn.md @@ -4,50 +4,44 @@ linkTitle: "设计策略" weight: 1 --- -{{% pageinfo color="warning" %}} -

- - Most of the documentation found in this section is still in English. - Please note we are not accepting pull requests to translate this content - as translating documentation of legacy components does not add value to - the community nor the project. -

-{{% /pageinfo %}} - -(previously located: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests) - -## Overview -Over time, projects tend to accumulate large numbers of tests. As the total number of tests increases, -it becomes harder to make changes to the codebase --- a single "simple" change may -cause numerous tests to fail, even though the application still works properly. -Sometimes these problems are unavoidable, but when they do occur you want to be -up and running again as quickly as possible. The following design patterns and -strategies have been used before with WebDriver to help to make tests easier to write and maintain. They may help you too. - -[DomainDrivenDesign]({{< ref "encouraged/domain_specific_language.md" >}}): Express your tests in the language of the end-user of the app. -[PageObjects]({{< ref "encouraged/page_object_models.md" >}}): A simple abstraction of the UI of your web app. -LoadableComponent: Modeling PageObjects as components. -BotStyleTests: Using a command-based approach to automating tests, rather than the object-based approach that PageObjects encourage - -## Loadable Component - -### What Is It? - -The LoadableComponent is a base class that aims to make writing PageObjects -less painful. It does this by providing a standard way of ensuring that pages -are loaded and providing hooks to make debugging the failure of a page to load -easier. You can use it to help reduce the amount of boilerplate code in your -tests, which in turn make maintaining your tests less tiresome. - -There is currently an implementation in Java that ships as part of Selenium 2, -but the approach used is simple enough to be implemented in any language. - -### Simple Usage - -As an example of a UI that we'd like to model, take a look at -the [new issue](https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+) page. -From the point of view of a test author, this offers the service of being -able to file a new issue. A basic Page Object would look like: + +(原位置: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests) + +## 概览 + +随着时间推移, 项目往往会积累大量测试. +随着测试总数的增加, 对代码库进行改动会变得更困难 —— 即便只是一次“简单”的改动, +也可能导致大量测试失败, 而应用本身仍然能正常工作. +有时这种问题不可避免, 但一旦发生, 你希望能尽快恢复运行. +下面介绍的一些设计模式与策略在 WebDriver 场景下被证明可以简化测试编写与维护, +可能也对你有帮助. + +[领域驱动设计]({{< ref "encouraged/domain_specific_language.md" >}}): 以最终用户的语言来表达测试. + +[页面对象]({{< ref "encouraged/page_object_models.md" >}}): 对 Web 应用 UI 的一种简单抽象. + +LoadableComponent: 把页面对象建模为可加载的组件. + +BotStyleTests: 使用以命令为导向的自动化测试方式, 而不是页面对象更偏向的对象化方法 + + +## Loadable Component + +### 其是什么? + +LoadableComponent 是一个基类, 目标是让编写页面对象更轻松. +它通过提供一套标准机制来确保页面被正确加载, 并提供在页面加载失败时用于调试的钩子. +你可以利用它来减少测试中的样板代码, 从而降低维护测试的工作量. + +目前在 Selenium 中包含了一个 Java 实现, +但该方法足够简单, 可在任何语言中实现. + +### 简单用法 + +举个我们想要建模的 UI 的例子, 看看 [new issue](https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+) 页面. +对于测试作者而言, 该页面的作用是提供一个提交新 issue 的功能. +一个基本的页面对象看起来像: + ```java package com.example.webdriver; @@ -121,7 +115,8 @@ public class EditIssue { } ``` -In order to turn this into a LoadableComponent, all we need to do is to set that as the base type: +为了把它变成一个 LoadableComponent, +我们所要做的就是将其设为基类: ```java public class EditIssue extends LoadableComponent { @@ -129,10 +124,11 @@ public class EditIssue extends LoadableComponent { } ``` -This signature looks a little unusual, but it all means is that -this class represents a LoadableComponent that loads the EditIssue page. +这个签名看起来有些不寻常, 但它的含义很简单: +该类表示一个用于加载 EditIssue 页面 的 LoadableComponent. -By extending this base class, we need to implement two new methods: + +通过继承这个基类, 我们需要实现两个新方法: ```java @Override @@ -147,15 +143,16 @@ By extending this base class, we need to implement two new methods: } ``` -The `load` method is used to navigate to the page, whilst the `isLoaded` method -is used to determine whether we are on the right page. Although the -method looks like it should return a boolean, instead it performs a -series of assertions using JUnit's Assert class. There can be as -few or as many assertions as you like. By using these assertions -it's possible to give users of the class clear information that -can be used to debug tests. -With a little rework, our PageObject looks like: +`load` 方法用于导航到页面, +而 `isLoaded` 方法用于判断我们是否位于正确的页面. +虽然该方法看起来像是应该返回 boolean, +但实际上它通过 JUnit 的 Assert 类执行一系列断言. +断言可以多也可以少. 通过这些断言, +可以为类的使用者提供清晰的调试信息, +用于定位测试失败的原因. + +稍作改造后, 我们的页面对象如下: ```java package com.example.webdriver; @@ -243,27 +240,25 @@ public class EditIssue extends LoadableComponent { field.sendKeys(text); } } - ``` -That doesn't seem to have bought us much, right? One thing it has done -is encapsulate the information about how to navigate to the page into -the page itself, meaning that this information's not scattered through -the code base. It also means that we can do this in our tests: +看起来似乎没带来太多好处, 对吧? +不过它确实把如何导航到该页面的信息封装进了页面本身, +这意味着这些信息不会散落在代码库各处. +这也意味着我们可以在测试中这样做: ```java EditIssue page = new EditIssue(driver).get(); ``` -This call will cause the driver to navigate to the page if that's necessary. +上述调用会在必要时促使 driver 导航到该页面. -### Nested Components +### 嵌套组件 -LoadableComponents start to become more useful when they are used in -conjunction with other LoadableComponents. Using our example, we could -view the "edit issue" page as a component within a project's website -(after all, we access it via a tab on that site). You also need to be -logged in to file an issue. We could model this as a tree of nested components: +当 LoadableComponent 与其他 LoadableComponent 配合使用时, +会更加有用. 以我们的例子为例, +我们可以把“编辑 issue”页面视为项目网站中的一个组件(毕竟我们是通过该网站的某个选项卡访问它). +并且提交 issue 需要登录. 我们可以把它建模为一棵嵌套组件树: ``` + ProjectPage @@ -271,9 +266,10 @@ logged in to file an issue. We could model this as a tree of nested components: +---+ EditIssue ``` -What would this look like in code? For a start, each logical component -would have its own class. The "load" method in each of them would "get" -the parent. The end result, in addition to the EditIssue class above is: +这在代码中会是什么样子? +首先, 每个逻辑组件都有自己的类. +每个类的 `load` 方法会调用父组件的 `get` 方法. +最终效果, 除了上面的 EditIssue 类外, 还包括: ProjectPage.java: @@ -307,8 +303,8 @@ public class ProjectPage extends LoadableComponent { } } ``` - -and SecuredPage.java: + +以及 SecuredPage.java: ```java package com.example.webdriver; @@ -365,7 +361,7 @@ public class SecuredPage extends LoadableComponent { } ``` -The "load" method in EditIssue now looks like: +EditIssue 中的 `load` 方法现在如下: ```java @Override @@ -376,8 +372,10 @@ The "load" method in EditIssue now looks like: } ``` -This shows that the components are all "nested" within each other. -A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage: + +这表明这些组件都是相互 "嵌套" 的. +在 EditIssue 中调用 `get()` 会导致它的所有依赖组件也被加载. +示例用法: ```java public class FooTest { @@ -409,21 +407,23 @@ public class FooTest { } ``` -If you're using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, -the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests. +如果在测试中使用像 [Guiceberry](https://github.com/zorzella/guiceberry) 这样的库, +设置页面对象的前置步骤可以省略, 从而使测试更简洁、可读. + +## Bot 模式 -## Bot Pattern -(previously located: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests) +(原位置: https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests) -Although PageObjects are a useful way of reducing duplication in your tests, -it's not always a pattern that teams feel comfortable following. -An alternative approach is to follow a more "command-like" style of testing. -A "bot" is an action-oriented abstraction over the raw Selenium APIs. -This means that if you find that commands aren't doing the Right Thing -for your app, it's easy to change them. As an example: +尽管页面对象是减少测试重复的一种有效方式, +但并非所有团队都愿意或适应这种模式. +另一种可选的方式是采用更加 "命令式" 的测试风格. + + +“bot” 是对底层 Selenium API 的一种面向动作的抽象. +这意味着如果发现某些命令不适合你的应用, 可以轻松修改它们. 例如: ```java public class ActionBot { @@ -454,15 +454,16 @@ public class ActionBot { } ``` -Once these abstractions have been built and duplication in your tests -identified, it's possible to layer PageObjects on top of bots. + +一旦构建了这些抽象并找出测试中的重复, +就可以在 bot 之上再封装 页面对象. -## Example +## 示例 {{< tabpane text=true >}} {{< tab header="Python" >}} -一个用例 使用 `python + pytest + selenium` 实现了设计策略 "**Action Bot**, **Loadable Component** 和 **Page Object**". +一个用例 使用 `python + pytest + selenium` 实现了设计策略 "**Action Bot**, **Loadable Component** 和 **页面对象**". A `pytest` fixture `chrome_driver`. @@ -486,7 +487,7 @@ A `pytest` fixture `chrome_driver`. {{< /tabpane >}} -"**Action Bot**" implementation. +"**Action Bot**" 实现. {{< tabpane text=true >}} {{< tab header="Python" >}} @@ -510,7 +511,7 @@ A `pytest` fixture `chrome_driver`. {{< /tabpane >}} -"**Loadable Component** definition. +"**Loadable Component** 定义. {{< tabpane text=true >}} {{< tab header="Python" >}} @@ -534,7 +535,7 @@ A `pytest` fixture `chrome_driver`. {{< /tabpane >}} -"**Loadable Component** and **Page Object**" implementation. +"**Loadable Component** 以及 **页面对象**" 实现. {{< tabpane text=true >}} {{< tab header="Python" >}} @@ -557,7 +558,7 @@ A `pytest` fixture `chrome_driver`. {{< /tab >}} {{< /tabpane >}} -Test cases implementation. +测试用例实现. {{< tabpane text=true >}} {{< tab header="Python" >}}