你如何处理Haskell中的函数可见性和单元测试?
如果您将模块中的每个函数都导出,以便单元测试可以访问它们,那么您会冒险让其他人调用不应该在公共API中的函数。
我考虑使用{-# LANGUAGE CPP #-}
然后用#ifdef
包围导出部分:
{-# LANGUAGE CPP #-}
module SomeModule
#ifndef TESTING
( export1
, export2
)
#endif
where
有没有更好的方法?
你如何处理Haskell中的函数可见性和单元测试?
如果您将模块中的每个函数都导出,以便单元测试可以访问它们,那么您会冒险让其他人调用不应该在公共API中的函数。
我考虑使用{-# LANGUAGE CPP #-}
然后用#ifdef
包围导出部分:
{-# LANGUAGE CPP #-}
module SomeModule
#ifndef TESTING
( export1
, export2
)
#endif
where
有没有更好的方法?
通常的约定是将您的模块分为公共部分和私有部分,即:
module SomeModule.Internal where
-- ... exports all private methods
然后是公共API
module SomeModule where (export1, export2)
import SomeModule.Internal
那么在测试和其他需要获得内部实现的地方,你可以导入SomeModule.Internal
。
这个想法是,库的用户永远不会无意中调用私有 API,但如果他们知道自己在做什么(例如调试),就可以使用它。与强制隐藏私有 API 相比,这大大增加了您的库的可用性。
进行测试时,通常会在cabal项目文件中将应用程序分为库、生产可执行文件和test-suite可执行文件,以测试库函数,因此测试断言函数被保留。
对于外部函数的可见性,您需要在库模块之间划分“exposed-modules”部分和“other-modules”部分。
other-modules
模块的方法是在cabal文件中指定hs-source-dirs: src, tests
。换句话说,src
也会在测试套件中编译。缺点是您需要将源代码编译两次:正常编译和测试编译。但这是我所知道的最好的方法。 - Emmanuel Touzery