功能隐私和单元测试Haskell

Ral*_*lph 43 haskell unit-testing private-methods

你如何处理Haskell中的函数可见性和单元测试?

如果导出模块中的每个函数以便单元测试可以访问它们,则可能会冒其他人调用不应该在公共API中的函数.

我想到使用{-# LANGUAGE CPP #-}然后用以下方法包围出口#ifdef:

{-# LANGUAGE CPP #-}

module SomeModule
#ifndef TESTING
( export1
, export2
)
#endif
where
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

sha*_*ang 66

通常的惯例是将您的模块拆分为公共和私有部分,即

module SomeModule.Internal where

-- ... exports all private methods
Run Code Online (Sandbox Code Playgroud)

然后是公共API

module SomeModule where (export1, export2)

import SomeModule.Internal
Run Code Online (Sandbox Code Playgroud)

然后,您可以导入SomeModule.Internal测试和其他对于访问内部实现至关重要的地方.

我们的想法是,您的库的用户永远不会意外地调用私有API,但如果知道他们正在做什么(调试等),他们可以使用它.与强制隐藏私有API相比,这大大增加了库的可用性.

  • 这会影响内联(编译时优化)吗?阅读https://www.haskell.org/haskellwiki/Performance/GHC#Inlining它似乎会...所以你可以编写单元测试或优化?(拜托,有人告诉我,我错了!) (2认同)
  • 对于任何试图使用哈斯克尔-Stack的这个建议,使`SomeModule.Internal`模块,你需要创建一个合适的目录结构 - 参见[这个问题](/sf/ask/1973530681/ -a模块功能于ghci中按模块名称时,模块名称犯规匹配文件名). (2认同)

Gab*_*iba 8

对于测试,通常将应用程序拆分在cabal项目文件中,库,生产可执行文件和测试库函数的测试套件可执行文件之间,因此测试断言功能保持分开.

对于外部功能可见性,您可以在"exposed-modules"部分和"other-modules"部分之间拆分库模块.

  • @Blaisorblade是的,测试套件从`other-modules`访问模块的方法是在cabal文件中指定`hs-source-dirs:src,test`用于测试套件.换句话说,`src`也在测试套件中编译.缺点是你然后编译你的源两次:正常的方式,然后再次测试.但那是我所知道的最好的方式. (2认同)