2016-02-01 80 views
3

我想用真實設備測試我的程序庫調用的效果。這個調用啓動一個服務,該服務向服務器發送一個HTTP請求,該服務器的URL在資源中被硬編碼。嘲笑Android儀器測試上的資源

我想驗證請求是否正確發送。所以我設置了一個本地HTTP服務器,但爲了能夠使用它,我必須改變/覆蓋/模擬資源,以便它指向http://127.0.0.1

我想做「端到端」測試;在這種情況下,儘管在本地,服務發出實際的網絡請求也很重要。

我試圖通過在androidTest/res/values/strings.xml中創建具有相同名稱的字符串資源來覆蓋該值,但該資源僅在測試包中可見,而不在應用程序包中。

使用Instrumentation類只允許我獲取Context引用,但無法用模擬或類似方法替換它(或返回值爲getResources())。

如何更改被測應用程序的資源值?

回答

2

你有幾個選擇:

  • 依賴注入
  • 存根/嘲笑
  • SharedPreferences
  • 腳本或gradle這個任務

依賴注入

使用庫像R oboGuice或Dapper。注入處理提出API請求的對象。然後,在您的測試設置中,您可以改爲使用測試版替換注射模塊。這樣你的測試代碼運行而不是原來的;該代碼可以傳遞不同的字符串(或者是硬編碼或者來自測試strings.xml)。

DI庫的設置可能很昂貴:高學習曲線,如果使用不當,可能會出現性能問題。如果對象的範圍/生命週期配置不正確,甚至可能會引入難以調試的問題。如果測試是使用DI的唯一原因,如果您對DI容器不熟悉,則可能不值得。

存根/嘲笑

結束語中的東西,實現你寫一個自定義界面您的來電。然後,您的主要實現將填充主機URL並調用API。然後,在測試中,使用該接口上的存根或模擬組合替換填充主機URL部分的代碼。

由於存根或模擬將替換部分代碼,因此這不是集成測試。但比建立依賴注入框架更簡單。

SharedPreferences

使用Android SharedPreferences系統。讓它默認爲某個端點(生產)。但允許應用程序在測試設備上啓動,然後使用一些對話框或設置來更改主機URL。再次運行測試,現在他們指向一個不同的API URL。

腳本或gradle這個任務

寫一些腳本或gradle這個任務是在某些情況下編譯之前修改源。

這可能是相當複雜的,甚至可能是過於平臺或系統相關的,如果不這樣做的權利。系統中的變化可能會相當脆弱。如果運行錯誤的命令來構建最終的打包版本並且錯誤的代碼投入市場,可能會引入錯誤。

個人觀點

裏面做建議?如果您和/或您的團隊熟悉RoboGuice或Dapper等DI庫,我建議您選擇此選項。這是最正式的,類型安全和嚴格的解決方案。它還保持更多的堆棧完整性來測試整個解決方案。

如果你不熟悉的一個很好的DI庫,存根/模擬考試和接口的包裝是一個很好的回退解決方案。他們部分必須在DI解決方案還是使用,你可以寫身邊足夠的測試涵蓋了良好的大多數需要測試(和在控制)的情況下。它已經足夠接近DI解決方案,我向那些在項目中不使用DI的人推薦。

的SharedPreferences解決方案爲QA和支持分期和生產環境之間切換的偉大工程。不過,我不會推薦它的自動化測試,因爲應用程序將最有可能被重新安裝/開發過程中經常重置,它將獲得煩人,經常重置該URL。另外,第一輪測試可能會失敗;在CI服務器會失敗,等無頭測試(你可能會違約的URL本地主機,但你跑的意外釋放默認生產的某個時候風險。)

我不建議腳本或砍死特寫gradle任務。過於脆弱,對其他開發者來說不太清晰,而且更復雜,那麼他們就值得,IMO。

+0

我們已經使用AndroidAnnotations不允許AFAIK改變生產代碼(它的單元測試工作的偉大,雖然) ,並且在相同的代碼中使用兩個DI框架可能會妨礙可維護性。我會避免使用SharedPreferences,因爲這會讓惡意用戶更容易在生產中放置不同的URL。我想出了另一個適用於我的選項,我會以答案的形式發佈。 –

+0

我們將URL終點對話框隱藏在一個簡單的4位代碼後面。所以要改變它,用戶必須聯繫我們。 –

0

除了約翰·亞當斯的解決方案,有一個進一步的一個:在建型

改寫資源

By default, a library module is built in release mode當它被其他模塊。調試模式僅用於測試(單元測試和儀器測試)。因此,使用資源覆蓋可以僅更改該庫的檢測測試的資源值,並在庫的用戶中使用原始值。

這有一些注意事項,但:

  • 儀表/集成測試必須留在庫本身,而不是在主應用程序包;
  • 同樣的資源值必須在所有測試共享的(除非使用產品口味)