在 Haskell 中测试

了解如何在 Exercism 上测试你的 Haskell 练习


运行测试

在练习目录中执行以下命令来运行测试:

stack test

如果要在每次保存文件时都运行测试,请改用这个命令:

stack test --file-watch

如果你遇到这样的错误信息……

No .cabal file found in directory

你用的很可能是旧版 stack,需要升级。

或者,如果你遇到这样的错误信息……

No compiler found, expected minor version match with...
Try running "stack setup" to install the correct GHC...

按提示操作即可,它会下载并安装正确的编译器版本:

stack setup

解答练习

练习的解答是一个 Haskell 模块。模块名在测试套件的导入语句中定义,通常位于开头:

import Test.Hspec        (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFailFast, defaultConfig, hspecWith)

import ModuleName (someFunc)

main :: IO ()
main ...

在这个示例中,测试文件在第 4 行导入了一个名为 ModuleName 的模块,该模块导出了一个名为 someFunc 的函数。这意味着你需要创建一个名为 ModuleName.hs 的文件,内容大致如下:

module ModuleName (someFunc) where

someFunc :: ...
someFunc ...

你会在 src/ 中找到一个已经存在的同名文件,可以把它作为解答的起点。

请记住,这个存根只是帮你入门。如果你觉得应该彻底改掉它,尽管这么做。

使用包

如果你想用一些包来写出更优雅的解答,请先在 package.yaml 中把这些包添加到解答的依赖里:

library:
  exposed-modules: ModuleName
  source-dirs: src
  dependencies:
    - foo
    - bar

在本地开发时,你可以随意使用任何包。不过,在线测试运行器只能访问一组有限的包。可用的包包括

  • GHC 预装的包(最值得注意的是 base、containers、array、time、mtl、deepseq、exceptions、bytestring),以及
  • 为测试运行器预先构建的包,列在 haskell-test-runner/pre-compiled/package.yaml 中。

如果你提交的解答使用了不可用的包,那么测试运行器会因为无法访问互联网而报错,错误信息大致如下:

Cabal file info not found for unavailable-package-1.0@..., updating
Selected mirror https://hackage.haskell.org/
Downloading root
HttpExceptionRequest Request {
  host                 = "hackage.haskell.org"
  ...
}
 (ConnectionFailure ...)

运行 GHCi

如果你想在 GHCi 里试试你的解答,运行这个命令即可:

stack ghci

HLint(可选)

强烈建议你对解答运行 hlint,看看它能否发现你遗漏的问题:

hlint ModuleName.hs

你不必接受 hlint 给出的所有建议,但通常它们能帮你学会如何写出漂亮、地道的 Haskell 代码。