【问题标题】:Haskell Unit tests using IO monad使用 IO monad 的 Haskell 单元测试
【发布时间】:2015-12-09 00:11:40
【问题描述】:

我正在尝试为返回 IO 单子的 haskell 函数编写 HUnit 测试,因为它们执行文件 I/O。有没有办法做到这一点?现在我正在尝试编写一个只返回 Bool 并且可以作为我的测试的方法

combine :: FilePath -> FilePath -> Bool
combine fp1 fp2 = do
  cs <- readFile fp1
  let (_,y,z) = strToHuff cs
  let _ = writeToFile fp2 z y
  (a, b) <- readFromFile fp2
  z == a && b == y

但这给了我以下错误:

FileWriter.hs:153:3: Couldn't match type ‘IO b0’ with ‘Bool’ …
    Expected type: IO String -> (String -> IO b0) -> Bool
      Actual type: IO String -> (String -> IO b0) -> IO b0
    In a stmt of a 'do' block: cs <- readFile fp1
    In the expression:
      do { cs <- readFile fp1;
           let (_, y, z) = strToHuff cs;
           let _ = writeToFile "try1.txt" z y;
           (a, b) <- readFromFile fp2;
           .... }
    In an equation for ‘combine’:
        combine fp1 fp2
          = do { cs <- readFile fp1;
                 let (_, y, z) = ...;
                 let _ = ...;
                 .... }
FileWriter.hs:157:3: Couldn't match expected type ‘IO b0’ with actual type ‘Bool’ …
    In a stmt of a 'do' block: z == a && b == y
    In the expression:
      do { cs <- readFile fp1;
           let (_, y, z) = strToHuff cs;
           let _ = writeToFile "try1.txt" z y;
           (a, b) <- readFromFile fp2;
           .... }
    In an equation for ‘combine’:
        combine fp1 fp2
          = do { cs <- readFile fp1;
                 let (_, y, z) = ...;
                 let _ = ...;
                 .... }
Compilation failed.

【问题讨论】:

  • 嗯,类型是很好的单元测试开始!试试return (z == a &amp;&amp; b == y)
  • 有没有办法将其包装在 hunit 测试中?
  • @astiefel 一个 HUnit Assertion 只是一个 IO () 所以是的,你可以。正确的做法可能是assertEqual "..." z a; assertEqual "..." b y - 这样您就可以说明为什么这些必须相等,并且当您的测试失败时,您将更容易找出原因。

标签: haskell io monads ghci hunit


【解决方案1】:

就像@user2407038 在 cmets 中所说的以及在 IO monad 中运行的 HUnit user manual HUnit 测试中提到的那样。

这是一个例子:

testFilesEqual = TestCase (do x <- readFile "a.txt"
                              y <- readFile "b.txt"
                              assertEqual "files not equal" x y)
# a.txt == b.txt
λ> runTestTT testFilesEqual
Cases: 1  Tried: 0  Errors: 0  Failures: 0
Counts {cases = 1, tried = 1, errors = 0, failures = 0}

# a.txt != b.txt
λ> runTestTT testFilesEqual
### Failure:
files not equal
expected: "hello\n"
but got: "world\n"
Cases: 1  Tried: 1  Errors: 0  Failures: 1
Counts {cases = 1, tried = 1, errors = 0, failures = 1}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-08
    • 2013-08-15
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    相关资源
    最近更新 更多