The Cucumber for Java Book读书笔记[二]

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Part 5 Expressive Scenarios

Background

Background可以放置一些共有的描述,重构好帮手。

对于公用的Background,不会被多个scenario共享,每个scenario会独立运行自己的Background,仅仅起到了代码复用的作用

Cucumber不建议Background涉及太多技术方面的描述,scenario也要简洁

Data Tables

可以这么定义Data Tables

Feature:
  Scenario:
    Given a board like this:
      |   | 1 | 2 | 3 |
      | 1 |   |   |   |
      | 2 |   |   |   |
      | 3 |   |   |   |
    When player x plays in row 2, column 1
    Then the board should look like this:
      |   | 1 | 2 | 3 |
      | 1 |   |   |   |
      | 2 | x |   |   |
      | 3 |   |   |   |

解析可以这么做

import cucumber.api.java.en.*;
import cucumber.api.PendingException;
import cucumber.api.DataTable;

import java.util.List;

public class BoardSteps {
    private List> board;

    @Given("^a board like this:$")
    public void aBoardLikeThis(DataTable table) throws Throwable {
        this.board = table.raw();
    }

    @When("^player x plays in row (\\d+), column (\\d+)$")
    public void playerXPlaysInRowColumn(int arg1, int arg2) throws Throwable {
        System.out.println(board.toString());
        
        throw new PendingException();
    }

    @Then("^the board should look like this:$")
    public void theBoardShouldLookLikeThis(DataTable arg1) throws Throwable {
        // Write code here that turns the phrase above into concrete actions
        // For automatic transformation, change DataTable to one of
        // List, List>, List> or Map.
        // E,K,V must be a scalar (String, Integer, Date, enum etc)
        throw new PendingException();
    }
}

注意,传入的DataTable是不可变的,

java.lang.UnsupportedOperationException
         at java.util.Collections$UnmodifiableList.set(Collections.java:1311)
         at tic_tac_toe.BoardSteps.playerXPlaysInRowColumn(BoardSteps.java:20)
         at *.When player x plays in row 2, column 1(tic_tac_toe.feature:8)

所以想增删改只能这么做

import cucumber.api.java.en.*;
import cucumber.api.PendingException;
import cucumber.api.DataTable;

import java.util.ArrayList;
import java.util.List;

public class BoardSteps {
    private List> board;

    @Given("^a board like this:$")
    public void aBoardLikeThis(DataTable table) throws Throwable {
        this.board = new ArrayList>();
        for (List row : table.raw()) {
            this.board.add(new ArrayList(row));
        }
    }

    @When("^player x plays in row (\\d+), column (\\d+)$")
    public void playerXPlaysInRowColumn(int row, int col) throws Throwable {
        board.get(row).set(col, "x");
    }

    @Then("^the board should look like this:$")
    public void theBoardShouldLookLikeThis(DataTable expectedTable) throws Throwable {
        expectedTable.diff(board);
    }
}
Scenario Outline
Scenario Outline: Withdraw fixed amount
Given I have  in my account
When I choose to withdraw the fixed amount of 
Then I should    
And the balance of my account should be     
  Examples: Successful withdrawal     
  | Balance | Withdrawal | Outcome              | Remaining |     
  | $500    | $50        | receive $50 cash     | $450      |     
  | $500    | $100       | receive $100 cash    | $400      |  
Examples: Attempt to withdraw too much     
| Balance | Withdrawal | Outcome              | Remaining |     
| $100    | $200       | see an error message | $100      |     
| $0      | $50        | see an error message | $0        |

可惜cucumber貌似不支持header和bottom的过滤,所以手动筛选

@When("^I need a table$")
    public void doSomething(DataTable dataTable) throws Throwable {
        List> rows = dataTable.asLists(String.class);
        // Either quit having a header in your datatable or remove the first row
        rows.remove(0);
        for (List row : rows) {
            ...
        }
    }
Doc Strings
 Scenario: Ban Unscrupulous Users   
 When I behave unscrupulously   
 Then I should receive an email containing:     
 """     
 Dear Sir,      
 Your account privileges have been revoked due to your unscrupulous behavior.      
 Sincerely,     T
 he Management     
 """   
 And my account should be locked


Staying Organized with Tags and Subfolders

顾名思义,使用Tags和子文件夹维护项目结构

作者说,想当年Cucumber还是个叫RSpec Story Runner的工具,使用.story的后缀名,是不是很像Agile里的user story?作者说后来认为user story脱离于代码,且伴随着user story的变化,理应不影响cucumber中现有的feature,所以推荐不要混淆,即使要引入story的思维,也应该用tag

The features should describe how the system behaves today, but they don’t need to document the history of how it was built; that’s what a version control system is for!

