2012-07-16 80 views
5

我最近參與了一些使用PHPUnit的TDD。 我必須測試一個數據庫驅動的應用程序,並閱讀我計劃在未來幾周內研究和實現的DbUnit擴展。但是,我自己也碰到過這個人 - Sebastian Bergmann - 他有一張幻燈片,題目是「如果可以的話,避免對MySQL進行測試」,這對我的冒險行爲產生了一些疑問。爲什麼我應該避免使用DbUnit來測試MySQL?

有人可以解釋爲什麼我不應該針對MySQL測試的原因嗎?

感謝

+0

鏈接的演示文稿不再可用。 :( – SDC 2012-11-06 10:41:01

+0

@SDC:演示文稿PDF可在[幻燈片共享框下面的非風格鏈接](http://en.oreilly。COM/mysql2008 /公/資產/附件/ 1980)。 (咆哮:這就是爲什麼我說[鏈接應該看起來像一個鏈接](http://web.archive.org/web/20100713205344/http://my.opera.com/CrazyTerabyte/blog/web-design -tip-a-link-should-look-like-a-link)) – 2014-06-06 22:30:25

回答

6

兩個原因:

  • 它是緩慢的(和單元測試需要要快)
  • 它增加了額外的故障點,超出你的控制(沒有測試真正失敗當數據庫連接失敗?)

相反,作爲建議你應該測試你的DAL與內存數據庫,如SQLit即這消除了上述問題。

然而,這種方法也有它的缺點太 - 你可能有從一個數據庫方言SQLite的移植SQL的問題。這自然意味着你將無法測試你的DAL的MySQL特定部分。與往常一樣,這是一把雙刃劍 - 你會得到單元測試的速度和隔離,但是你失去了可信度(如果我們可以這樣調用它) - 如果它通過SQLite,你能100%確定它在MySQL上工作嗎?

它可能並不壞主意離開你的DAL/DAO測試,集成測試階段,在那裏你會測試他們的核心agains使用,離開了單元測試的小東西真正的數據庫引擎;例如映射(如果你使用的是ORM)。

編輯:在快速絕非嚴格的要求 - 這是一個好的一般建議。在做TDD的開發人員運行單元測試很多(這樣的想法,每次提交到本地回購/每重要代碼變化將需要通過運行單元測試代碼庫的完整性檢查) - 也許不是所有的人,但肯定一些。你希望這個過程很快。

現在,有慢測試通常結尾是這樣的:

  • 「夥計,這東西跑這麼慢......」
  • 「也許我可以運行只是少數人...我要跑剩下的以後」
  • 在這一點上,我們知道以後還沒有出現
  • ‘嘿,我上次提交沒有破壞任何東西,我沒有運行在所有的任何測試!’
  • 「爲什麼我要運行它們呢?」

編寫沒有運行的測試,幾乎殺死了寫它們的目的。

這件事發生在與我一起工作的朋友身上;他的團隊測試套件運行+/- 20分鐘(DAL測試做得不好,參與測試的IoC容器),開發商開始運行一些測試,不一會兒「當前構建斷路器」的電子郵件成爲日常用品。他們有相當大的套件,但打破測試是沒那麼差

總體而言,您的方法似乎是正確的 - 我不會將測試移動到SQLite。就像我建議的那樣,使用集成測試套件對數據庫層進行測試(以便它可以與普通的單元測試套件分開運行)。

+0

感謝您的明確回答。我們遇到的問題是我們正在嘗試儘可能進行單元測試(例如,每個新的錯誤修復/增強都應該有一個與之相關的單元測試)。當錯誤修復/增強僅僅是一個新的和改進的SQL查詢時,這是否合理可行?如果DbUnit不推薦用於Mysql,那麼測試這些修補程序的標準過程是什麼(不使用SQLite方法)?將所有東西移植到SQLite似乎有點矯枉過正。 – user1027562 2012-07-17 11:17:12

+0

另外,爲什麼單元測試**需要**快速?我們沒有當前的要求來優化我們的單元測試流程,而且我不明白爲什麼這會非常重要? (我是TDD的noob,因此任何啓發都會被讚賞) – user1027562 2012-07-17 11:47:00

+0

當你運行他們很多。每次提交時,都應該儘可能多地運行自動化測試。理想情況下(和「構建」不是一個構建,直到所有的自動化測試運行並通過)。如果這需要不到10分鐘,那麼它是令人討厭的,但可以接受,但超過十分鐘,並停止被接受。 – 2012-07-17 16:20:25

2

我使用DbUnit來測試我的模型(說到MVC,包括ORM模型),因爲它們與數據庫密切相關。對於其他任何東西(主要是控制器),我使用模擬對象。

單元測試的基本思路是,以測試只是其中的一個應用程序代碼單元(這是一個類)的時間,所以最好避免使用DB除非代碼直接使用它。

當然,性能很重要。例如,我對模型進行了500次測試,幾乎所有的測試都使用DB和燈具。在一臺非常快的計算機上執行所有這些測試需要大約30-40秒。代碼覆蓋率報告生成大約需要一分鐘。

3

我完全不同意Sebastian Bergmann寫的幻燈片33的標題。

(因爲從幻燈片上的信息可以很容易地被誤解,我 肯定,在他的講座中,他解釋了真正意義)

正如在他的介紹調試吮吸說,但測試岩石

如果真實環境使用mySQL你必須對mySQL進行測試。否則,你會發現自己正在調試SQLite和mySQL之間的區別。

我相信,他的方向給開發商,而不是單元測試,在這個意義上我也建議開發人員可以保持他們的代碼數據庫中和成爲可能需要的任何努力。它將改善項目整個生命週期的質量,而不僅僅是單元測試人員。它甚至可以保護mySQL本身的功能。 (過去有很多問題)。

但是,當測試使用SQL的單一代碼時,無論您已經做了哪些其他測試,您必須必須對真實的東西進行測試。

我的做法是創建一個數據庫連接的抽象層,並進行測試以與該層作出反應。隨後,我爲每個要測試的數據庫服務器創建不同的具體類。

按照給定的,我們可以測試frequenlty對SQLite的這個環境,但真正的測試將每天至少運行一次。

相關問題