優才譯文∣安卓代碼整潔之道(一)
看作者腦洞大開——「我們在討論安卓設計模式,我的建議是使用一個iOS設計模式。」
「
你在尋找完美的移動單元測試工具嗎?那麼你就不要忽略你APP的結構以及它是否支持單元測試。
這篇博文是關於我發現正確的移動應用單元測試框架的過程,以及我怎樣實現了安卓代碼的整潔——依靠一種設計模式。當你讀完了這一系列的博文,我敢保證,你將學會怎樣一步一步地給你的移動應用進行單元測試。
讓我們從單元測試開始吧
寫一個擁有好的單元測試代碼覆蓋率的安卓app並不容易,因為安卓代碼有一個大規模的activity類需要管理不止一個功能或任務。典型的activity類實現如下的任務:
從像API(一個本地的資料庫,或者一個內容供應者)這樣的數據源中做數據收回。
根據UI的需要,對收回的數據進行數據操作和裝飾。
做具有UI特性的活動,比如打底、上色、響應用戶事件,以及創造fragment。
當你試著在一個單一的類中完成超過一個任務時,你經常會遇到Activity或者Fragment漸漸變成一個大規模的類以及它們的方法纏結在一起,在所有地方做一切事情。在這個設置中測試這些方法不容易;你有太多需要用mock測試的依賴。
維持用許多mocks測試代碼要花費大量的工夫。在尋找完美的單元測試工具,像JUnit, Robolectric,以及安卓instrumentation框架,我們經常忽略app開發結構對單元測試的適應性。
單元測試自動化失敗背後的主要原因之一就是一個app結構不支持單元測試。使一個開發結構支持測試以及使用極少的mocking或者完全不使用mocking是很重要的。當你的app開發結構天生地不支持單元測試時,這個測試框架就不能把你從你自造的問題中解救出來。
你要知道,我們需要一個好的設計模式來協助測試,以鮑勃叔叔的整潔結構作為參考嚮導,我已經開始研究移動應用中的適合於測試驅動開發的設計模式了。
本土的移動開發模式
在大量的為移動應用開發創造的設計模式中,一個相當類似於整潔代碼結構以及在iOS世界流行的就是VIPER。
iOS中VIPER的普通型vanilla的安裝啟用有它自己的挑戰。在鮑勃叔叔的整潔結構或者VIPER(在app delegate中做所有的安裝)里沒有配置器,導致代碼被外來的安裝代碼弄得凌亂不堪。整潔-快捷使一個iOS模式能夠克服這些挑戰,在這裡依賴的布線被抽取出給配置器。
稍等一分鐘,我們在討論安卓設計模式,我的建議是使用一個iOS設計模式。
為什麼不呢?
如果你除去每個平台上的獨創性,你會發現Android和iOS開發是非常相似的。依靠整潔-快捷設計模式,我們將能夠測試至少80%的代碼。
迫使一個VIPER去適應安卓有它的問題;你可以在Lyubomir博客上多讀讀相關內容。在Android整潔代碼中,去適應整潔-快捷,在Lyubomir博客上提到過的這個問題被關注了——相信我並繼續閱讀。
Android整潔代碼
歡迎來到Android整潔代碼的世界,在整潔-快捷之上建立。它建立的原則是SOLID。
整潔的Android是通過將龐大的activity拆分成一些單元來建立的。
每一個activity需要從一個或者更多的數據源獲取數據;數據收回工作將被interactor類處理。
一旦數據被interactor收回,這個數據可能就需要以能被activity呈現的形式修改;做這個工作的類是presenter。
Activity以事件形式做呈現數據和接受用戶行為的有規律的工作。
那麼activity, interactor,以及presenter怎麼樣互相對話呢?
使用介面(interface)
當屏幕需要載入,它使用InteractorInput介面命令Interactor去獲取數據。
一旦數據收回成功了或失敗了,Interactor使用PresentorInput介面命令Presenter去布置原始數據。
一旦數據是在一個展示形式的狀態中,Presenter使用ActivityInput介面命令Activity去顯示數據。正如你看見的,數據流是單向性的。
讓我們開始吧。複製這個用於舉例的項目並且在Android Studio中打開。
說說Activity
當設計這個activity類的時候,我們必須確定這個Activity類應該做什麼以及應該不做什麼。
堅持SRP原則,activity類工作時呈現數據給用戶以及傾聽用戶行為,不會更多,也不會更少。
由於這個Activity用來呈現數據,它需要來自數據源的數據,它應該親自去獲取數據嗎?不,他應該通過使用介面將工作委託給Interactor。讓我們來給介面下定義。
我們在Activity類中定義一個成員,它能夠控制介面的implementation instance。在Activity的onCreate方法中,使用這個方法會為Activity收回數據。
等等,這個輸出成員(output member)將怎樣憑藉合適的implementation初始化呢?
配置器做的事情是依賴的布線(the wiring of the dependencies),後面還要再講講。如果你使用整潔Android代碼發生器,這些類將會為你自動生產。
讓我們專註於測試。寫一個類別介紹測試用例來測試Activity;你可以參考這裡的代碼。我們會用Robolectric代替JUnit來測試activity,因為當mock測試Android生態系統比如語境的時候,Robolectric能夠做所有困難的工作。
我們將寫一個簡單的類別介紹測試用例來看看是否這個Activity被創建了。我把這叫做一個Canary測試,來看看是否基礎的部分被合適地布線(wired)了。
既然我們知道這個activity確實被創建了,讓我們查看是否這個Interactor方法被喚醒了。
離開Interactor,我們怎樣測試這個Activity呢?你應該能夠在沒有實際的Interactor的時候測試;讓我們使用一個spy來查看是否這個方法被喚醒了。
想要理解spy,mock,和stubs是什麼嗎?點擊這裡。
讓我們為介面HomeInteractroInput創建spy。
代碼是不言自明的,它實現了介面以及介面所需的方法。
讓我們創建這個測試方法來測試那個被喚醒的Interactor。
如果這個Interactor方法以正確的輸入被喚醒,那麼讓我們也測試一下。
儘管我們在為一個有簡單邏輯的類進行單元測試,而且你可能理解了這個設計模式有多麼強大,因為它使開發者無論在方法被喚醒的時候還是經過的參數被賦值的情況下都能測試。事實上,開發者能夠一步一步地為activity類進行單元測試。
在我們結束這個練習以前,使用代碼覆蓋率(code coverage)來運行這個測試用例(Android Studio Menu Run Run with coverage)並且自己看看有多少Activity 類被覆蓋了。
下一步呢?我們將在下一輪中談論Interactor。
每日推薦:
1.三十五年經驗分享:程序員進階八法
2.職業成長的四個關鍵詞:趨勢、目標、努力和素質
3.經典語句徵集│你能打動多少人?
4.在「人民的名義」面前,普通人如何成功突圍
如您有任何疑問,
以及想要和優才小編溝通,
請聯繫:15201480058
點擊展開全文


