前言
事情的起因是這樣的。相信很多人都經曆過這樣一個過程,一個成熟的線上app版本需要更新一個系列新功能的時候,我們上線需要完成以下幾個步驟:
1.測試環境下,測試人員測試新功能,并且連帶需要測試線上穩定版本的主要老功能。
2.確定沒問題以後,背景和app上生産環境,測試人員需要在把生産環境的新功能和老功能都測試一遍。(一般大的公司上線都在淩晨,測試人員、背景、app開發都需要等生産沒有問題了才可以下班)
這麼看來,即使是上線一個小功能,還需要把之前疊代很多版本的老功能都按照測試用例測試一遍。實在是勞民傷财。那麼我們的自動化測試就派上用場了。每次小版本更新的時候,都配套寫多個自動化測試用例。上線前後直接跑一整套的測試用例。如果出現問題,會直接指出哪裡有問題。
Espresso
Espresso測試架構是在Android測試支援庫中的,提供了操作一個app的api來模拟使用者的操作。Espresso測試可以運作在Android2.3.3及其更高版本的機器上。
第一步:在app的build.gradle裡面添加依賴
def VERSION = '27.1.0'
def espressoVersion = '2.2.2'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:' + VERSION
implementation 'com.android.support:support-annotations:' + VERSION
implementation 'com.android.support:recyclerview-v7:' + VERSION
androidTestImplementation 'com.android.support.test.espresso:espresso-core:' + espressoVersion
androidTestImplementation('com.android.support.test.espresso:espresso-contrib:' +espressoVersion) {
transitive false
}
androidTestImplementation 'com.android.support:support-annotations:' + VERSION
androidTestImplementation 'com.android.support:recyclerview-v7:' + VERSION
}
第二步:在app項目的androidTestwen檔案夾下面找到一個自動生成的測試用例類。你也可以自己建立一個用來測試的類。

