问题描述
我正在尝试编写自己的测试框架,但我什至无法开始。这是我的目录结构:
$ tree
.
├── prj1
│ ├── package.yaml
│ ├── src
│ │ └── Module.hs
│ └── test-dir
│ └── TheTest.hs
└── stack.yaml
每个文件是:
stack.yaml
resolver: lts-16.11
packages:
- prj1
package.yaml
name: prj1
version: 0.1
maintainer: fakedrake
category: Test
library:
source-dirs: src
exposed-modules: []
dependencies:
- base
tests:
prj1-tests:
main: TheTest.hs
source-dirs: test-dir
dependencies:
- base
TheTest.hs
module TheTest () where
main :: IO ()
main = putStrLn "Test passes!"
Module.hs
module Module () where
但是当我运行 stack test
时我得到
$ stack test
prj1> configure (lib + test)
Configuring prj1-0.1...
prj1> build (lib + test)
Preprocessing library for prj1-0.1..
Building library for prj1-0.1..
[1 of 2] Compiling Module
[2 of 2] Compiling Paths_prj1
Preprocessing test suite 'prj1-tests' for prj1-0.1..
Building test suite 'prj1-tests' for prj1-0.1..
[1 of 2] Compiling Paths_prj1
[2 of 2] Compiling TheTest
<no location info>: error:
output was redirected with -o,but no output will be generated
because there is no Main module.
-- While building package prj1-0.1 using:
/my/home/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.3 --builddir=.stack-work/dist/x86_64-osx/Cabal-3.0.1.0 build lib:prj1 test:prj1-tests --ghc-options ""
Process exited with code: ExitFailure 1
Progress 1/2
解决方法
基于 HPack / Stack 的项目的约定是测试的主要入口点位于文件 test/Spec.hs
因此,只需将您的模块 TheTest.hs
重命名为 Spec.hs
,并在 main: Spec.hs
的 tests:
部分设置 package.yaml
,一切都应该没问题。>
您还可以生成一个基于 HPack/Stack 的最小项目脚手架,包括以 stack new prj1
为起点的测试套件。
Spec.hs 作为主要入口点的好处是它允许自动查找 测试用例。
要启用此功能,只需在 Spec.hs 中放置一行:
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
这个 pragma 会找到所有遵循命名约定的模块
*Spec.hs
然后你可以有像ReverseSpec.hs
这样的单独的测试模块:
module ReverseSpec where
import Test.Hspec
-- `main` is here so that this module can be run from GHCi on its own. It is
-- not needed for automatic spec discovery.
main :: IO ()
main = hspec spec
-- this is the actual entry point for tests
spec :: Spec
spec = do
describe "reverse" $ do
it "is inverse to itself" $
property $ \str -> (reverse . reverse) str `shouldBe` (id str :: String)
如果您真的想推出自己的测试框架,您可以按如下方式编辑您的文件 TheTest.hs
:
- 没有模块子句:
-- module TheTest () where
main :: IO ()
main = putStrLn "Test passes!"
- 或使用修改后的模块子句:
module Main where
main :: IO ()
main = putStrLn "Test passes!"
这适用于 cabal test
和 stack test
。