3

类似于 quickcheck 如何支持反例:

property \x ->
  counterexample ("Foo failed with: " ++ ...) $
    foo x

但在某种程度上它适用于shouldBe,例如

failDetails (" details: " ++ baz a) $
  a `shouldBe` 2

我希望它可以打印以下内容:

expected: 2
 but got: 3
 details: ...
4

2 回答 2

5

是的,这似乎是可能的:

import Control.Exception
import Test.HUnit.Lang (HUnitFailure(..))

failDetails details assert = do
  assert `catch` \(HUnitFailure loc msg) -> do
    throw $ HUnitFailure loc $ msg ++ "\n" ++ details

我们捕获由 抛出的异常shouldBe,修改消息并重新抛出它。

我们甚至可以像这样使用它:

1 `shouldBe` 2
  $> failDetails "foobar"

如果我们定义:

($>) = flip ($)
infixl 0 $>
{-# INLINE ($>) #-}
于 2016-09-25T12:33:02.757 回答
1

受@Wizek 回答的启发,这里有一个版本适用于较新版本的 HUnit,并且适用于 Selenium/WebDriver。

它适当地解包和重新打包 FailureReason 的不同构造函数

关键区别在于 Control.Monad.Catch 的使用,它允许您使用 WD 而不是 IO。

也没有必要写$>操作符 - 已经有&来自 Data.Function

import Test.HUnit.Lang
import Control.Monad.Catch
import qualified Data.Text as Text
import Data.Function ((&))

failDetails :: Text -> WD () -> WD ()
failDetails textMessage expectation =
  expectation `catch` \(HUnitFailure loc reason) ->
    throwM $ HUnitFailure loc $ addMessageTo reason
  where
  message :: String 
  message = Text.unpack textMessage

  addMessageTo :: FailureReason -> FailureReason
  addMessageTo (Reason reason) = Reason $ reason ++ "\n" ++ message
  addMessageTo (ExpectedButGot preface expected actual) = 
    ExpectedButGot newPreface expected actual
    where
    newPreface = 
      case preface of 
      Nothing -> Just message
      Just existingMessage -> Just $ existingMessage ++ "\n" ++ message
于 2019-07-05T12:00:35.193 回答