第三步:話不多說直接上代碼!
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Rule
public ActivityTestRule activityTestRule = new ActivityTestRule(MainActivity.class);
@Test
public void case1() {
//進入case1(單選題,我最喜歡吃的食物是什麼?,正确答案是:beer 啤酒) 進來先選擇選項一、二、三。
//最後斷言 看最終選擇的是不是正确答案 beer 啤酒
Espresso.onView(withId(R.id.tvCase1)).perform(click());
Espresso.onView(withId(R.id.rb1)).perform(click());
Espresso.onView(withId(R.id.rb2)).perform(click());
Espresso.onView(withId(R.id.rb3)).perform(click());
Espresso.onView(withId(R.id.tvFavoriteFood)).check(matches(withText("beer")));
}
@Test
public void case2() {
//進入case1(單選題,我最喜歡吃的食物是什麼?,正确答案是:beer 啤酒) 進來先選擇選項一、二、三、四。
//最後斷言 看最終選擇的是不是正确答案 beer 啤酒
Espresso.onView(withId(R.id.tvCase1)).perform(click());
Espresso.onView(withId(R.id.rb1)).perform(click());
Espresso.onView(withId(R.id.rb2)).perform(click());
Espresso.onView(withId(R.id.rb3)).perform(click());
Espresso.onView(withId(R.id.rb4)).perform(click());
Espresso.onView(withId(R.id.tvFavoriteFood)).check(matches(withText("beer")));
}
}
測試用例很簡單進入測試界面。選擇最喜歡的食物,正确答案是beer 啤酒。case1選擇的是第三個選項 Fried chicken。case2選擇的是第四個選項 beer。兩個case結束的時候,我都進行了斷言比對選項是不是“beer”。
不知道怎麼運作的同學請看截圖(在想運作的類上面右擊選擇Run “你的類”):
運作case(不得不說作為谷歌的親兒子,espresso的響應速度可謂非常快的):
運作後結果如圖:
可以看出來日志顯示“2 tests done:1 failed.” 也就是說case1失敗,case2成功。符合原先的的代碼邏輯,是我希望看到的結果。紅框上面也提示了“with text :is "beer" doesn't match the selected view”.告訴我case1的最終選擇不是我想要的“beer”這個答案。
Appium
appium優點:
- 跨平台。支援Android、ios、前端。支援java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure,或者Perl語言等語言。是相容性最廣泛的開源項目。
- 跨應用。與espresso相比較。appium不僅支援對目前應用的操作,而且可以操作手機上面任意看得到的應用。(比如一條測試用例是點選分享到微信朋友圈,espresso就無法做到,但appium可以)
- 跨源碼。硬凹的押韻,其實意思就是,appium編寫測試用例的時候,不需要app的源碼支援。
appium缺點:
- 必須改寫軟鍵盤才能支援中文輸入。這樣app裡面軟鍵盤就無法彈出。而且系統軟鍵盤會被預設設定成appium的軟鍵盤,需要手動改回來。
- 響應速度可以接受,但是和espresso比起來還是差遠了。
那麼接下來開始:
第一步,配置環境,安裝sdk,nodejs,appium用戶端等。傳送門 https://www.jianshu.com/p/9412e4eebaae
第二步,在項目中添加一個Java library的module。添加目錄和檔案。
第三步,上代碼
public class AndroidContactsTest {
//Driver
private AndroidDriver<AndroidElement> driver;
/**
* 配置啟動driver
*
* @throws Exception
*/
@Before
public void setUp() throws Exception {
File classpathRoot = new File(System.getProperty("user.dir"));
//app的目錄
File appDir = new File(classpathRoot, "/src/main/java/apps/release");
//app的名字,對應你apps目錄下的檔案
File app = new File(appDir, "app-release.apk");
//建立Capabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
//設定要調試的模拟器的名字
capabilities.setCapability("deviceName", "Redmi 4X");
//設定模拟器的系統版本
capabilities.setCapability("platformVersion", "7.1.2");
//設定app的路徑
capabilities.setCapability("app", app.getAbsolutePath());
//設定app的包名
capabilities.setCapability("appPackage", "com.ironman.autotestappium");
//設定app的啟動activity
capabilities.setCapability("appActivity", ".MainActivity");
//設定app可以輸入中文字元
capabilities.setCapability("unicodeKeyboard", "True");
capabilities.setCapability("resetKeyboard", "True");
//啟動driver
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
@After
public void tearDown() throws Exception {
//測試完畢,關閉driver,不關閉将會導緻會話還存在,下次啟動就會報錯
driver.quit();
}
@Test
public void case1() {
//進入case1(單選題,我最喜歡吃的食物是什麼?,正确答案是:beer 啤酒) 進來先選擇選項一、二、三。
//最後斷言 看最終選擇的是不是正确答案 beer 啤酒
driver.findElementById("com.ironman.autotestappium:id/tvCase1").click();
driver.findElementById("com.ironman.autotestappium:id/rb1").click();
driver.findElementById("com.ironman.autotestappium:id/rb2").click();
driver.findElementById("com.ironman.autotestappium:id/rb3").click();
String favoriteFood = driver.findElementById("com.ironman.autotestappium:id/tvFavoriteFood").getText();
assertEquals("beer", favoriteFood);
}
@Test
public void case2() {
//進入case1(單選題,我最喜歡吃的食物是什麼?,正确答案是:beer 啤酒) 進來先選擇選項一、二、三、四。
//最後斷言 看最終選擇的是不是正确答案 beer 啤酒
driver.findElementById("com.ironman.autotestappium:id/tvCase1").click();
driver.findElementById("com.ironman.autotestappium:id/rb1").click();
driver.findElementById("com.ironman.autotestappium:id/rb2").click();
driver.findElementById("com.ironman.autotestappium:id/rb3").click();
driver.findElementById("com.ironman.autotestappium:id/rb4").click();
String favoriteFood = driver.findElementById("com.ironman.autotestappium:id/tvFavoriteFood").getText();
assertEquals("beer", favoriteFood);
}
@Test
public void case3() {
driver.findElementById("com.ironman.autotestappium:id/tvJump").click();
driver.findElementByXPath("//*[@text='登入']").click();
driver.findElementById("com.tencent.mm:id/hz").sendKeys("17600000000");
driver.findElementById("com.tencent.mm:id/alr").click();
driver.findElementById("com.tencent.mm:id/hz").sendKeys("123456");
driver.findElementById("com.tencent.mm:id/alr").click();
driver.pressKey(new KeyEvent(AndroidKey.BACK));
}
}
運作case(相比較espresso,這測試速度真心是。。。。反正急性子的人慎用,另外感謝 特效大神 過志鑫 同學協助完成錄屏部分)
運作後的結果如圖:
相比較espresso,appium的輸出日志就清晰很多了。case1、case2、case3全部的三個測試用例都展示了出來,并且告訴你case1失敗(斷言期待結果是“beer”,結果是“Fried chicken”),case2、case3成功。
總結
appium總體來說,除了響應速度略微慢了點,其他不管是測試用例實作方式,應用的範圍、日志生成的表現形式都是優于espresso的。但如果是輕量級測試UI方面的話,espresso也是一個不錯的選擇。
最後貼上附上github的Demo.習慣的老鐵可以點一波關注,或者輕按兩下666。