将@keyword置于Feature或者Scenario之前,便是Tag

 @nightly @slow 
 Feature: Nightly Reports
     @widgets   
     Scenario: Generate overnight widgets report
          ...
     @doofers   
     Scenario: Generate overnight doofers report

三个用处:

  • Documentation:标记标识

  • Filtering:运行或生成报表时的筛选

  • Hooks:部分运行

Part 6 Keeping Your Cucumbers Sweet

Feeling the Pain


Symptom Problem
Some of our tests fail randomly. Flickering scenarios
We keep breaking tests unintentionally. Brittle features
Our features take too long to run. Slow features
Our stakeholders don’t read our features. Bored stakeholders

Flickering scenarios就是莫名其妙地时好时坏的test case,最常见的有三种:

  • Shared Environments                      

  • Leaky Scenarios                      

  • Race Conditions and Sleepy Steps

当然,作者也说,要是真轮到你改bug,实在是找不出方法了,那就把这个test case删掉...

Brittle features就是那些不得不做的却不相干的事

通常有这些可能:

  • Fixture Data                      

  • Duplication                      

  • Leaky Scenarios                      

  • Tester Apartheid

SLOW FEATURES

这个没啥好说的,慢呗,作者建议真遇到了,可以试试tag+并行

Race Conditions and Sleepy Steps                      

Lots of Scenarios                      

Big Ball of Mud

BORED STAKEHOLDERS

貌似就是在说产品经理和开发测试之间的隔膜...

常见的来源如下:

Incidental Details                      

Imperative Steps                      

Duplication                      

Ubiquitous What?                      

Siloed Features


Working Together

作者强调Cucumber features就是living documentation

Living: It tests the system automatically so you can work on it safely.                  

Documentation: It facilitates good communication about the current or planned behavior of the system.

Scenario要写的直观相关简洁

Bad:

Scenario: Check inbox   
Given a User "Dave" with password "password"   
And a User "Sue" with password "secret"   
And an email to "Dave" from "Sue"   
When I sign in as "Dave" with password "password"   
Then I should see 1 email from "Sue" in my inbox

Well:

 Scenario: Check inbox   
 Given I have received an email from "Sue"   
 When I sign in   
 Then I should see 1 email from "Sue" in my inbox


作者说了命令式编程(Imperative Programming) 和 声明式编程(Declarative Programming)。

Gherkin是命令式的,但是推荐采用声明式的方式去写

作者说 ”想当年我跟Martin Fowler结对编程的时候,受益匪浅!“, 强调DAMP principle: Descriptive and Meaningful Phrases和DRY principle (Don’t Repeat Yourself)

Three Amigos

Three Amigos            

    The best Gherkin scenarios are created when the three amigos come together, bringing three very different perspectives:                                                                          

    The first amigo is a tester, who thinks about how to break things. The tester will typically come up with lots of scenarios, sometimes covering obscure edge cases and sometimes covering very important ones that no one else had thought of.                              

    The second amigo is a programmer, who thinks about how to make things. The programmer will typically add steps to scenarios, as he asks clarifying questions about what exactly should happen.               The third amigo is the product owner, who cares about scope. When the tester thinks of scenarios that hit edge cases the product owner doesn’t care about, she can tell the team to drop that scenario out of scope altogether, or the group can decide to test it with unit tests only. When the programmer explains that implementing a particular scenario will be complicated, the product owner has the authority to help decide on alternatives or to drop it altogether.                          

    Many teams practicing BDD have found the three amigos make a great partnership for thrashing out Gherkin scenarios that the whole team believes in. You don’t have to stop at three amigos, though: invite your team’s user experience specialists or operations staff, for example, if the feature being discussed will affect them.

Caring for Your Tests

同上一节,讲了一些问题和解决办法

LEAKY SCENARIOS --〉Test Data Builders

RACE CONDITIONS AND SLEEPY STEPS --〉introduce a fixed-length pause, or sleep

SHARED ENVIRONMENTS --〉 One-Click System Setup

Tester Apartheid --〉 delegate the work of running basic checks to Cucumber

FIXTURE DATA --〉 Nightly Build

LOTS OF SCENARIOS --〉subfolders +  tags

BIG BALL OF MUD --〉包含上述多种问题,要确保可测

Stop the Line and Defect Prevention

扯了些管理学的故事和理念

Stop the Line

大野耐一(Taiichi Ohno 1912-1990) Stop the Line at Toyota

DEFECT PREVENTION 四要素

Detect the abnormality. 

Stop what you’re doing.                      

Fix or correct the immediate problem.                      

Investigate the root cause and install a countermeasure.

第一部分Cucumber fundamentals 就结束了。

作者反复强调 Scenario要写出declarative style












转载于:https://my.oschina.net/u/921876/blog/649988

你可能感兴趣的:(The Cucumber for Java Book读书笔记[二])