当测试文件被定义为模块时,使用堆栈调用的 hspec 定义测试会抛出错误

hspec defined tests invoked with stack throw an error when test file is defined as a module

我想弄明白为什么包含定义为模块的单元测试的测试文件在 运行 和 stack build --test 时失败的原因。

假设有一个从头开始定义的简单测试模块:

stack new test-module
cd test-module

vim package.yaml # remove "executables" section, add "hspec" as tests dependency

按照 Hspec 文档中的“getting started”说明,我修改了文件,例如:

第 1 步:描述您想要的行为

-- file test/Spec.hs

module LibSpec where

import Test.Hspec
import Lib

main :: IO ()
main = hspec $ do
    describe "divides" $ do
        it "returns True when the first number divides the second" $
           2 `divides` 4 `shouldBe` True

第 2 步:编写一些代码

-- file src/Lib.hs

module Lib (divides) where

divides :: Integer -> Integer -> Bool
divides d n = rem n d == 0

运行 stack build --test 抛出以下错误:

<no location info>: error:
    output was redirected with -o, but no output will be generated
because there is no Main module.

当我注释掉 test/Spec.hs 文件中的 "module definition" 行时,构建成功并且单元测试通过:

-- file test/Spec.hs

-- Notice the next line is commented out:
-- module LibSpec where

import Test.Hspec
import Lib

main :: IO ()
main = hspec $ do
    describe "divides" $ do
        it "returns True when the first number divides the second" $
           2 `divides` 4 `shouldBe` True

是Hspec相关还是Stack相关?还是我遗漏了一些明显的东西?

它是 Haskell 语言的一部分。

A Haskell program is a collection of modules, one of which, by convention, must be called Main and must export the value main.

An abbreviated form of module, consisting only of the module body, is permitted. If this is used, the header is assumed to be module Main(main) where.


The Haskell 2010 report, section 5 (Modules) https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-980005


另请参阅 cabal 文档,关于 package.yaml 代理的配置,包含 test/executable 文件的字段:

main-is: (...) while the name of the file may vary, the module itself must be named Main.


https://www.haskell.org/cabal/users-guide/developing-packages.html#pkg-field-executable-main-is


GHC 有一个选项 -main-is MyModule.mymain 可以覆盖此行为 (documented in the GHC user guide)。