2010-08-18 30 views
2

大家都喜歡單元測試。但是測試實體的持久性有點不同。您正在使用不同的語言測試跨多個圖層的過程。你的測試有副作用(在行被添加/修改等的意義上)。測試實體持久性的方法和建議

我想知道你是如何做到這一點的。例如,您的測試是否會創建一個全新的數據庫模式並每次都放棄它?您是否必須維護用於測試模式創建的SQL腳本,並讓它們與生產數據庫保持同步?你甚至可以測試你在生產中使用的相同數據庫產品嗎?你是隨機產生你的實體的狀態,還是總是使用相同的值?你如何配置你的測試,以確保它們是針對測試數據庫而不是生產測試數據庫執行的?

在這方面可能有一堆我沒有想到的重要問題。爲了爭分奪秒,我會將答案標記爲似乎副作用最小並且最容易實現的答案。

+0

哇,我真的希望有更多的意見,而不僅僅是兩個。也許不是一場完整的火焰戰爭,但也許是一些教育方面的分歧。 – David 2010-08-18 15:50:31

回答

1

單元測試數據持久性幾乎是不可能的,所以我通常在集成層面上做。

關於數據庫,在我當前的項目中,集成測試套裝確實會刪除整個模式,並從頭開始重新創建所有內容(當測試從構建服務器運行時使用)。但是,您也可以針對已經創建的數據庫運行測試 - 如果您正在從機器進行測試/調試,並且不想浪費時間或鬆散測試數據,則這是有意義的。你應該維護你的數據庫腳本(它們應該和生產腳本一樣) - 這樣你就可以測試你的腳本以及你的.Net代碼。一般來說,腳本不會創建任何數據(可能除了靜態數據) - 它應該成爲測試的一部分,以創建測試數據,對其執行一些操作並驗證期望值 - 確保您可以針對每個數據庫運行測試正確的模式。在創建測試數據時,我們通常會使用隨機標識符和唯一字段並硬編碼其他所有內容

關於環境管理,您應該已經有一些機制來配置數據庫連接(以便您可以擁有測試和生產環境) - 有很多方法可以實現它,包括Microsoft產品和內部解決方案 - 所以你應該使用相同的方式來配置你的構建機器。

+0

我想這幾乎是我想象的。一個相當的工作實施,加上可能會煩人保持我猜。但不痛不收! – David 2010-08-18 11:00:45

0

我的方法是創建一套用於測試數據訪問層(存儲庫和映射)的集成測試。我認爲這是非常重要的,如果你使用ORM工具,它使用「約定配置」方法 - 比如EF中的POCO映射。我有數據庫初始化腳本,它創建新的數據庫(與當前的開發數據庫相同)並創建初始測試數據集。該腳本在測試運行開始時只運行一次。數據庫在測試運行結束時被刪除。每個集成測試使用在測試結束時回滾的事務,因此所有測試的測試數據都是相同的。驗證數據庫中的數據我使用標準SqlCommand方法使用助手類。要使用SqlCommand,您必須爲您的測試使用ReadUncommited事務隔離級別,因爲您通常不會在SqlCommand和EF上下文之間共享連接。

+0

謝謝 - 有趣。我有點不確定你爲什麼回滾事務。正如你所說,你必須使用ReadUncommitted隔離級別。爲什麼不使用SqlCommand輔助類來運行一些SQL來刪除相關表中的行呢? – David 2010-08-18 10:59:49

+0

因爲在這種情況下,您必須爲每個與回滾具有相同結果的測試創建清理代碼。 – 2010-08-18 13:00:00

1

在過去的六年裏,我主要使用NHibernate進行持久化。

在單元測試級別上,我使用內存中的SQLite測試持久性/實體映射,並在集成測試級別上使用真實數據庫服務器(本地和構建服務器)。

在這兩種情況下,我設置數據庫與NHibernate的/功能NHibernate可以爲你每個測試(並在整合之後的情況下殺DB)的腳本。這需要更長的時間才能運行,但恕我直言,清理代碼變壞的風險更糟(順便說一下,在xUnit測試模式書中有關於此的討論)。

+0

但是這隻有在你使用模型第一種方法時纔有效,不是嗎? – 2010-08-19 08:55:43

+0

是的。我自己是DDD /「Model + POCO第一人」。 – 2010-08-19 08:57:38