简体   繁体   English

使用HSpec(或HUnit)是否可以将进一步的信息附加到仅在发生故障时才打印的断言上?

[英]Is it possible with HSpec (or HUnit) to attach further information to assertions that get printed in and only in case of failure?

Similarly to how quickcheck supports counterexamples: 与quickcheck如何支持反例类似:

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

but in a way that it works with shouldBe , eg 但以某种方式应与shouldBe一起shouldBe ,例如

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

And I would like it to print something along the lines of: 我希望它按照以下方式打印一些内容:

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

Yes, it seems to be possible: 是的,似乎有可能:

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

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

We catch the exception thrown by shouldBe , amend the message, and rethrow it. 我们捕获了shouldBe抛出的异常,修改了消息,然后将其重新抛出。

We can even use it like: 我们甚至可以像这样使用它:

1 `shouldBe` 2
  $> failDetails "foobar"

if we define: 如果我们定义:

($>) = flip ($)
infixl 0 $>
{-# INLINE ($>) #-}

Inspired by @Wizek's answer, here's a version works with a newer version of HUnit and that is suitable for use with Selenium/WebDriver. 受@Wizek答案的启发,以下版本适用于较新版本的HUnit,适用于Selenium / WebDriver。

It unpacks and repacks FailureReason's different constructors appropriately 它适当地解包和重新包装FailureReason的不同构造函数

The key difference is the use of Control.Monad.Catch which lets you work with WD as opposed to IO. 关键区别在于Control.Monad.Catch的使用,它使您可以使用WD而不是IO。

Also there's no need to write the $> operator - there's already & from Data.Function 另外,也不需要编写$>运算符-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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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