※嵌入式分析2.0將改變商業智能市場
※「產品待辦事項列表」 一團混亂
※創業初心│不選最Hot,只做最Right
※房價飛漲,程序員工資怎麼漲?
※SQL性能調優:查找慢查詢的5種方法
TAG:優才學院 |
※《道德經》全文及譯文(二)
※商周金文拓片選彙編(附譯文)(上)
※商周金文拓片選彙編(附譯文)(下)
※千古奇文,明 楊慎《韜晦術》原文及譯文
※了凡四訓譯文(四)謙德
※古代志怪故事(張昺,文言文譯文對照,官員斗邪術)
※論語顏淵第十二(音頻+原文+譯文)
※古代志怪,物奇,銅鏡四則(浙右漁人 等,原文加譯文)
※了凡四訓譯文(三)積善
※了凡四訓譯文(一)立命
※古代志怪故事(謝二,荊州漁人,原文譯文對照)
※中國古代孝經宋人書畫孝經(圖冊)以及原文、譯文
※《冰鑒》原文及譯文
※《六國論》原文及譯文
※經典國學《二十四廉》原文、譯文
※王羲之《孝女曹娥碑》碑文解析以及譯文
※楊珣碑(珍稀原拓)並譯文
※國學經典:《近思錄》宋·朱熹——卷十四·聖賢 原文及譯文
※《尉繚子》原文及譯文
※金剛經全文及譯文《一》