Cucumber & Espressco - Behavior Driven Development (BDD) for Android - Phần 2

I. Introduction

Ở phần 1 mình đã giới thiệu cho các bạn về các công cụ cần thiết để áp dụng, phần này mình sẽ đi vào chi tiết từng bước áp dụng vào code nhé

II. Implement code

1. Giới thiệu về app mình dùng áp dụng cho việc testing

  • Mình sẽ tiến hành viết BDD cho ứng dụng đơn giản gồm 3 màn hình: màn hình search user từ API của github, màn hình list show kết quả, màn hình detail

2. Config

  • Add các dependencies của curcumber và espressco file gradle
androidTestCompile 'info.cukes:cucumber-android:1.2.5'
androidTestCompile 'info.cukes:cucumber-picocontainer:1.2.5'
androidTestCompile 'info.cukes:cucumber-jvm-deps:1.0.5'
// Screenshots
androidTestCompile 'com.squareup.spoon:spoon-client:1.7.1'
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
  exclude group: 'com.android.support', module: 'support-annotations'
  exclude group: 'com.android.support', module: 'appcompat-v7'
  exclude group: 'com.android.support', module: 'support-v4'
  exclude module: 'recyclerview-v7'
}
  • Tạo file TestRunner 1 config cần thiết để Android chạy được test UI file có dạng như sau và khai báo trong gradle
  defaultConfig {
          ...
          testInstrumentationRunner "packagename.CucumberTestRunner"
   }
  • Config sourceSet để Adroid đọc được những file feature, mình đặt trong assets của package adroidTest trong build.gradle
  sourceSets {
  androidTest {
    assets.srcDirs = ['src/androidTest/assets']
  }
}

3. Implement code test

  • Ở đây mình sẽ demo cho màn search
  • Đầu tiên ta cần viết script cho BDD file search.feature đặt trong asset có dạng ntn
Feature: MainScreen
 Perform search on keyword and limit number are inputted

 @search-scenarios
 Scenario Outline: Input keyword and limit number in wrong format
   Given I have a MainActivity
   When I input keyword "<keyword>" and limit "<limit>"
   And I click button search
   Then I should see <error>

   Examples:
     | keyword | limit | error         |
     |         |       | empty_empty   |
     | shit    |       | keyword_empty |
     |         | 123   | empty_limit   |
     | shit    | 123   | keyword_limit |
     | shit    | 13    | keyword_none  |
     | abc     | 123   | none_limit    |
   
 @search-scenarios
 Scenario: Input keyword and limit number in correct format
   Given I have a MainActivity
   When I input keyword "test" and limit "<12>"
   And I click button search
   Then I see result Screen
  • viết như ngôn ngữ tự nhiên của end user
  • Tiếp theo ta viết code java để thực thi file feature bên trên trong file StepDefinitions
@Given("^I have a MainActivity$")
   public void I_have_a_MainActivity() {
       mCurrentPage = new MainPage();
   }

   @When("^I input keyword \"([^\"]*)\" and limit \"([^\"]*)\"$")
   public void iInputKeywordKeywordAndLimitLimit(String keyword, String limit) {
       mCurrentPage.is(MainPage.class).inputKeywordAndLimit(keyword, limit);
   }

   @And("^I click button search$")
   public void iClickButtonSearch() {
       mCurrentPage.is(MainPage.class).doSearch();
   }

   @Then("^I should see (\\S+)$")
   public void iShouldSeeErrorOnViewView(String errorMessage) throws Throwable {
       mCurrentPage.is(MainPage.class).seeError(errorMessage);
   }

   @Then("^I see result Screen$")
   public void iGotoResultScreen() throws Throwable {
       mCurrentPage = mCurrentPage.is(MainPage.class).seeSearchResultScreen();
       mCurrentPage.is(SearchResultPage.class);
   }
  • File MainPage chứa tất cả các action user thực thi với màn hình search dùng Espressco để giả lập hành động người dùng có dạng như sau
public class MainPage extends BasePage {

   /**
    * The constructor verifies that we are on the correct page by checking
    * the existence of the unique identifier elements of the page/view
    */
   public MainPage() {
       onView(withId(R.id.main_activity)).check(matches(isDisplayed()));
   }

   public void inputKeywordAndLimit(String keyword, String limit) {
       Espresso.onView(ViewMatchers.withId(R.id.edtKeyword))
               .perform(ViewActions.typeText(keyword));
       Espresso.onView(ViewMatchers.withId(R.id.edtNumberLimit))
               .perform(ViewActions.typeText(limit));
       closeSoftKeyboard();
   }

   public void doSearch() {
       Espresso.onView(ViewMatchers.withText("Search")).perform(ViewActions.click());
   }
}

III. Run

  • Click chuột phải vào file StepDefinitions và run bạn sẽ thấy kết quả như sau:
  • Kết quả run test:

IV. Sourcode

Github: Implement BDD with Espressco and Curcumber