iOS和Android應(yīng)用的技術(shù)審核已經(jīng)成為日常工作必不可少的一部分禁炒。這項(xiàng)工作看起來容易,然而在實(shí)際進(jìn)行審核的時(shí)候消别,我們會發(fā)現(xiàn)有不少實(shí)現(xiàn)細(xì)節(jié)要注意都伪。我們來回顧一下這個(gè)文檔里面我們認(rèn)為最重要的審核條目。這些審核條目按照技術(shù)方向被分成幾種不同類別。
版本控制系統(tǒng):
工程師是否使用版本控制惩猫,使用哪種系統(tǒng)芝硬,通過哪種過程來向我們呈現(xiàn)軟件開發(fā)過程。
你有沒有一個(gè)正確設(shè)置的*ignore忽略文件轧房,使得IDE的元文件和多余的東西不出現(xiàn)在版本控制系統(tǒng)中拌阴?
第三方庫文件是不是通過版本控制系統(tǒng)放到同一個(gè)倉庫中,而不是被設(shè)置成一個(gè)外部依賴奶镶?
你有沒有撰寫足夠準(zhǔn)確而且描述清晰的提交信息迟赃?
提交的大小是否合理?
同一個(gè)提交的所有文件是否都是和同一個(gè)問題或者特性相關(guān)連厂镇?
你在使用分支時(shí)有沒有使用”特性分支“或者”git-flow”這樣的分支策略纤壁?
分支命名是否足夠描述清晰?
是否在合并到主分支之前使用拉取請求(pull request)或者代碼審核(code review)系統(tǒng)捺信?
審核拉取請求(pull request)的時(shí)候酌媒,有沒有相關(guān)可以參考的參考規(guī)則?
每個(gè)PR平均有多少評論迄靠?
每個(gè)PR有多少人審核秒咨?
合并PR需要達(dá)到多少個(gè)同意?
誰來負(fù)責(zé)關(guān)閉被合并的分支掌挚?
有沒有用發(fā)布分支(release branch)來準(zhǔn)備每次版本發(fā)布雨席?
測試過程持續(xù)多久?
正式發(fā)布之前需要引進(jìn)多少個(gè)問題修復(fù)到發(fā)布候選版本中吠式?
能否簽出和用于構(gòu)建線上應(yīng)用的完全一樣的代碼陡厘?
去年你一共發(fā)布了多少個(gè)緊急修復(fù)(hotfixes)?
合并分支到主分支或者開發(fā)分支之前你是否會壓縮提交特占?
主分支或者開發(fā)分支是否隨時(shí)可以發(fā)布糙置?
構(gòu)建工具:
能夠在任何開發(fā)者機(jī)器,任何像持續(xù)集成系統(tǒng)這樣的外部系統(tǒng)上復(fù)制構(gòu)建過程非常重要摩钙。
項(xiàng)目使用了多少庫罢低?
項(xiàng)目是否被分成了多個(gè)模塊?
項(xiàng)目模塊是否通過Maven或者Gradle來提供依賴還是使用本地Jar文件胖笛?
項(xiàng)目是否接近了dex方法數(shù)量的紅線网持?還是已經(jīng)超過了紅線?
有沒有使用不需要的庫长踊?
有沒有使用multidex功舀?
外部依賴是否保持了最新狀態(tài)?
你是否遵守了每個(gè)第三方庫的授權(quán)證明身弊?
項(xiàng)目是否使用了任何過時(shí)或者被遺棄/停止維護(hù)的第三方庫辟汰?
最低SDK是否是項(xiàng)目描述中所要求的列敲?
目標(biāo)SDK是否是當(dāng)前最新?
是否啟用并且正確配置了proguard或者任何其他混淆工具帖汞?
keystore證書和Google Play Store證書是否被存放在安全的地方戴而?
應(yīng)用證書和簽名是否被存放在安全的地方?
應(yīng)用有沒有正確使用構(gòu)建類型翩蘸?
應(yīng)用是否正確使用特色類型所意?
發(fā)布構(gòu)建類型是否正確配置?
是否開啟了備份選項(xiàng)催首?
lint是否啟用而且成功通過扶踊?
是否配置了靜態(tài)分析工具而且成功通過?
是否配置了風(fēng)格檢查而且成功通過
是否正確配置應(yīng)用id和版本號郎任,版本編碼秧耗?
對于id,你是否使用某種版本結(jié)構(gòu)或者策略舶治?
有沒有配置持續(xù)集成工具分井?
發(fā)布過程是否自動化?
Android資源使用:
在Android世界中有很多不同的設(shè)備歼疮,每種都有不同的屏幕大小杂抽,功能等等特征。你需要額外小心還要使用Android工具來根據(jù)用戶的設(shè)備給他們提供最佳的體驗(yàn)韩脏。
對于各種屏幕密度,特色或者構(gòu)建類別是否有缺失的資源铸磅?
應(yīng)用是否支持產(chǎn)品描述要求的所有屏幕密度赡矢?
應(yīng)用是否使用位圖,字體或者矢量資源阅仔?
是否有缺失的翻譯吹散?
翻譯過程是否自動化?
默認(rèn)的翻譯是什么語言八酒?
應(yīng)用是否使用自定義字體空民?
應(yīng)用是否使用存放在String資源文件中的配置變量?
變量命名的規(guī)則和資源命名的規(guī)則是否一致羞迷?
硬件相關(guān)的配置參數(shù)是否正確設(shè)置界轩?
是否支持平板設(shè)備?
Android布局用法:
就像我們之前說到的衔瓮,市面上有很多不同屏幕浊猾,不同像素密度的各種Android設(shè)備。正確使用Android布局非常重要热鞍。
應(yīng)用布局的層數(shù)是否造成了性能問題葫慎?
是否使用了主題和風(fēng)格衔彻?
是否通過使用“include”標(biāo)簽來復(fù)用布局?
在布局實(shí)現(xiàn)中有沒有使用正確的視圖組(view group)?
布局有沒有為不同屏幕大小適配偷办?
布局和控件命名規(guī)則是否一致艰额?
實(shí)現(xiàn)列表的時(shí)候使用的是ListView還是RecyclerView控件?
是否正確使用了Android Support庫椒涯?
權(quán)限用法:
請求正確的權(quán)限可以幫助你在用戶中建立起信任悴晰,也可以讓你的應(yīng)用走的更遠(yuǎn),同時(shí)可以無縫的和其他服務(wù)集成給你的用戶帶來良好的體驗(yàn)逐工。
所有請求的權(quán)限是否真的有必要铡溪?
有沒有濫用任何權(quán)限?
有沒有缺失必要的權(quán)限泪喊?
目標(biāo)SDK版本是否高于23棕硫?危險(xiǎn)權(quán)限是否通過兼容權(quán)限系統(tǒng)(compatibility permissions system)請求?
權(quán)限被使用時(shí)有沒有發(fā)出請求袒啼?
有沒有通過反饋說明需要請求的權(quán)限哈扮?
安全問題:
作為開發(fā)者,我們需要意識到應(yīng)用的安全性蚓再,我們不希望用戶數(shù)據(jù)被泄露或者用戶會話被劫持滑肉。
HTTP客戶端是否配置使用HTTPS?
HTTP客戶端是否配置使用證書綁定摘仅,消息是否使用HMAC驗(yàn)證靶庙?
應(yīng)用是否持久化用戶敏感信息?存放在哪里了娃属?
應(yīng)用是否在內(nèi)置存儲外存儲信息六荒?
運(yùn)行一個(gè)發(fā)布版時(shí),應(yīng)用是否記錄日志跟蹤信息矾端?
應(yīng)用代碼有沒有混淆掏击?
應(yīng)用是否對外暴露任何content provider, receiver或者service給其他應(yīng)用?
發(fā)行版中秩铆,應(yīng)用的“debuggable”標(biāo)志是否被禁用了砚亭?
推送通知:
推送通知是一種可以在任何時(shí)候保持用戶關(guān)注相關(guān)內(nèi)容的良好機(jī)制,但是這個(gè)問題并不像第一眼看起來那么簡單殴玛。
應(yīng)用是否使用第三方庫來實(shí)現(xiàn)推送通知系統(tǒng)捅膘?
GCM系統(tǒng)是否用來給應(yīng)用通過推送通知來發(fā)送信息還是只是用來給用戶顯示消息?(這個(gè)問題沒有理解清楚)
應(yīng)用收到推送通知后的行為是什么族阅?
如果和推送通知關(guān)聯(lián)的信息并不是我們想要的篓跛,這時(shí)應(yīng)用的行為又是什么?
通知是否使用了兼容API來顯示給用戶坦刀?
性能:
性能非常關(guān)鍵愧沟。沒人希望在自己購買的設(shè)備上運(yùn)行一個(gè)又爛又慢的應(yīng)用蔬咬。性能就是金錢。
應(yīng)用是否有內(nèi)存泄露沐寺?
開發(fā)版構(gòu)建中是否配置了類似“LeakCanary”這樣類似的內(nèi)存分析工具林艘?
開發(fā)版構(gòu)建中是否配置并啟用了Strick Mode?
應(yīng)用的線程使用情況怎么樣混坞?有沒有使用async task狐援,intent services或者其他第三方庫?
后臺線程的數(shù)量是否造成了性能問題究孕?
有沒有使用任何線程調(diào)度策略啥酱,還是有需要就創(chuàng)建線程?
有沒有隨時(shí)關(guān)注Android的Doze Mode厨诸?
應(yīng)用是否監(jiān)聽了網(wǎng)絡(luò)狀態(tài)事件镶殷,或者其他操作系統(tǒng)的重復(fù)事件?
主線程是否只用來執(zhí)行用戶界面相關(guān)的任務(wù)微酬?
應(yīng)用有沒有使用任何緩存策略绘趋?
HTTP客戶端有沒有配置超時(shí)?
HTTP客戶端有沒有配置GZIP壓縮颗管?
UI能否達(dá)到每秒60的幀率陷遮?
有沒有分配大量內(nèi)存,或者在UI線程執(zhí)行耗時(shí)炒作的自定義控件垦江?
有沒有在低端設(shè)備上測試你的應(yīng)用帽馋?
自循環(huán)列表控件(recycler view)的滾動有沒有卡頓?
圖片處理實(shí)現(xiàn)使用了第三方庫還是用自定義的解決方案疫粥?
使用圖片的時(shí)候是在設(shè)備上縮放到屏幕大小還是下載和屏幕大小相關(guān)聯(lián)的圖片茬斧?
內(nèi)存使用是否合理?
有沒有正確使用“static”修飾符梗逮?
有沒有圖片管理相關(guān)的功能一次同時(shí)處理一張以上的圖片的情況?
狀態(tài)跟蹤系統(tǒng)是不是運(yùn)行在一個(gè)正確配置了優(yōu)先級的后臺線程上绣溜?
代碼是否在發(fā)行版構(gòu)建中做了優(yōu)化慷彤?
Java包結(jié)構(gòu):
好的包結(jié)構(gòu)可以讓代碼更好擴(kuò)展
包是根據(jù)功能還是概念來分割的?比如怖喻,登錄(Login)相對與用戶(User)底哗。
在包內(nèi)部有沒有使用java的可見性修飾符來隱藏實(shí)現(xiàn)細(xì)節(jié)?
有沒有包游離在根包之外锚沸?
測試目錄和源代碼目錄是否遵循了同樣的包結(jié)構(gòu)跋选?
功能需求是否用同樣的包結(jié)構(gòu)來組織?
有沒有任何放在不正確包里面的類哗蜈?
有沒有遵循一定的命名規(guī)范前标,這樣包命名就可以比較一致坠韩?
根包的名字是否和公司名字相關(guān)?
代碼風(fēng)格:
風(fēng)格一致的代碼基礎(chǔ)庫可以讓工程師更容易閱讀代碼炼列。工程師通常讀的代碼遠(yuǎn)多于寫的代碼只搁,所以這個(gè)概念很重要。
風(fēng)格是否保持一致俭尖?
是否使用匈牙利命名法氢惋?
有沒有配置并通過代碼風(fēng)格檢查工具?
代碼是否遵循java的代碼風(fēng)格稽犁?
使用tab還是空格焰望?
類名是否正確?
使用“I”作為接口前綴還是使用“Impl”作為后綴已亥?
變量名是否正確熊赖?
字段命名是否正確?
方法命名是否正確陷猫?
屬性和方法的可見性修飾符是否正確使用了秫舌?
代碼是否用英語來寫?
是否使用javadoc绣檬?
是否寫注釋足陨?
是否使用常量或者枚舉量來避免出現(xiàn)重復(fù)的字面量?
離線實(shí)現(xiàn):
好的離線體驗(yàn)是我們應(yīng)用的一個(gè)差異化因素娇未。
斷網(wǎng)時(shí)應(yīng)用是否可以正常使用墨缘?
網(wǎng)速慢時(shí)應(yīng)用的行為是什么?
網(wǎng)絡(luò)請求被網(wǎng)絡(luò)中斷時(shí)應(yīng)用的行為是什么零抬?
應(yīng)用的數(shù)據(jù)更改是否在應(yīng)用后端連接恢復(fù)時(shí)馬上進(jìn)行同步镊讼?
網(wǎng)絡(luò)連接有沒有設(shè)置超時(shí)?
有沒有配置HTTP緩存策略平夜?
用戶會話是否自動重新協(xié)商蝶棋?
架構(gòu):
代碼角度的應(yīng)用架構(gòu)是整個(gè)審查規(guī)則中讓我們對應(yīng)用有更多洞察的一部分。在應(yīng)用架構(gòu)復(fù)審的時(shí)候我們將關(guān)注SOLID相關(guān)的概念以及Clean Code原則忽妒。
展示層實(shí)現(xiàn):
針對GUI實(shí)現(xiàn)玩裙,應(yīng)用有沒有相應(yīng)的模式?MVP和MVVM可能時(shí)開發(fā)應(yīng)用時(shí)最常見的兩種模式段直。有沒有正確實(shí)現(xiàn)呢吃溅?
展示層實(shí)現(xiàn)是否和顯示層實(shí)現(xiàn)耦合了?
顯示層實(shí)現(xiàn)和模型層實(shí)現(xiàn)是否耦合了鸯檬?
展示層是否實(shí)現(xiàn)了業(yè)務(wù)需求决侈?
顯示層實(shí)現(xiàn)是否正確使用了Android SDK里面提供的工具?
是否使用了第三方庫來簡化顯示層實(shí)現(xiàn)喧务?
不同特性用activity還是fragment實(shí)現(xiàn)赖歌?
公共的UI行為是否統(tǒng)一處理了枉圃?
有沒有使用自定義控件來重用UI代碼?
領(lǐng)域?qū)崿F(xiàn):
領(lǐng)域?qū)由踔琳f全部業(yè)務(wù)邏輯是否有在展示層實(shí)現(xiàn)俏站?
領(lǐng)域規(guī)則和不同應(yīng)用的需求是否在主要的業(yè)務(wù)邏輯主體里面進(jìn)行描述讯蒲?
領(lǐng)域?qū)訉?shí)現(xiàn)是否用了面向?qū)ο蟮脑瓌t?
領(lǐng)域?qū)訉?shí)現(xiàn)是否和Android SDK或者任何第三方庫耦合肄扎?
領(lǐng)域?qū)邮欠窈驼故緦玉詈希?/p>
領(lǐng)域模型是否很少墨林?
是否使用大量的領(lǐng)域模型?
代碼是否構(gòu)建在高內(nèi)聚低耦合的模塊中犯祠?
錯(cuò)誤處理時(shí)用Exception還是其他錯(cuò)誤處理機(jī)制實(shí)現(xiàn)旭等?
不同層次的數(shù)據(jù)是否進(jìn)行了映射?
外部設(shè)計(jì)(比如數(shù)據(jù)庫模型或者JSON解析)是否影響領(lǐng)域模型設(shè)計(jì)衡载?
開發(fā)者有沒有濫用繼承搔耕?
代碼是否重復(fù)?
有沒有使用依賴注入庫或者服務(wù)發(fā)現(xiàn)器痰娱?
類或者方法復(fù)雜度是否過高弃榨?
API客戶端實(shí)現(xiàn)
API客戶端實(shí)現(xiàn)是否和Android SDK耦合?
API客戶端是否泄露了HTTP客戶端或者網(wǎng)絡(luò)層實(shí)現(xiàn)的相關(guān)細(xì)節(jié)梨睁?
API客戶端是否發(fā)送了正確的頭鲸睛?
對應(yīng)不同的HTTP相應(yīng),API客戶端的行為是什么坡贺?
API客戶端是否實(shí)現(xiàn)了驗(yàn)證機(jī)制官辈?
刷新會話的過程是否正確實(shí)現(xiàn)了?
JSON序列化工具是否支持混淆遍坟?
API客戶端是否和不同API分割開(這里沒有完全理解)?
存儲實(shí)現(xiàn):
信息存放在哪里拳亿?
從存儲讀出或者寫入數(shù)據(jù)時(shí)有沒有使用事務(wù)?
存儲是否安全存放了用戶的敏感信息愿伴?
數(shù)據(jù)層是否使用第三方庫肺魁?
數(shù)據(jù)層是否泄露了實(shí)現(xiàn)細(xì)節(jié)?
存儲的表或者模型是否正確建模了隔节?
發(fā)送到存儲的請求是否做了優(yōu)化万搔?
是否在正確的場合使用了Android SDK的持久化API?數(shù)據(jù)放數(shù)據(jù)庫官帘,選項(xiàng)或者小數(shù)據(jù)放Shared Preferences,文件存放在磁盤上昧谊?
可測試性:
應(yīng)用是否有測試刽虹?
應(yīng)用是否可測試?
應(yīng)用是否覆蓋不同測試(單元測試,集成測試抛计,端到端測試)抱慌?
測試命名是否正確鹰椒?
測試是否正確劃分了范圍博秫?
測試中有沒有過度描述鲤看?
測試執(zhí)行事件是否合理沙热?
測試覆蓋率是否過低侣滩?
有沒有被忽略的測試初烘?
有沒有不可靠的測試涡真?
有沒有使用最新的測試框架?
有沒有沒有斷言的測試肾筐?
測試是否由實(shí)現(xiàn)線上代碼的相應(yīng)開發(fā)者編寫哆料?
有沒有手工QA團(tuán)隊(duì)?
有沒有QA團(tuán)隊(duì)自動化部分測試吗铐?
有沒有持續(xù)集成系統(tǒng)东亦?
有沒有使用構(gòu)造類,工廠類或者母親類來減少創(chuàng)建測試所需實(shí)體的麻煩唬渗?
測試斷言是否正確編寫典阵?
每個(gè)測試是否執(zhí)行了超過一個(gè)邏輯斷言?
同一個(gè)項(xiàng)目是否有不同的測試套件镊逝?
測試應(yīng)用不同部分時(shí)壮啊,你是否使用了不同的測試方法?
有沒有使用monkey runner蹋半?
你是否遵循TDD或者BDD方法論他巨?
是否使用java編寫測試用例?
根據(jù)這個(gè)列表的不同主題减江,我們能夠確保應(yīng)用的質(zhì)量染突。我們還考察一些其他的點(diǎn),但是這個(gè)列表包含了最重要的部分辈灼。你能給出這些問題的正確回答嗎份企?