2015-01-01 25 views
1

我正在嘗試將單元測試應用於正在處理的項目。我使用Python和MySQLdb工作,但我認爲這個討論是與語言無關的。 我想測試一個函數,我們稱之爲foobar()。它執行與以下類似的SQL查詢:數據庫連接是否應該被模擬?

cursor.execute("SELECT * FROM my_table WHERE a == " +varA+ " AND b < " +varB) 

函數中存在一點點複雜性。 cursor.execute(query)被調用的方式和頻率取決於foobar的參數。

現在我不確定是否應該模擬數據庫連接cursor。 如果我不這樣做,這很糟糕,因爲測試取決於數據庫服務器的可用性。 如果我這樣做,這很糟糕,因爲模擬必須知道哪些查詢將被調用。但確切的查詢是一個實現細節。例如。查詢是寫成小寫還是大寫不影響foobar的正確性。但改變這將打破測試。由於有些複雜的模擬對象,測試也很難閱讀。

這是選擇較小的邪惡?有第三種方法嗎?

+0

只有當這個話題很大時纔有這麼小的問題? – hakre

回答

0

不,您不應該模擬遊標或連接。重構代碼並將此代碼提取到單獨的服務/存儲庫。應該是需要行的兩個參數varAvarB並返回列表的方法/對象

    你快/單元測試
  • 你應該嘲笑整個倉庫 - 檢查你的方法被調用合適的參數(varAvarB )。
  • 在慢/集成測試,你應該檢查是否你真正數據庫中嘲諷連接/光標你要做的僅僅是實現數據庫正確執行這個查詢所有可能varAvarB

- 它只是浪費時間

0

您已經在權衡利弊方面做得很好,但需要注意的一點是,測試的目的是模擬接近生產中可見的確切條件。

您應該避免嘲笑數據庫連接並讓它從本地Mysql數據庫實例讀取數據。此外,確保在每次測試之前db的狀態被重置,以確保測試模塊化。

的一般工作流程是 -

  1. 之前所有測試創建模式myApp_test,如果它不存在。
  2. 刪除所有表並從模擬數據裝置重新創建它們。您可以通過多種方式來完成這項工作,我最喜歡的是從YML配置文件中讀取燈具並將它們直接插入到數據庫中。 (如果您正在使用像rails這樣的框架,它具有預先構建的功能來執行此操作,或者有其他語言的許多寶石和庫可能有助於實現此目的。)
  3. 在每次測試之前,請致電在步驟2中的功能重新設定DB
  4. 運行測試

針對您的問題,我不認爲這是一個問題,它依賴於一個DB可用,尤其是地方政府。如果您正在運行測試,指定您應該有可用的數據庫並非不合理。或者,如果您真的關心數據庫的可用性,您可以嘗試使用SQLite或其他基於文本的本地數據庫在本地創建自己的數據庫。

+0

對真實數據庫運行單元測試(即使它是爲測試目的而創建的本地數據庫),使它們變得緩慢而脆弱。 – buxter

相關問題