2011-06-07 52 views
3

我一直在做單元測試,遇到了這個奇怪的壞問題。Zend Session Handler Db表在PHPUnit測試期間被破壞

我正在用我的一些服務/映射器進行用戶認證測試。

我跑了,所有307個測試現在一起。這隻有當我在一批中運行它們時才真正發生。

我嘗試僅實例化一個Zend_Application對象,並將其用於我的所有測試。我只是實例化它來照顧數據庫連接,會話和我的類的自動加載。

這是問題所在。

沿測試線的某處,調用Zend_Session_SaveHandler_DbTable的__destruct方法。我不知道爲什麼?但它確實如此。

__destruct方法將呈現任何寫入我的會話對象無用,因爲它們被標記爲只讀。

我不知道爲什麼要調用destruct方法。

它在我的認證測試之前被調用了很多測試。如果我單獨運行每個測試文件夾,則沒有問題。只有當我嘗試運行所有307個測試時。我確實有一些做數據庫工作的測試,但是我的代碼沒有關閉數據庫連接或破壞保存處理程序。

有沒有人有任何想法,爲什麼會發生這種情況,爲什麼我的Zend_Session_SaveHandler_DbTable被破壞?這與默認的一生有什麼關係?

回答

1

我認爲發生了什麼是PHPUnit正在做垃圾回收。每當我運行307測試時,垃圾收集器都必須運行,並且由於某種原因它可能會破壞Zend_Session_SaveHandler_DbTable。

這可以解釋爲什麼在更少的測試運行時它沒有被破壞。

或者也許是PHP做垃圾回收,這樣做更有意義。

無論哪種方式,我目前的解決方案是爲每個測試類創建一個新的Zend_Application對象,以便該類中的所有測試都有一個新的zend_application對象。

這裏有一些有趣的信息。

我在savehandler的__destruct方法中放置了一個echo語句。

該方法被稱爲(X + 1)次,其中X是我運行的測試次數。如果我跑50次測試,我得到51回聲,307測試,然後308回聲等。

這是有趣的部分。如果我只進行了一些測試,回波就會在測試運行的最後完成。如果我試圖運行所有307次測試,90次測試之後會出現90次回聲。其餘的回聲會在剩下的測試結束時出現。回聲的數量再次是X + 1,或者在這種情況下是308。

所以,這是我假設這與PHPUnit調用的tearDown方法或PHP垃圾回收器有關。也許PHPUnit在拆解時調用垃圾回收器。誰知道,但我很高興現在能夠正常工作,因爲我的測試全部都是事先通過的。

如果您有任何更好的解決方案,請告訴我。也許我發現了我的代碼,phpunit或zend中的一個缺陷,這個缺陷之前並不知道,並且有一些方法可以解決它。

+0

我認爲理論上你會想要一個新的應用程序對象爲每個測試。但實際上,當我們確信每個後續測試都是原始的時候,使用相同的對象往往是一種方式。他們都在同一個測試套件中嗎?在不同的套件中進行測試有助於解決這類問題。如果你發現兩次_destruct被調用兩次,你可能會發現什麼阻礙了你的測試。祝好運,+回覆您的發現。 – stefgosselin 2011-06-08 03:10:31

+0

嘿,我有我的引導文件創建一個全局zend_application對象,並將其放入$ GLOBALS變量。然後,每個測試類將在它的setUpBeforeClass/SetUp方法中獲取應用程序對象。 我沒有調度任何控制器或任何東西。我實例化它的原因是因爲可以調用應用程序來設置我的模型的自動加載和數據庫/認證測試的數據庫連接。 – 2011-06-08 12:28:29

+0

我所有的測試都在其他文件夾的「應用程序」文件夾中。在PHP單元中,如果我指定了子文件夾,那麼一切都很好。但是,一旦我試圖運行每一個測試,事情就變得糟糕。 我認爲我錯過了某種可以解釋所有這些的PHPUnit行爲。 – 2011-06-08 12:30:33

1

這是一個古老的問題,但我剛剛遇到同樣的問題,並找到解決方案here。我認爲這是解決問題的正確方法。

Zend_Session::$_unitTestEnabled = true;