就知道,這肯定是杯假咖啡,搬磚還有時間喝咖啡!!!
年輕人,別急躁嗎,看完之後,你會發現可能真的可以空出一大把時間去喝咖啡了。
我信了你的邪了。
…,不信?你就往下看唄
- 何爲意式濃縮咖啡(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.運行該測試
觀察模擬器的動作變化
模擬器它會自動點擊按鈕並更改按鈕的文本內容
運行結束觀察控制檯的測試結果
可以看到所有測試通過
進階使用
接下來我們實現一個登錄的測試
修改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("登錄成功")));
}
}
運行,它會自動填寫用戶名和密碼並點擊登錄按鈕
最後驗證登錄按鈕文本是否變爲登錄成功,看看控制檯結果是pass的
上面只是介紹了Espresso的一小部分內容,關於Espresso還有更多的用法,不想看英文官方文檔的,爲你準備一份中文文檔
下一篇博客會介紹在有網絡請求的情況下,我們怎麼進行測試。因爲並非所有的UI操作都是同步響應的。也就是說我們的UI更新需要等待網絡返回結果。如果我們直接測試,那麼很大概率會報錯,因爲在我們要測試數據是否展示在UI上時,網絡數據很有可能還沒有獲取到。。這種情況該怎麼辦呢,好期待筆者的下篇博客哦[假裝很期待]