简体   繁体   中英

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

I'm trying to get my head around the reason why the test file containing unit-tests which is defined as a module fails when run with stack build --test .

Say having a simple test module defined from scratch with:

stack new test-module
cd test-module

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

Following " getting started " instructions from Hspec documentation I've modified files such as:

Step 1: Describe your desired behavior

-- 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

Step 2: Write some code

-- file src/Lib.hs

module Lib (divides) where

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

Running stack build --test throws the following error:

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

When I comment out the "module definition" line from the test/Spec.hs file the build succeeds and the unit-test passes:

-- 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

Is that Hspec related or Stack related? Or maybe am I missing something obvious?

It's part of Haskell the language.

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


See also the cabal documentation, about the configuration that package.yaml is a proxy for, the field containing the test/executable file:

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 has an option -main-is MyModule.mymain to override this behavior ( documented in the GHC user guide ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM