所以我试图关注suggested structure of a Haskell project,我在组织测试时遇到了一些问题。
为简单起见,让我们从:
开始src/Clue/Cards.hs # defines Clue.Cards module
testsuite/tests/Clue/Cards.hs # tests Clue.Cards module
首先,我不确定在testsuite/tests/Clue/Cards.hs
中包含测试代码的模块名称是什么,另一方面,我不知道如何编译我的测试代码以便我可以链接到我的源:
% ghc -c testsuite/tests/Clue/Cards.hs -L src
testsuite/tests/Clue/Cards.hs:5:0:
Failed to load interface for `Clue.Cards':
Use -v to see a list of the files searched for.
答案 0 :(得分:26)
我自己使用Snap Framework为他们的测试套件采取的方法,基本归结为:
通过将.Tests
附加到包含IUT的模块名称来命名包含测试的模块,例如:
module Clue.Cards where ... -- module containing IUT
module Clue.Cards.Tests where ... -- module containing tests for IUT
通过使用单独的命名空间,您可以将测试放在单独的源文件夹tests/
中,然后可以使用单独的Cabal构建目标(另请参阅cabal test
- build-target支持最近的Cabal版本的测试套件,其中包含hs-source-dirs
设置中的附加源文件夹,例如:
Executable clue
hs-source-dirs: src
...
Executable clue-testsuite
hs-source-dirs: src tests
...
这很有效,因为IUT和测试套件中的模块之间没有命名空间冲突。
答案 1 :(得分:3)
就个人而言,我觉得额外的./src/
目录对于小型Haskell项目没有多大意义。粗略的来源,我下载了源代码。
无论哪种方式(有或没有src),我建议你重构并拥有一个Clue
目录和一个Test
目录:
./Clue/Cards.hs -- module Clude.Cards where ...
./Test/Cards.hs -- module Test.Cards where ...
这允许GHCi + Test.Cards看到Clue.Cards而没有任何额外的args或使用cabal。在这方面,如果您不使用cabal +标志来选择构建测试模块,那么您应该查看它。
我在许多项目中使用的另一个选项是:
./Some/Module/Hierarchy/File.hs
./tests/someTests.hs
我cabal install
然后包运行tests/someTests.hs
个东西。我想如果我的软件包特别大并且安装时间太长,那将会很烦人。
答案 2 :(得分:3)
这是另一种方式:
每个模块的单元测试定义为hunit TestList at the end of the module,具有一些一致的命名方案,例如“tests_Path_To_Module”。我认为这有助于我编写测试,因为我不必在源代码树中搜索远处的另一个模块,也不必保持两个并行文件层次结构同步。
模块的测试列表还包括任何子模块的测试。 Hunit的runTestTT跑步者内置于应用程序中,可通过test command访问。这意味着用户可以随时运行测试而无需特殊设置。或者,如果您不喜欢生产应用程序中的运输测试,请使用CPP和cabal标志仅将它们包含在开发版本中,或者包含在单独的测试运行程序可执行文件中。
还有功能测试,tests/目录中的每个文件一个或多个,使用shelltestrunner运行,以及基于Makefile的一些与开发进程相关的测试。
答案 3 :(得分:1)
为了完整起见,值得一提的是通过ghci -i
进行小项目的一种非常简单的方法。例如,在您的情况下,
>ghci -isrc:testsuite
ghci>:l Clue.Cards
ghci>:l tests.Clue.Cards