尽管 CPP 覆盖,但 hspec 仍无法导入(私有)代码依赖项



假设我有一个这样的src文件:

{-# LANGUAGE CPP #-}
module Alphabet (
#ifdef TEST
  alphabet
#endif
) where
  alphabet :: [Char]
  alphabet = "abcdefghijklmnopqrstuvwxyz"

像这样.cabal文件:

name:                Alphabet
version:             0.1.0.0
library
  build-depends:       base >=4.8 && <4.9, containers >=0.5 && <0.6, split >=0.2 && <0.3
  hs-source-dirs:      src
  Exposed-modules:     Alphabet
  default-language:    Haskell2010
test-suite alphabet-test
  ghc-options:         -Wall -Werror
  cpp-options:         -DTEST
  default-extensions:  OverloadedStrings
  type:                exitcode-stdio-1.0
  main-is:             Spec.hs
  hs-source-dirs:      tests
  build-depends:       Alphabet, base >= 4.8 && < 4.9, containers >= 0.5 && <0.6, split >= 0.2 && < 0.3, hspec, QuickCheck
  default-language:    Haskell2010

主测试文件如下所示:

 {-# OPTIONS_GHC -F -pgmF hspec-discover #-}

以及一个测试文件,例如:

module AphabetSpec (spec) where
  import Test.Hspec
  import Alphabet (alphabet)
  spec :: Spec
  spec = do
    describe "Alphabet.alphabet" $ do
      it "returns the alphabet" $ do
        alphabet `shouldBe` "abcdefghijklmnopqrstuvwxyz"
now running `cabal test`:
cabal test
Preprocessing library Alphabet-0.1.0.0...
In-place registering Alphabet-0.1.0.0...
Preprocessing test suite 'alphabet-test' for Alphabet-0.1.0.0...
[1 of 1] Compiling Main             ( tests/AlphabetSpec.hs, dist/build/alphabet-test/alphabet-test-tmp/AlphabetSpec.o )
tests/AlphabetSpec.hs:4:27:
Module ‘Alphabet’ does not export ‘alphabet’

为什么我的 CPP 没有按预期工作?我该如何解决它?

为什么我的 CPP 没有按预期工作?

两步式构建。由于您的测试依赖于库,因此首先构建它。库未设置任何 CPP 选项,因此不会导出alphabet

生成测试后,库已编译,alphabet不会导出。这是关注点的分离。

我该如何解决它?

有几个技巧可以使用"隐藏"(例如非导出)函数。首先,您可以将它们全部放入.Internal模块中。这样,想要使用隐藏位的用户可以很容易地做到这一点,但临时用户手头没有太多工具。

处理此问题的另一种方法是删除测试中的依赖项,而是将src目录添加到测试中:

 hs-source-dirs:      tests, src

但是,这也意味着您必须重建整个库进行测试,但它将启用使用 CPP。

第三种选择是不测试alphabet,而是测试依赖于它的导出函数的可观察行为。因此,与其测试 alphabet,不如测试 filterAlpha

filterAlpha :: String -> String
filterAlpha = filter (`elem` alphabet)

无论如何,你必须测试filterAlpha。如果有很多函数使用 alphabet ,如果您不小心更改了回归,您可能会有一些测试会注意到回归。

问题只是语法错误。 #ifdef错了,#ifndef是对

相关内容

  • 没有找到相关文章

最新更新