天天看點

自動化測試之 Espresso VS Appium前言Appium總結

前言

事情的起因是這樣的。相信很多人都經曆過這樣一個過程,一個成熟的線上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檔案夾下面找到一個自動生成的測試用例類。你也可以自己建立一個用來測試的類。

自動化測試之 Espresso VS Appium前言Appium總結

第三步:話不多說直接上代碼!

@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 “你的類”):

自動化測試之 Espresso VS Appium前言Appium總結

運作case(不得不說作為谷歌的親兒子,espresso的響應速度可謂非常快的):

自動化測試之 Espresso VS Appium前言Appium總結

運作後結果如圖:

自動化測試之 Espresso VS Appium前言Appium總結

可以看出來日志顯示“2 tests done:1 failed.” 也就是說case1失敗,case2成功。符合原先的的代碼邏輯,是我希望看到的結果。紅框上面也提示了“with text :is "beer" doesn't match the selected view”.告訴我case1的最終選擇不是我想要的“beer”這個答案。

Appium

appium優點:

  1. 跨平台。支援Android、ios、前端。支援java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure,或者Perl語言等語言。是相容性最廣泛的開源項目。
  2. 跨應用。與espresso相比較。appium不僅支援對目前應用的操作,而且可以操作手機上面任意看得到的應用。(比如一條測試用例是點選分享到微信朋友圈,espresso就無法做到,但appium可以)
  3. 跨源碼。硬凹的押韻,其實意思就是,appium編寫測試用例的時候,不需要app的源碼支援。

appium缺點:

  1. 必須改寫軟鍵盤才能支援中文輸入。這樣app裡面軟鍵盤就無法彈出。而且系統軟鍵盤會被預設設定成appium的軟鍵盤,需要手動改回來。
  2. 響應速度可以接受,但是和espresso比起來還是差遠了。

那麼接下來開始:

第一步,配置環境,安裝sdk,nodejs,appium用戶端等。傳送門 https://www.jianshu.com/p/9412e4eebaae

第二步,在項目中添加一個Java library的module。添加目錄和檔案。

自動化測試之 Espresso VS Appium前言Appium總結

第三步,上代碼

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 VS Appium前言Appium總結

運作後的結果如圖:

自動化測試之 Espresso VS Appium前言Appium總結

相比較espresso,appium的輸出日志就清晰很多了。case1、case2、case3全部的三個測試用例都展示了出來,并且告訴你case1失敗(斷言期待結果是“beer”,結果是“Fried chicken”),case2、case3成功。

總結

appium總體來說,除了響應速度略微慢了點,其他不管是測試用例實作方式,應用的範圍、日志生成的表現形式都是優于espresso的。但如果是輕量級測試UI方面的話,espresso也是一個不錯的選擇。

最後貼上附上github的Demo.習慣的老鐵可以點一波關注,或者輕按兩下666。

繼續閱讀