[Cucumber] 如何寫出好的 Cucumber 測試
凌晨1:04這週在網路上面讀到一篇 Write Great Cucumber Test, 看完挺有感觸的, 剛好自己這兩三個月都在用 Cucumber 寫 Acceptance Test. 趁這個機會就來做個 Summary 吧, 重點分成三個部分:
- Feature file
- Step Definitions file
- Configuration
- 寫 Feature 檔
Feature 檔幫助非專業的 stackholders 使用並了解整個測試, 透過這份文件, 可以用協同合作的方式與測試人員及整個團隊搭起橋樑. 基於這個理由, 寫出一份好的 feature 檔無非是幫助整個團隊更有效率地使用 BDD 的方式來進行合作.
下面這些建議及標準, 可以幫助我們寫出好的 Cucumber feature 檔:
Organization | Feature files can live at the root of the /features directory. However, features can be grouped in a subfolder if they describe a common object. The grouped filenames should represent the action and context that is covered within. |
Feature Files | Every *.feature file consists in a single feature, focused on the business value. |
Gherkin Template | Feature: Title (one line describing the story) |
Background | The background needs to be used wisely. If you use the same steps at the beginning of all scenarios of a feature, put them into the feature’s background scenario. The background steps are run before each scenario. |
Scenarios | Keep each scenario independent. The scenarios should run independently, without any dependencies on other scenarios. |
Scenario Outline | If you identify the need to use a scenario outline, take a step back and ask the following question: Is it necessary to repeat this scenario ‘x’ amount of times just to exercise the different combination of data? In most cases, one time is enough for UI level testing. |
Write Declarative Scenarios, Not Imperative | The declarative style describes behavior at a higher level, which I think improves the readability of the feature by abstracting out the implementation details of the application. Example: Imperative Scenario: User logs in
Given I am on the homepage
When I click on the "Login" button
And I fill in the "Email" field with "me@example.com"
And I fill in the "Password" field with "secret"
And I click on "Submit"
Then I should see "Welcome to the app, John Doe"
Example: Declarative Scenario: User logs in
Given I am on the homepage
When I log in
Then I should see a login notification
Just avoid unnecessary details in your scenarios. |
Given, When, and Then Statements | I’ve often seen people writing the Gherkin syntax confuse when to put the verification step in the Given, When, Then sequence. Each statement has a purpose.
Just remember the ‘then’ step is an acceptance criteria of the story. |
Tagging | Since tags on features are inherited by scenarios, please don’t be redundant by including the same tags on scenarios. |
- 寫 Step Definitions
Cucumber 自己本身不可能知道你沒有定義過的步驟. 而 Step Definitions 就是將這些純文字翻譯成 Gherkin Steps, 作為與測試機器間的互動. 這些 Steps Definitions 會使用 Ruby 的語法來完成並且放在 features/step_definitions/*.steps.
這邊有一些建議及標準, 可以幫助我們寫出好的 Steps Definitions 檔:
Step Definitions | Keep the step definitions unique. If your step definition names aren’t unique, then you will find during runtime the following exception is thrown - ambiguous match. |
Hard-coding | As you know you shouldn't be hard coding parameters into your code. This applies to site URL’s as well to allow flexibility to globally change the value. |
Reusable Objects | At the beginning of any automation project, you need to think about scalability and maintainability. A good programming practice is Don’t Repeat Yourself (or DRY) by creating reusable code. You will find many different ways to share code between Cucumber scenarios. Be careful!
Why use the Page Object Pattern?
|
Code | No sleep statements. It is better to use method or function with a built-in timeout. |
RSpec Expectations | The rspec-expectations library is bundled with many built-in matchers for testing validation. Each of the matchers can be used with expect(..).to or expect(..).not_to to define positive and negative expectations respectively on an object under test. I recommend using rspec-expectations matchers over Selenium matchers for Ruby testing frameworks. |
- Cucumber 的組態設定
在 Ruby 使用 Cucumber 是一件很簡單的事情, 需包含下列這些組態檔案:
cucumber.yml | It simplifies command-line execution by defining reusable profiles within the cucumber.yml file. |
Gemfile | The Gemfile is used to manage dependencies for a Ruby project. We should also pin the versions of these Ruby gems. If you don’t pin a Ruby version, it will auto update and break your automation. |
Rakefile | Rakefile is a software task management and build automation tool. It allows you to specify tasks and describe dependencies as well as group tasks in namespaces. |
support/env.rb | The support/env.rb is an environment configuration file for Cucumber. This file is designed to provide flexibility by allowing you to do things easily, like toggle your execution environment from local to remote. To fully understand all the capabilities of this support file, you should take more time to read up on all of the capabilities. |
心得
蠻喜歡文章最後提到的一段話
BDD (Cucumber) allows for team collaboration early in the planning and development phases. Keep the numbers down. Ask yourself and the team: “If I can write a low-level test for this user story, should I write an UI acceptance test?” We should automate only the things that need to be automated at the UI level. It is a known fact that low-level tests are more reliable compared to UI tests. Cucumber is code, and all types of programming require thoughts upfront before writing automated tests. It is so important to lay a test automation foundation that embraces coding standards and follows design patterns that everyone will follow during automation development.
其實 BDD 最大的精神就是協同合作 (collaboration), 而裡面有一個問題 “If I can write a low-level test for this user story, should I write an UI acceptance test?”,
自己蠻認同他的答案, 也就是說我們應該只自動化在 UI 層級那些需要被自動化的部分, 因為這是一大家都知道的事實.
與其說 Cucumber 是 code 的一部份, 還不如說每當我們在寫自動化測試之前, 先制定 coding standard 和 遵循的設計模式 的方法, 讓這些方法成為自動化測試的基礎, 因此可以讓更多人投入來寫自動化測試.
[Reference]
0 意見