【问题标题】:hspec defined tests invoked with stack throw an error when test file is defined as a module当测试文件被定义为模块时,使用堆栈调用的 hspec 定义的测试会引发错误
【发布时间】:2019-11-20 09:53:39
【问题描述】:

我试图弄清楚为什么包含被定义为模块的单元测试的测试文件在使用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 文件中注释掉“模块定义”行时,构建成功并且单元测试通过:

-- 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 相关?或者我是否遗漏了一些明显的东西?

【问题讨论】:

    标签: unit-testing haskell hspec


    【解决方案1】:

    它是 Haskell 语言的一部分。

    Haskell 程序是一组模块,按照惯例,其中一个必须称为 Main 并且必须导出值 main

    允许使用仅由模块主体组成的模块的缩写形式。如果使用它,则假定标头为module Main(main) where


    Haskell 2010 报告,第 5 节(模块)https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-980005


    另请参阅 cabal 文档,关于 package.yaml 代理的配置,包含测试/可执行文件的字段:

    main-is: (...) 虽然文件名可能不同,但模块本身必须命名为 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)。

    【讨论】:

    • 我只是仔细检查了 - 当我没有运行 stack build --test 时,我将 src/Lib.hs 文件和 test/Spec.hs 文件放在顶层目录中,并按照 Hspec 教程调用 stack exec -- runhaskell Spec.hs 和模块定义(未注释)它不会引发错误。现在更令人困惑:P
    • 这很令人困惑。
    • 这可能是runhaskell(据我了解是runghc 的别名,是一种无需编译即可运行Haskell 程序的方法)提取模块被调用的任何内容并以某种方式覆盖main-is 选项有吗?
    • 是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多