搬磚之餘來一杯意式濃縮咖啡(Espresso)

就知道,這肯定是杯假咖啡,搬磚還有時間喝咖啡!!!

年輕人,別急躁嗎,看完之後,你會發現可能真的可以空出一大把時間去喝咖啡了。

我信了你的邪了。

…,不信?你就往下看唄

  • 何爲意式濃縮咖啡(Espresso)
  • 幾種UI自動化測試工具的比較
  • 基礎用法
  • 進階使用

何爲意式濃縮咖啡(Espresso)?

Espresso是Google的開源自動化測試框架。相對於Robotium和UIAutomator,它的特點是規模更小、更簡潔,API更加精確,編寫測試代碼簡單,容易快速上手。因爲是基於Instrumentation的,所以不能跨App

幾種UI自動化測試工具的比較

那相比較其他自動化測試工具,有什麼不一樣呢?

Monkey

Monkey是Android SDK自帶的測試工具,在測試過程中會向系統發送僞隨機的用戶事件流,如按鍵輸入、觸摸屏輸入、手勢輸入等),實現對正在開發的應用程序進行壓力測試,也有日誌輸出。實際上該工具只能做程序做一些壓力測試,由於測試事件和數據都是隨機的,不能自定義,所以有很大的侷限性

Instrumentation

Instrumentation是早期Google提供的Android自動化測試工具類,雖然在那時候JUnit也可以對Android進行測試,但是Instrumentation允許你對應用程序做更爲複雜的測試,甚至是框架層面的。通過Instrumentation你可以模擬按鍵按下、擡起、屏幕點擊、滾動等事件。Instrumentation是通過將主程序和測試程序運行在同一個進程來實現這些功能,你可以把Instrumentation看成一個類似Activity或者Service並且不帶界面的組件,在程序運行期間監控你的主程序。缺點是對測試人員來說編寫代碼能力要求較高,需要對Android相關知識有一定了解,還需要配置AndroidManifest.xml文件,不能跨多個App

UiAutomator

UiAutomator也是Android提供的自動化測試框架,基本上支持所有的Android事件操作,對比Instrumentation它不需要測試人員瞭解代碼實現細節(可以用UiAutomatorviewer抓去App頁面上的控件屬性而不看源碼)。基於Java,測試代碼結構簡單、編寫容易、學習成本,一次編譯,所有設備或模擬器都能運行測試,能跨App(比如:很多App有選擇相冊、打開相機拍照,這就是跨App測試)。缺點是隻支持SDK 16(Android 4.1)及以上,不支持Hybird App、WebApp

配置Espresso

1.打開app/build.gradle

在dependencies節點下添加以下庫:

androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestCompile 'com.android.support.test:rules:1.0.2'

2.在android.defaultConfig下添加下面的代碼
 defaultConfig {
        //...省略
       "android.support.test.runner.AndroidJUnitRunner"
    }

基礎用法

下面寫一個簡單的Demo來學習一下它的基礎用法

1.先寫一個Activity用來測試

裏面有一個按鈕,點擊它,裏面的文本會改變

MainActivity的代碼如下,xml文件省略

public class MainActivity extends AppCompatActivity {
    Button btClick;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btClick=(Button)findViewById(R.id.bt_click);
        btClick.setText("click me");
    }
    
    public void clickButton(View view){
        btClick.setText("learn espresso");
    }
}

2.在src/androidTest/java/com.example.package/路徑下新建一個測試類

MyEspressoTest.class

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyEspressoTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
    
    @Test
    public void clickButton(){

        //檢查文本是不是Hello World,並點擊一下按鈕
        onView(withId(R.id.bt_click))
                .check(matches(withText("Hello World!")))
                .perform(click());

        //檢驗按鈕上的文本是否修改
        onView(withId(R.id.bt_click))
                .check(matches(withText("learn espresso")));


    }
}
3.運行該測試

run test.png

觀察模擬器的動作變化

模擬器它會自動點擊按鈕並更改按鈕的文本內容

運行結束觀察控制檯的測試結果

可以看到所有測試通過
test result.png

進階使用

接下來我們實現一個登錄的測試

修改MainActivity

如果用戶名爲jasonking,密碼爲123,則登錄按鈕文本變爲登錄成功,否則變爲登錄失敗

MainActivity.class

public class MainActivity extends AppCompatActivity {
    EditText edName;
    EditText edPass;
    Button btClick;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btClick=(Button)findViewById(R.id.bt_click);
        edName=(EditText) findViewById(R.id.ed_username);
        edPass=(EditText) findViewById(R.id.ed_pass);
        btClick.setText("登錄");
    }

    public void clickButton(View view){
        if(edName.getText().toString().equals("jasonking")&&edPass.getText().toString().equals("123")){
            btClick.setText("登錄成功");
        }else{
            btClick.setText("登錄失敗");
        }
    }
}

修改測試類

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyEspressoTest {
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void clickLogin(){
        //清空文本框,然後輸入用戶名jasonking,關閉軟鍵盤
        onView(withId(R.id.ed_username))
                .perform(
                        clearText(),
                        replaceText("jasonking"),
                        closeSoftKeyboard()
                )
                .check(matches(withText("jasonking")));
        
        //清空文本框,然後輸入密碼123,關閉軟鍵盤
        onView(withId(R.id.ed_pass))
                .perform(
                        clearText(),
                        replaceText("123"),
                        closeSoftKeyboard()
                )
                .check(matches(withText("123")));



        //點擊按鈕檢查文本是不是登錄
        onView(withId(R.id.bt_click))
                .check(matches(withText("登錄")))
                .perform(click());

        //檢驗按鈕上的文本是不是登錄成功
        onView(withId(R.id.bt_click))
                .check(matches(withText("登錄成功")));
    }
}

運行,它會自動填寫用戶名和密碼並點擊登錄按鈕

test screen.png

最後驗證登錄按鈕文本是否變爲登錄成功,看看控制檯結果是pass的

上面只是介紹了Espresso的一小部分內容,關於Espresso還有更多的用法,不想看英文官方文檔的,爲你準備一份中文文檔

Espresso中文文檔

下一篇博客會介紹在有網絡請求的情況下,我們怎麼進行測試。因爲並非所有的UI操作都是同步響應的。也就是說我們的UI更新需要等待網絡返回結果。如果我們直接測試,那麼很大概率會報錯,因爲在我們要測試數據是否展示在UI上時,網絡數據很有可能還沒有獲取到。。這種情況該怎麼辦呢,好期待筆者的下篇博客哦[假裝很期待]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章