2013-01-17 68 views
36

如何處理Haskell中的函數可見性和單元測試?函數隱私和單元測試Haskell

如果您導出模塊中的每個函數以便單元測試可以訪問它們,則可能會有其他人調用不應該在公共API中的函數。

我想用{-# LANGUAGE CPP #-},然後圍繞着出口與#ifdef

{-# LANGUAGE CPP #-} 

module SomeModule 
#ifndef TESTING 
(export1 
, export2 
) 
#endif 
where 

有沒有更好的辦法?

+0

可能的重複https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods-fields-or-inner-classes – Raedwald

回答

55

通常的慣例是你的模塊分成公共和私人部分,即

module SomeModule.Internal where 

-- ... exports all private methods 

,然後公共API

module SomeModule where (export1, export2) 

import SomeModule.Internal 

然後你就可以導入在測試中和其他地方SomeModule.Internal其至關重要的是獲得內部實施。

的想法是,你永遠庫意外電話私有API的用戶,但是他們可以使用它,如果知道他們在做什麼(調試等)。與強制隱藏私有API相比,這大大增加了您的庫的可用性。

+1

這會影響內聯(編譯時優化)?閱讀https://www.haskell.org/haskellwiki/Performance/GHC#Inline它似乎會...所以你可以寫單元測試或優化? (請告訴我,我錯了!) – tlo

+0

如果擔心通過此技術禁用內聯優化,請注意,您仍然可以使用明確內聯來確保它發生。 – Jules

+0

對於任何想使用Haskell-Stack的建議,要創建'SomeModule.Internal'模塊,您需要創建一個合適的目錄結構 - 請參閱[此問題](https://stackoverflow.com/questions/28193295/)負載一個模塊式-ghci中逐模塊名稱時模塊名稱管理犯規匹配文件名稱)。 – hnefatl

7

爲了測試您通常將應用程序拆分爲cabal項目文件,庫,生產可執行文件和測試庫函數的可執行文件之間,因此測試斷言功能保持分開。

對於外部功能可見性,您可以在「exposed-modules」部分和「other-modules」部分之間拆分庫模塊。

+0

這裏供參考的是一個可執行文件的cabal包的例子,它被分割成庫和可執行文件:http://www.haskell.org/cabal/users-guide/developing-packages.html#configurations –

+0

測試套件包含對'other-modules'部分的模塊的測試?單元測試內部結構並沒有將它們暴露給外部客戶聽起來對我來說是非常可取的。 – Blaisorblade

+1

@Blaisorblade是的,測試套件從'other-modules'訪問模塊的方式是在cabal文件'hs-source-dirs:src,test'中指定測試套件。換句話說'src'也被編譯在測試套件中。缺點是,你再編譯你的源碼兩次:正常的方式,然後再次測試。但這是我知道的最好方式。 –