haskell-hedgehog icon indicating copy to clipboard operation
haskell-hedgehog copied to clipboard

Need way to perform work upon test failure

Open newhoggy opened this issue 5 years ago • 7 comments

In particular, when a test fails, I'd like a way to perform some IO action to read a file and annotate it.

It is insufficient to do the annotation before the assertion because the file is a log file that is growing and will not contain all the information I need, hence the desire to add the annotation at the point of failure.

newhoggy avatar Sep 15 '20 23:09 newhoggy

It sounds like all you want is onException from the exceptions library. I believe test failure is just raising an exception

On Wed, 16 Sep 2020, at 12:07 AM, John Ky wrote:

In particular, when a test fails, I'd like a way to perform some IO action to read a file and annotate it.

It is insufficient to do the annotation before the assertion because the file is a log file that is growing and will not contain all the information I need, hence the desire to add the annotation at the point of failure.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/hedgehogqa/haskell-hedgehog/issues/399, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFDDWFAZPKYVB3OC7LKRLSF7XTBANCNFSM4RN4ZCDA.

ocharles avatar Sep 16 '20 06:09 ocharles

Are exceptions considered part of the API or an implementation detail?

newhoggy avatar Sep 16 '20 10:09 newhoggy

newtype PropertyT m a =
  PropertyT {
      unPropertyT :: TestT (GenT m) a
    }

newtype TestT m a =
  TestT {
      unTest :: ExceptT Failure (Lazy.WriterT Journal m) a
    }

It doesn't use exceptions for failures, though it does catch them. But you can unwrap and rewrap these types as much as you like.

HuwCampbell avatar Oct 01 '20 10:10 HuwCampbell

I got it working:

               ┏━━ test/Spec/Network.hs ━━━
            76 ┃ hprop_foo :: Property
            77 ┃ hprop_foo = H.propertyOnce . H.runFinallies $ do
            78 ┃   H.onFailure $ H.noteM_ $ H.readFile "moo.txt"
               ┃   │ Reading file: moo.txt
               ┃   │ hello world
            79 ┃ 
            80 ┃   H.writeFile "moo.txt" "hello world"
               ┃   │ Writing file: moo.txt
            81 ┃ 
            82 ┃   H.failure
               ┃   ^^^^^^^^^

Line 78 says if the test fails, run provided action, which is annotate the contents of a file. Line 80 writes the file. Line 82 fails, causing the provided action to run. This only works because the writeFile has already happened.

newhoggy avatar Oct 02 '20 04:10 newhoggy

@newhoggy, great :+1: Feel free to paste an example here, if that's easy for you, for anyone else that might be looking into this in the future.

moodmosaic avatar Oct 02 '20 08:10 moodmosaic

This is the code I used to expose the ability to catch and throw assertions:

https://github.com/input-output-hk/cardano-node/blob/master/hedgehog-extras/src/Hedgehog/Extras/Test/MonadAssertion.hs

The runFinallies function is defined here:

https://github.com/input-output-hk/cardano-node/blob/5106f637233a9f2c12faaca571b78378714b4d0a/hedgehog-extras/src/Hedgehog/Extras/Test/Base.hs#L362

And onFailure function is defined here:

https://github.com/input-output-hk/cardano-node/blob/5106f637233a9f2c12faaca571b78378714b4d0a/hedgehog-extras/src/Hedgehog/Extras/Test/Base.hs#L349

newhoggy avatar Oct 06 '20 03:10 newhoggy

I'd love for something like this to be upstreamed into hedgehog.

newhoggy avatar Oct 06 '20 03:10 newhoggy