搬磚之餘來一杯意式濃縮咖啡(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還有更多的用法,不想看英文官方文件的,為你準備一份中文文件
ofollow,noindex">Espresso中文文件
下一篇部落格會介紹在有網路請求的情況下,我們怎麼進行測試。因為並非所有的UI操作都是同步響應的。也就是說我們的UI更新需要等待網路返回結果。如果我們直接測試,那麼很大概率會報錯,因為在我們要測試資料是否展示在UI上時,網路資料很有可能還沒有獲取到。。這種情況該怎麼辦呢,好期待筆者的下篇部落格哦[假裝很期待]