Custom options in Tasty

Tasty 0.6 is released, making it possible to create custom options just for your test suite!

Add your own option in three easy steps:

Define a datatype to represent the option, and make it an instance of IsOption Register the options with the includingOptions ingredient To query the option value, use askOption .

Examples follow.

Ignoring a test

My use case is a test suite that has a number of tests that fail on a certain build bot. I can’t fix the build bot configuration ATM, so I’d like to be able to mark these tests as known-fail in the build script for this particular build bot. — 23Skidoo

To some extent this is just a way around Tasty’s limited pattern language (which will improve, too!), but I still find it pretty nice.

With the following code, you can disable the second test by passing a --buildbot command-line option.

{-# LANGUAGE DeriveDataTypeable #-} import Test.Tasty import Test.Tasty.Options import Test.Tasty.HUnit import Data.Typeable ( Typeable ) import Data.Tagged import Data.Proxy import Options.Applicative newtype BuildBot = BuildBot Bool deriving ( Eq , Ord , Typeable ) instance IsOption BuildBot where = BuildBot False defaultValue = fmap BuildBot . safeRead parseValuesafeRead = return "buildbot" optionName = return "Running under a build bot" optionHelp = optionCLParser fmap BuildBot $ switch optionName :: Tagged BuildBot String )) ( long (untag ()) <> help (untag ( optionHelp :: Tagged BuildBot String )) help (untag ()) ) = defaultMainWithIngredients ings $ maindefaultMainWithIngredients ings $ \( BuildBot bb) -> askOption\(bb) "Tests" $ testGroup "Successful test" $ return () ] ++ [ testCase() ] if bb bb then [] [] else [ testCase "Failing test" $ assertFailure "build bot" ] [ testCaseassertFailure where = ings Option ( Proxy :: Proxy BuildBot )] : includingOptions [)] defaultIngredients

Controlling the depth

When running the tests is there any general solution to set the Depth parameter for the (individual) tests, or better yet, a fine grained solution to set the Depth parameter for individual fields? — jules

Not that I recommend doing this — see this answer.

But here’s how you can do it if you’re sure you want it.

(This was also possible to hack with earlier versions of Tasty — see this gist).

{-# LANGUAGE DeriveDataTypeable #-} import Test.Tasty import Test.Tasty.Options import Test.Tasty.SmallCheck import Test.SmallCheck.Series import Control.Applicative import Data.Proxy import Data.Typeable data T1 = T1 { p1 :: Int , p2 :: Char , p3 :: Int } deriving ( Eq , Show ) newtype P1Depth = P1Depth { getP1Depth :: Int } deriving Typeable instance IsOption P1Depth where = P1Depth 5 defaultValue = fmap P1Depth . safeRead parseValuesafeRead = return "smallcheck-depth-p1" optionName = return "Depth to use for p1" optionHelp t1Series :: Monad m => Int -- depth of p1 -> Series m T1 = decDepth $ t1Series ddecDepth T1 <$> localDepth ( const d) series <~> series <~> series localDepth (d) seriesseriesseries main :: IO () () = defaultMainWithIngredients (optsIng : defaultIngredients) $ maindefaultMainWithIngredients (optsIngdefaultIngredients) $ \( P1Depth p1d) -> askOption\(p1d) "Test1" $ testProperty $ over (t1Series p1d) -> x == x \x where = includingOptions [ Option ( Proxy :: Proxy P1Depth )] optsIngincludingOptions [)]