今日科技快訊
近日,谷歌母公司Alphabet釋出了截至3月31日的2020年第一季度財報。財報顯示,Alphabet第一季度營收為412億美元,較上年同期的363億美元增長13%;淨利潤為68億美元,較上年同期67億美元增長3%;每股收益為9.87美元,高於去年同期的9.5美元。財報釋出後,Alphabet股價盤後暴漲逾8%。
作者簡介明天就是五一小長假了,祝大家玩的開心。另外,聽說跨省旅遊歸來可能會面臨隔離,建議大家還是謹慎出行。我們節後再見。
本篇文章轉自Flywith24的部落格,文章主要分享了他對優達學城資料中關於Android Test相關內容的翻譯,希望對大家有所幫助。
Flywith24的部落格地址:
https://juejin.im/user/57c7f6870a2b58006b1cfd6c
前言一直以來,關於如何寫測試程式碼的相關內容資源都比較少,之前在優達學城看到了這部分的視訊,但由於沒有中文字幕,對有些小夥伴可能不太友好。因此我決定將其整理成系列文章,那麼就從認識test開始吧。
本文內容來自(需要有賬號登入之後才能進行檢視):
https://classroom.udacity.com/courses/ud940/lessons/fa3a54ab-2da2-46b9-af73-e7f05b20f90f/concepts/374e1e3c-7018-4607-97b3-c50e1061ceda
結構作為Android開發者我們知道在Android Studio的Android檢視中有三部分程式碼:
app的邏輯程式碼(main source set)androidTest程式碼local test程式碼test程式碼知道所有的main source set中的程式碼,因此可以測試這些類。但是app程式碼不知道test中的程式碼,並且androidTest和test都不知道對方的存在。事實上,當你構建出apk並提交應用市場時,測試程式碼並沒有包含在內。
依賴引用下面標記的依賴 使用了test的引用方式testImplementation和androidTestImplementation。
注意:這些test程式碼不會打包到最終的apk檔案中。
testImplementation引用的JUnit依賴只能在test source set中使用,這種依賴範圍的限制是Gradle實現的。簡單總結下:
三種source sets:main,test,androidTest測試程式碼能訪問app程式碼app 程式碼 不能 訪問測試程式碼測試不會被打入到Apk中依賴範圍包括:testImplementation和androidTestImplementation/ 執行第一個test /
我們開啟test source set ,看到其中有一個ExampleUnitTest。
可以看到其內部只有一個addition_isCorrect()方法。有兩個要素使它成為一個test:
使用了@Test註解它存在於兩個test source set之一有了這兩個要素,這個方法就可以獨立的作為test執行。本示例test測試的內容在第15行,它被稱之為斷言(assertion)。斷言是test的核心內容,它檢查你的程式碼或者app行為是否符合你的預期。本示例中,斷言檢查 4 是否等於 2 + 2。按照規定,您需要將你的預期結果傳入到expected引數中,將實際結果傳入到actual引數中。@Test註解和斷言語句都是JUnit下的。
關於JUnit的更詳細的的資訊,請移步官方文件:
https://junit.org/junit4/
緊接著,Run視窗會出現:
可以看到該視窗顯示了test的資訊,顯示出test是否通過以及有多少test通過。下面我們嘗試一個test不通過的情況,我們加入一個斷言,如下所示:
我們可以看到,即使只有一個斷言失敗,整個test失敗了。視窗指出了預期的結果為5,而實際的結果為4,並且下邊標記處錯誤發生在第15行,可以看到這的確是個bug。解決好bug ,我們再次執行test 。這次我們使用一個不一樣的方式
下面介紹一些其他執行 test 的方式。
可以右擊類名選擇Run選項:
也可以在左側檢視中右擊test source set選擇Run按鈕,該方法會執行所有test。在頂部可以切換要執行的test ,點選綠色按鈕可以執行。也可切換回 app。
Android Test VS Test下面我們來對比一下androidTest和test:
testandroidTestLocal TestsInstrumented TestsLocal machine JVMReal or emulated devicesFasterSlower我們來執行一個androidTest,可以看到啟動了模擬器:
寫一個test首先我們針對一個功能來建立test,如圖所示,存在一個getForkAndOriginRepoStats()方法用於獲取fork倉庫和原始倉庫的資料並返回StatsResult,其中StatsResult第一個引數為fork專案的百分比,第二個引數為原始專案的百分比。我們呼叫Generate ,選中test選項,在彈出框中選擇JUnit4,點選OK並選擇存放在local test中。這樣我們就建立了一個test。
接下來我們編寫test 。可以看到自動創建出的test路徑與app code中的程式碼路徑的包名是對應的。我們先測試專案列表只有一個item,並且沒有fork ,然後計算fork專案的百分比和原始專案的百分比。理論上講,fork專案的百分比為0 ,而原始專案的百分比為100%,程式碼如下圖所示,我們編寫完畢後點擊執行。
可以看到測試通過這是一個正常流程,我們還需要測試異常的流程,比如repos為empty list或者repos變數本身為null。
可以看到我們的程式碼中沒有針對list為empty或null做判斷,所以導致了空指標,之後我們修改程式碼後即可通過測試。
事實上,我們上面的編碼流程叫做Test Driven Development(TDD)。
讓你的test更具可讀性與寫普通程式碼一樣,您需要讓您的test程式碼更具可讀性,可以從三個方向入手:
優秀的命名Given/When/Then藉助斷言庫優秀的命名首先我們來談談命名,我們知道test方法使用@Test 註解標記,理論上方法名可以隨意命名,但隨意的命名會導致可讀性的降低,因此需要一些特定的命名規範:測試模組_ 動作或輸入_ 結果狀態。
例如上面的例子我們的命名為:getForkAndOriginRepoStats_noForked_returnHundredZero。
第一部分顯示我們要測試的是getForkAndOriginRepoStats() 方法,第二部分代表我們需要的是沒有fork倉庫的資料來源,第三部分是結果的狀態,0%。
Given/When/Then說完了命名我們來談談Given/When/Then。測試的基本結構是Given X,When Y,Then Z。
還是上面的例子
Given 為你的測試邏輯提供資料來源When 是你的實際操作Then 檢查 test 是否通過藉助斷言庫
上面示例最後的斷言程式碼讓人看著很彆扭,我們可以藉助斷言庫來提高這部分的可讀性。
// 之前assertEquals(result.forkPercent, 0f)// 之後assertThat(result.forkPercent, `is`(0f))下面的語句就像人類的一句話,翻譯下來就是斷言forkPercent是0f。這樣的寫法需要引入一個庫Hamcrest。
testImplementation "org.hamcrest:hamcrest-all:1.3" 測試範圍測試範圍指一個test測試多少程式碼。例如自動化測試根據測試範圍可以分為:
Unit Tests(單元測試)Integration Tests(整合測試)End to end Tests(端到端測試)您的測試策略需要覆蓋到所有的型別。
Unit Tests上面的示例我們已經寫過了Unit Tests。
範圍是單個方法或類幫助查明失敗原因應該執行的很快,通常是本地測試低保真度他們的範圍是單個的方法或類。如果Unit Tests失敗了,您知道您的程式碼在哪裡出了問題。因為它聚焦於很小一段程式碼。Unit Tests也意味著可以快速執行,由於您頻繁地修改程式碼會使得它會頻繁的執行,因此需要速度。Unit Tests通常是本地測試。它們有較低的保真度,因為現實世界您的app要執行很多程式碼而不僅僅是一個方法或者類。Unit Tests就像檢查一個鏈條的每個環節是否能夠正常執行。
但它不檢查這些環節組合在一起是否能夠執行,為此您需要Integration Tests。
Integration TestsIntegration Tests擁有更大的範圍:
範圍是幾個類或單個功能確保幾個類共同執行可以使用本地測試或機器測試就像Integration這個詞一樣,Integration Tests整合一些類確保他們組合起來的表現符合預期。構建Integration Tests的方式是讓他們測試單個功能,就像獲取指定使用者的Github倉庫。
與Unit Tests 相比,Integration Tests有著更大的範圍,但他們仍執行的很快並且有著很好的保真度。根據具體情況來判斷使用本地測試還是機器測試,例如如果您寫的Integration Tests涉及到了UI元件,那麼您需要使用真機來測試了。
End to end Tests第三種類型是End to end Tests,該測試將一些列功能組合起來一起執行。
範圍是app的大部分高保真度將app作為整體來測試接近真實地使用,應該使用裝置測試End to end Tests測試app的大部分,它十分接近真實地使用,因此速度上會比較慢,它有著最高的保真度並確保您的應用作為一個整體執行。這些測試應該使用裝置測試。
測試比重推薦的測試比例是70%的單元測試,20%的整合測試,以及10%的端到端測試。
您能否輕鬆地在各個部分測試您的app取決於您的app使用的結構。例如,您的應用將所有邏輯都放置在一個activity的大的方法中,您可能可以寫出端到端測試,但單元測試和整合測試則寫不出來。
一個更好的架構應該將應用的邏輯拆分為多個方法和類,這允許每部分可以獨立的測試。
對於單元測試,您可以測試ViewModel,Repository以及DAO。
對於整合測試,您可以組合測試fragment和ViewModel ,或者您可以測試整個資料庫程式碼。
端到端測試會測試整個應用。
關於測試的原理,可移步。官方文件:
https://developer.android.com/training/testing/fundamentals
test的codelab:
https://codelabs.developers.google.com/codelabs/advanced-android-kotlin-training-testing-basics/index.html?index=..%2F..index#0
Android330頁PDF的核心筆記