【问题标题】:Unit-Testing: Can module re-exports avoid having to "expose" all testable modules单元测试:模块重新导出是否可以避免“暴露”所有可测试模块
【发布时间】:2015-11-09 23:19:35
【问题描述】:

TLDR:是否可以使用模块重新导出来避免“暴露”所有可测试模块?

我在我的 Haskell 项目中使用了类似于 Chris Done 模板的东西。我的ventureforth.cabal 文件包含以下部分:

library
  hs-source-dirs:      src
  exposed-modules:     VForth,
                       VForth.Location
  build-depends:       base >= 4.7 && < 5
  ghc-options:         -Wall -Werror
  default-language:    Haskell2010

executable ventureforth
  hs-source-dirs:      app
  main-is:             Main.hs
  build-depends:       base >= 4.7 && < 5,
                       ventureforth -any
  ghc-options:         -Wall -Werror -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

test-suite ventureforth-test
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base >= 4.7 && < 5,
                       ventureforth -any,
                       doctest >= 0.9 && < 0.11,
                       hspec -any
  ghc-options:         -Wall -Werror -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

我的代码布局为

ventureforth/
 |
 +- ventureforth.cabal
 +- app/
 |   |
 |   +- Main.hs
 |
 +- src/
 |   |
 |   +- VForth.hs
 |   +- VForth/
 |       |
 |       +- Location.hs
 |
 +- test/
 |   |
 |   +- Spec.hs
 |   +- VForth
 |       |
 |       +- LocationSpec.hs

我已设置VForth.hs 重新导出VForth.Location

module VForth (
    module VForth.Location
) where

import VForth.Location

VForth.LocationSpec 单元测试中,我只需要import VForth 来测试Location 类型。

但是,除非我将添加 VForth.Location 添加到“公开模块”列表中,否则在尝试运行 cabal test 时会遇到链接器错误。

我曾认为公开一个模块 VForth,它重新导出所有其他模块就足够了。我真的陷入了不得不在 cabal 中列出每个源文件的境地吗?

【问题讨论】:

标签: haskell


【解决方案1】:

所以最终这是不可避免的。然而,仔细想想,这也是一种很好的行为。由于我正在创建一个库,而 Haskell 语言无法控制模块的可见性,因此我必须指定要在 Cabal 中导出哪些模块。

为了充当测试,我的测试不应该对我的库客户端所做的应用程序有任何额外的访问权限。因此,我的测试无法访问我的库的客户端也无法访问的任何模块是可以接受的。

然而,在实践中,我想要测试一些未公开的内部元素。因此,我将我的测试套件分为两个,一个是内部的,另一个是外部的,分别测试这些不同的方面。

test-suite ventureforth-test-external
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test
  main-is:             Spec.hs
  build-depends:       base >= 4.7 && < 5,
                       ventureforth -any,
                       hspec -any
  ghc-options:         -Wall -Werror -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

test-suite ventureforth-test-internal
  type:                exitcode-stdio-1.0
  hs-source-dirs:      test,src
  main-is:             Spec.hs
  build-depends:       base >= 4.7 && < 5,
                       hspec -any
  ghc-options:         -Wall -Werror -threaded -rtsopts -with-rtsopts=-N
  default-language:    Haskell2010

内部测试可以直接访问源代码,因此不会导入库。

最后,作为“内部”测试的第二个来源,我也在使用 doctest,如 Haskeleton project setup guide 中所述

最后,对于构建 Haskell 项目的任何其他人,请注意,您可以使用 Haskell Init tool 在同名目录中创建一个名为 my-project-name 的框架项目,并设置所有测试位和 bobs 并准备好去

hi my-project-name \
    --repository git://github.com/tfausak/haskeleton.git \
    --package-name my-project-name \
    --module-name MyProjectName \
    --author Bryan Feeney \
    --email bryan.feeney@mailserver.com

存储库标志提供了模板项目的路径。 Haskeleton 模板具有单元测试、文档测试和基准测试。其他项目模板,例如 web-apps,可以在 HI templates page 上找到。要安装 Haskell Init 工具,只需键入

cabal install hi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    相关资源
    最近更新 更多