我有一个阴谋集团的项目,它构建了一个可执行文件。
当我运行cabal test --enable-coverage
时,我得到以下错误:
All 9 tests passed (0.98s)
Test suite giter-test: PASS
Test suite logged to:
/home/refaelsh/repos/giter/dist-newstyle/build/x86_64-linux/ghc-9.2.7/giter-0.1.0/test/giter-0.1.0-giter-test.log
Error: .cabal-wrapped: Test coverage is only supported for packages with a
library component.
Error: cabal: Tests failed for giter-0.1.0.
1.有人能解释一下这是怎么回事吗?
1.当我的cabal项目只有一个可执行文件而没有库时,这个错误是正常的吗?
1.我是否应该只创建一个我想要的单元测试部分的库,并使我的exe依赖于该库?
1.如果是,这是惯用Haskell中的常见做法吗?
1.如果是的话,那么为了适应单元测试而对源代码和/或项目结构进行更改,感觉就像是一种代码气味。
1条答案
按热度按时间9jyewag01#
我认为this issue中涵盖了潜在的技术问题。Cabal假设你不想要单元测试代码本身的覆盖率报告,只想要被测试的代码,所以它调用
hpc
的方式是排除单元测试代码,只有实际被测试的源代码才包含在覆盖率报告中。如果代码是单独编译的库的一部分,这很容易做到:涵盖了库,但不涵盖任何属于单元测试的模块。但是,如果您没有
library
节,只有executable
和test-suite
节使用共享的模块集,则没有明显的方法来区分单元测试中不应覆盖的test-suite
模块和应覆盖的被测试代码中的模块。更普遍地说,Cabal对测试
executable
节的支持很差。根据this issue中的讨论,真正测试executable
的唯一方法是使用hack -要么指定executable
和test-suite
节共享相同的hs-source-dirs
,最终双重编译所有内容,要么将重要的内容移动到library
中,并将executable
作为存根。你可能使用的是前一种方法,而不是后一种,但两者都很糟糕。开发人员似乎已经决定“将所有内容都移动到library
中”是推荐的方法,即使不是所有的文档和/或教程材料都清楚地说明了这一点。请注意,Stack的情况与此类似--默认模板通常有一个存根应用程序,其中只包含一个
main
函数,其他所有内容都被移到库中。我想我会建议将整个应用程序(而不仅仅是你想要测试的部分)移动到
library
中,并为你的executable
编写一个stub main函数,如下所示:test-suite
和executable
都取决于library
。