Evaluate a test suite definition and then run it.
This function perform option-parsing to construct the Settings and then call sydTestWith.
:: a typeCtrl KGHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27
Modulesydtest-0.22.0.0Haskell2010
For a full overview of features and comparisons, please see the README.
To use sydtest, you don't necessarily need to know the following, but for advanced usage you definitely will.
If you're just starting out, you can ignore this section and just follow the examples in the docs below.
Every test is an instance of the IsTest type class.
A test can be a pure Bool, an IO (), a GoldenTest, some combination of those, or any type that you can implement IsTest for.
sydtest allows you to declare resources for use during your tests.
This could be things like a database connection or a server to connect to, for example.
Every resource is either an outer resource (set up once for a test group) or an inner resource (set up again for each test).
Every IsTest instance defines two associated types, an Arg1 type and an Arg2 type.
These correspond to two function arguments. Arg1 corresponds to the first and Arg2 corresponds to the second.
For example, IO () is an instance of IsTest, but arg -> IO () and outerArgs -> innerArg -> IO () are as well.
When using it or specify to define tests, the Arg1 and Arg2 arguments of the test that you pass in have to correspond to the outer and inner resources of your test suite, respectively.
You can declare how to set up or tear down resources using the around and aroundAll functions.
Evaluate a test suite definition and then run it.
This function perform option-parsing to construct the Settings and then call sydTestWith.
Evaluate a test suite definition and then run it, with given Settings
This function performs no option-parsing.
describe Declare a test group
describe "addition" $ do
it "adds 3 to 5 to result in 8" $
3 + 5 `shouldBe` 8
it "adds 4 to 7 to result in 11" $
4 + 7 `shouldBe` 11it Declare a test
Note: Don't look at the type signature unless you really have to, just follow the examples.
describe "addition" $
it "adds 3 to 5 to result in 8" $
3 + 5 == 8describe "readFile and writeFile" $
it "reads back what it wrote for this example" $ do
let cts = "hello world"
let fp = "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsdescribe "sort" $
it "is idempotent" $
forAllValid $ \ls ->
sort (sort ls) `shouldBe` (sort (ls :: [Int]))describe "readFile and writeFile" $
it "reads back what it wrote for any example" $ do
forAllValid $ \fp ->
forAllValid $ \cts -> do
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsThis is quite a rare use-case but here is an example anyway:
before (pure 3) $ describe "addition" $
it "adds 3 to 5 to result in 8" $ \i ->
i + 5 == 8This test sets up a temporary directory as an inner resource, and makes it available to each test in the group below.
let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in around setUpTempDir $ describe "readFile and writeFile" $
it "reads back what it wrote for this example" $ \tempDir -> do
let cts = "hello world"
let fp = tempDir </> "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsThis is quite a rare use-case but here is an example anyway:
before (pure 3) $ describe "multiplication" $
it "is commutative for 5" $ \i ->
i * 5 == 5 * 3let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in around setUpTempDir $ describe "readFile and writeFile" $
it "reads back what it wrote for this example" $ \tempDir ->
property $ \cts -> do
let fp = tempDir </> "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsDeclare a test that uses an outer resource
This is quite a rare use-case but here is an example anyway:
beforeAll (pure 3) $ describe "addition" $
itWithOuter "adds 3 to 5 to result in 8" $ \i ->
i + 5 == 8This test sets up a temporary directory as an inner resource, and makes it available to each test in the group below.
let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in aroundAll setUpTempDir describe "readFile and writeFile" $
itWithOuter "reads back what it wrote for this example" $ \tempDir -> do
let cts = "hello world"
let fp = tempDir </> "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsThis is quite a rare use-case but here is an example anyway:
beforeAll (pure 3) $ describe "multiplication" $
itWithOuter "is commutative for 5" $ \i ->
i * 5 == 5 * 3let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in aroundAll setUpTempDir describe "readFile and writeFile" $
itWithouter "reads back what it wrote for this example" $ \tempDir ->
property $ \cts -> do
let fp = tempDir </> "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsDeclare a test that uses both an inner and an outer resource
This is quite a rare use-case but here is an example anyway:
beforeAll (pure 3) $ before (pure 5) $ describe "addition" $
itWithBoth "adds 3 to 5 to result in 8" $ \i j ->
i + j == 8This test sets up a temporary directory as an inner resource, and makes it available to each test in the group below.
let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in aroundAll setUpTempDir describe "readFile and writeFile" $ before (pure "hello world") $
itWithBoth "reads back what it wrote for this example" $ \tempDir cts -> do
let fp = tempDir </> "test.txt"
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsThis is quite a rare use-case but here is an example anyway:
beforeAll (pure 3) $ before (pure 5) $ describe "multiplication" $
itWithBoth "is commutative" $ \i j ->
i * j == 5 * 3let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir
in aroundAll setUpTempDir describe "readFile and writeFile" $ before (pure "test.txt") $
itWithBoth "reads back what it wrote for this example" $ \tempDir fileName ->
property $ \cts -> do
let fp = tempDir </> fileName
writeFile fp cts
cts' <- readFile fp
cts' `shouldBe` ctsDeclare a test that uses all outer resources
You will most likely never need this function, but in case you do:
Note that this will always require a type annotation, along with the GADTs and ScopedTypeVariables extensions.
beforeAll (pure 'a') $ beforeAll (pure 5) $
itWithAll "example" $
\(HCons c (HCons i HNil) :: HList '[Char, Int]) () ->
(c, i) `shouldeBe` ('a', 5)specify A synonym for it
A synonym for itWithOuter
A synonym for itWithBoth
A synonym for itWithAll
Convenience function for backwards compatibility with hspec
prop s p = it s $ property pGet the path of describe strings upwards.
Note that using this function makes tests less movable, depending on what
you do with these strings.
For example, if you use these strings to define the path to a golden test
file, then that path will change if you move the tests somewhere else.
This combines unfortunately with the way sydtest-discover makes the module
name part of this path.
Indeed: moving your tests to another module will change their path as well,
if you use sydtest-discover.
Also note that while test forests can be randomised, their description path
upwards will not, because of how trees are structured.
xspecify A synonym for xit
A synonym for xitWithOuter
A synonym for xitWithBoth
A synonym for xitWithAll
Declare a test that has not been written yet.
Declare a test that has not been written yet for the given reason.
Test that the given text is the same as what we find in the given golden file.
Test that the produced text is the same as what we find in the given golden file.
Test that the given bytestring is the same as what we find in the given golden file.
Test that the produced bytestring is the same as what we find in the given golden file.
Test that the given lazy bytestring is the same as what we find in the given golden file.
Note: This converts the lazy bytestring to a strict bytestring first.
Test that the produced bytestring is the same as what we find in the given golden file.
Note: This converts the lazy bytestring to a strict bytestring first.
Test that the given lazy bytestring is the same as what we find in the given golden file.
Note: This converts the builder to a strict bytestring first.
Test that the produced bytestring is the same as what we find in the given golden file.
Note: This converts the builder to a strict bytestring first.
Test that the given string is the same as what we find in the given golden file.
Test that the produced string is the same as what we find in the given golden file.
Test that the show instance has not changed for the given value.
Test that the show instance has not changed for the given value, via ppShow.
The golden test context for adding context to a golden test assertion:
goldenTestCompare = \actual expected ->
if actual == expected
then Nothing
else Just $ Context (stringsNotEqualButShouldHaveBeenEqual actual expected) (goldenContext fp)A golden test for output of type a.
The purpose of a golden test is to ensure that the output of a certain process does not change even over time.
Golden tests can also be used to show how the output of a certain process changes over time and force code reviewers to review the diff that they see in the PR.
This works by saving a golden output in the repository somewhere,
committing it, and then compare that golden output to the output that is
currently being produced. You can use `--golden-reset` to have sydtest
update the golden output by writing the current output.
GoldenTestgoldenTestRead :: IO (Maybe a)Read the golden test output, Nothing if there is no golden output yet.
goldenTestProduce :: IO aProduce the current output
goldenTestWrite :: a -> IO ()Write golden output
goldenTestCompare :: a -> a -> IO (Maybe Assertion)Compare golden output with current output
The first argument is the current output, the second is the golden output
IsTest (IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (IO (GoldenTest a)) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (GoldenTest a) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (arg -> IO (GoldenTest a)) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (arg -> GoldenTest a) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (outerArgs -> innerArg -> IO (GoldenTest a)) = outerArgsDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg1 (outerArgs -> innerArg -> GoldenTest a) = outerArgsDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (IO (GoldenTest a)) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (GoldenTest a) = ()Defined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (arg -> IO (GoldenTest a)) = argDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (arg -> GoldenTest a) = argDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (outerArgs -> innerArg -> IO (GoldenTest a)) = innerArgDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Arg2 (outerArgs -> innerArg -> GoldenTest a) = innerArgDefined in sydtest-0.22.0.0 · Test.Syd.RunDefine a test for each file in the given directory.
Example:
scenarioDir "test_resources/even" $ \fp ->
it "contains an even number" $ do
s <- readFile fp
n <- readIO s
(n :: Int) `shouldSatisfy` evenDefine a test for each file in the given directory, recursively.
Example:
scenarioDirRecur "test_resources/odd" $ \fp ->
it "contains an odd number" $ do
s <- readFile fp
n <- readIO s
(n :: Int) `shouldSatisfy` oddAssert that two values are equal according to ==.
Assert that two values are not equal according to ==.
Assert that a value satisfies the given predicate.
Assert that a value satisfies the given predicate with the given predicate name.
Assert that a value does not satisfy the given predicate.
Assert that a value does not satisfy the given predicate with the given predicate name.
Assert that computation returns the given value (according to ==).
Assert that computation returns the given value (according to ==).
Assert that the given list has the given prefix
Assert that the given list has the given suffix
Assert that the given list has the given infix
Assert that the given list contains all elements from the other given list and only them, perhaps in a different order.
Make a test fail
Note that this is mostly backward compatible, but it has return type a instead of () because execution will not continue beyond this function.
In this way it is not entirely backward compatible with hspec because now there could be an ambiguous type error.
Annotate a given action with a context, for contextual assertions
This is a completely different function from the function with the same name in hspec. In hspec, context is a synonym for describe, but in sydtest, context is used for contextual failures.
For easy hspec migration
Assert that a given IO action throws an exception that matches the given exception
For easy hspec migration
An assertion that says two ByteStrings should have been equal according to ==.
A special exception that sydtest knows about and can display nicely in the error output
This is exported outwards so that you can define golden tests for custom types.
You will probably not want to use this directly in everyday tests, use shouldBe or a similar function instead.
NotEqualButShouldHaveBeenEqualWithDiff !String !String !(Maybe [Diff Text])Both strings are not equal. The latest argument is a diff between both arguments. If Nothing, the raw values will be displayed instead of the diff.
EqualButShouldNotHaveBeenEqual !String !StringPredicateSucceededButShouldHaveFailed !String !(Maybe String)PredicateFailedButShouldHaveSucceeded !String !(Maybe String)ExpectationFailed !StringContext !Assertion !StringEq AssertionDefined in sydtest-0.22.0.0 · Test.Syd.RunShow AssertionDefined in sydtest-0.22.0.0 · Test.Syd.RunGeneric AssertionDefined in sydtest-0.22.0.0 · Test.Syd.RunException AssertionDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Rep Assertion = D1 ('MetaData "Assertion"
"Test.Syd.Run"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) ((C1 ('MetaCons "NotEqualButShouldHaveBeenEqualWithDiff"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String) :*: (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe [Diff Text])))) :+: (C1 ('MetaCons "EqualButShouldNotHaveBeenEqual"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String)) :+: C1 ('MetaCons "PredicateSucceededButShouldHaveFailed"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe String))))) :+: (C1 ('MetaCons "PredicateFailedButShouldHaveSucceeded"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe String))) :+: (C1 ('MetaCons "ExpectationFailed"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String)) :+: C1 ('MetaCons "Context"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Assertion) :*: S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 String)))))Defined in sydtest-0.22.0.0 · Test.Syd.RunbeforeAll Run a custom action before all spec items in a group, to set up an outer resource a.
beforeAll_ Run a custom action before all spec items in a group without setting up any outer resources.
beforeAllWith Run a custom action before all spec items in a group, to set up an outer resource b by using the outer resource a.
afterAll Run a custom action after all spec items, using the outer resource a.
afterAll' Run a custom action after all spec items, using all the outer resources.
afterAll_ Run a custom action after all spec items without using any outer resources.
aroundAll Run a custom action before and/or after all spec items in group, to provide access to a resource a.
See the FOOTGUN note in the docs for around_.
aroundAll_ Run a custom action before and/or after all spec items in a group without accessing any resources.
This combinator gives the programmer a lot of power. In fact, it gives the programmer enough power to break the test framework. Indeed, you can provide a wrapper function that just _doesn't_ run the function like this:
spec :: Spec
spec = do
let don'tDo :: IO () -> IO ()
don'tDo _ = pure ()
aroundAll_ don'tDo $ do
it "should pass" TrueDuring execution, you'll then get an error like this:
thread blocked indefinitely in an MVar operationThe same problem exists when using around_.
Something even more pernicious goes wrong when you run the given action more than once like this:
spec :: Spec
spec = do
let doTwice :: IO () -> IO ()
doTwice f = f >> f
aroundAll_ doTwice $ do
it "should pass" TrueIn this case, the test will "just work", but it will be executed twice even if the output reports that it only passed once.
Note: If you're interested in fixing this, talk to me, but only after GHC has gotten impredicative types because that will likely be a requirement.
aroundAllWith Run a custom action before and/or after all spec items in a group to
provide access to a resource a while using a resource b
See the FOOTGUN note in the docs for around_.
aroundAllWithAll Run a custom action before and/or after all spec items in a group to
provide access to a resource a while using all outer resources.
before Run a custom action before every spec item, to set up an inner resource inner.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
before_ Run a custom action before every spec item without setting up any inner resources.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
after Run a custom action after every spec item, using the inner resource c.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
after_ Run a custom action after every spec item without using any inner resources.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
around Run a custom action before and/or after every spec item, to provide access to an inner resource c.
See the FOOTGUN note in the docs for around_.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
around_ Run a custom action before and/or after every spec item without accessing any inner resources.
It is important that the wrapper function that you provide runs the action that it gets _exactly once_.
This combinator gives the programmer a lot of power. In fact, it gives the programmer enough power to break the test framework. Indeed, you can provide a wrapper function that just _doesn't_ run the function like this:
spec :: Spec
spec = do
let don'tDo :: IO () -> IO ()
don'tDo _ = pure ()
around_ don'tDo $ do
it "should pass" TrueDuring execution, you'll then get an error like this:
thread blocked indefinitely in an MVar operationThe same problem exists when using Test.Syd.Def.Around.aroundAll_.
The same thing will go wrong if you run the given action more than once like this:
spec :: Spec
spec = do
let doTwice :: IO () -> IO ()
doTwice f = f >> f
around_ doTwice $ do
it "should pass" TrueNote: If you're interested in fixing this, talk to me, but only after GHC has gotten impredicative types because that will likely be a requirement.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
Run a custom action before and/or after every spec item, to provide access to an inner resource c while using the inner resource d.
See the FOOTGUN note in the docs for around_.
Note that this function turns off shrinking. See https://github.com/nick8325/quickcheck/issues/331
A function that can provide a resource.
You can think of this as a potentially-resource-aware version of 'IO resource'. In other words, it's like an 'IO resource' that can clean up after itself.
This type has a monad instance, which means you can now compose setup functions using regular do-notation. This works together nicely with most supplier functions. Some examples:
Note that these examples already have functions defined for them in sydtest companion libraries.
SetupFuncunSetupFunc :: forall r. (resource -> IO r) -> IO rUse aroundWith with a SetupFunc
Use aroundWith' with a SetupFunc
Use aroundAllWith with a SetupFunc
Use aroundAllWithAll with a SetupFunc
Eq TestRunSettingsDefined in sydtest-0.22.0.0 · Test.Syd.RunShow TestRunSettingsDefined in sydtest-0.22.0.0 · Test.Syd.RunGeneric TestRunSettingsDefined in sydtest-0.22.0.0 · Test.Syd.Runtype Rep TestRunSettings = D1 ('MetaData "TestRunSettings"
"Test.Syd.Run"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) (C1 ('MetaCons "TestRunSettings"
'PrefixI 'True) ((S1 ('MetaSel ('Just "testRunSettingSeed"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 SeedSetting) :*: (S1 ('MetaSel ('Just "testRunSettingMaxSuccess"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int) :*: S1 ('MetaSel ('Just "testRunSettingMaxSize"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int))) :*: ((S1 ('MetaSel ('Just "testRunSettingMaxDiscardRatio"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int) :*: S1 ('MetaSel ('Just "testRunSettingMaxShrinks"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedUnpack) (Rec0 Int)) :*: (S1 ('MetaSel ('Just "testRunSettingGoldenStart"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: S1 ('MetaSel ('Just "testRunSettingGoldenReset"
) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool)))))Defined in sydtest-0.22.0.0 · Test.Syd.RunDeclare that all tests below must be run sequentially
Declare that all tests below may be run in parallel. (This is the default.)
Annotate a test group with Parallelism.
Eq ParallelismDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefShow ParallelismDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefGeneric ParallelismDefined in sydtest-0.22.0.0 · Test.Syd.SpecDeftype Rep Parallelism = D1 ('MetaData "Parallelism"
"Test.Syd.SpecDef"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) (C1 ('MetaCons "Parallel"
'PrefixI 'False) U1 :+: C1 ('MetaCons "Sequential"
'PrefixI 'False) U1)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefDeclare that the order of execution of all tests below may be randomised.
Declare that the order of execution of all tests below must not be randomised.
Annotate a test group with ExecutionOrderRandomisation.
Eq ExecutionOrderRandomisationDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefShow ExecutionOrderRandomisationDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefGeneric ExecutionOrderRandomisationDefined in sydtest-0.22.0.0 · Test.Syd.SpecDeftype Rep ExecutionOrderRandomisation = D1 ('MetaData "ExecutionOrderRandomisation"
"Test.Syd.SpecDef"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) (C1 ('MetaCons "RandomiseExecutionOrder"
'PrefixI 'False) U1 :+: C1 ('MetaCons "DoNotRandomiseExecutionOrder"
'PrefixI 'False) U1)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefModify the test timeout
Turn off timeouts
Turn off timeouts
Modify the number of retries to use in flakiness diagnostics.
Turn off retries
Make the number of retries this constant
Mark a test suite as "potentially flaky" with a given number of retries.
This will retry any test in the given test group up to the given number of tries, and pass a test if it passes once. The test output will show which tests were flaky.
WARNING: This is only a valid approach to dealing with test flakiness if it is true that tests never pass accidentally. In other words: tests using flaky must be guaranteed to fail every time if an error is introduced in the code, it should only be added to deal with accidental failures, never accidental passes.
Like flaky, but also shows the given message to the user whenever the test is flaky.
You could use it like this:
flakyWith 3 "Something sometimes goes wrong with the database, see issue 6346" ourTestSuiteMark a test suite as "must not be flaky".
This is useful to have a subgroup of a group marked as flaky that must not be flaky afteral.
Mark a test suite as 'potentially flaky', such that it will not fail if it is flaky but passes at least once.
Like potentiallyFlaky, but with a message.
Annotate a test group with FlakinessMode.
Eq FlakinessModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefShow FlakinessModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefGeneric FlakinessModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDeftype Rep FlakinessMode = D1 ('MetaData "FlakinessMode"
"Test.Syd.SpecDef"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) (C1 ('MetaCons "MayNotBeFlaky"
'PrefixI 'False) U1 :+: C1 ('MetaCons "MayBeFlaky"
'PrefixI 'False) (S1 ('MetaSel 'Nothing 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe String))))Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefMark a test suite as 'should pass'
Mark a test suite as 'should fail'
Annotate a test suite with ExpectationMode
Eq ExpectationModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefShow ExpectationModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDefGeneric ExpectationModeDefined in sydtest-0.22.0.0 · Test.Syd.SpecDeftype Rep ExpectationMode = D1 ('MetaData "ExpectationMode"
"Test.Syd.SpecDef"
"sydtest-0.22.0.0-C6WVjaL6xelIJS238V3PZE"
'False) (C1 ('MetaCons "ExpectPassing"
'PrefixI 'False) U1 :+: C1 ('MetaCons "ExpectFailing"
'PrefixI 'False) U1)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefRun a test suite during test suite definition.
This function only exists for backward compatibility. You can also just use liftIO instead.
The test definition monad
This type has three parameters:
outers: A type-level list of the outer resources. These are resources that are prived once, around a group of tests. (This is the type of the results of aroundAll.)
inner: The inner resource. This is a resource that is set up around every test, and even every example of a property test. (This is the type of the result of around.)
result: The result (TestDefM is a monad.)
In practice, all of these three parameters should be () at the top level.
TestDefMunTestDefM :: WriterT (TestForest outers inner) (ReaderT TestDefEnv IO) resultMonadReader TestDefEnv (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMMonad (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMFunctor (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMApplicative (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMMonadIO (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMMonadWriter (TestForest outers inner) (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMA synonym for a test suite definition
runTest :: e -> TestRunSettings -> ProgressReporter -> ((Arg1 e -> Arg2 e -> IO ()) -> IO ()) -> IO TestRunResultRunning the test, safely
IsTest PropertyDefined in sydtest-0.22.0.0 · Test.Syd.RunIsTest BoolDefined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (IO ())Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (StagedGolden a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> Property)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> Bool)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> IO ())Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (arg -> StagedGolden a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> ReaderT env IO ())Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> Property)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> Bool)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> IO (GoldenTest a))Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> IO ())Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> GoldenTest a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (outerArgs -> innerArg -> StagedGolden a)Defined in sydtest-0.22.0.0 · Test.Syd.RunIsTest (ReaderT env IO ())Defined in sydtest-0.22.0.0 · Test.Syd.RunTDeftestDefVal :: valuetestDefCallStack :: CallStackA tree of tests
This type has three parameters:
outers: A type-level list of the outer resources. These are resources that are prived once, around a group of tests. (This is the type of the results of aroundAll.)
inner: The inner resource. This is a resource that is set up around every test, and even every example of a property test. (This is the type of the result of around.)
result: The result (TestDefM is a monad.)
In practice, all of these three parameters should be () at the top level.
When you're just using sydtest and not writing a library for sydtest, you probably don't even want to concern yourself with this type.
DefSpecifyNode :: Text -> TDef (ProgressReporter -> ((HList outers -> inner -> IO ()) -> IO ()) -> IO TestRunResult) -> extra -> SpecDefTree outers inner extraDefine a test
DefPendingNode :: Text -> Maybe Text -> SpecDefTree outers inner extraDefine a pending test
DefDescribeNode :: Text -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraGroup tests using a description
DefSetupNode :: IO () -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefBeforeAllNode :: IO outer -> SpecDefForest (outer ': outers) inner extra -> SpecDefTree outers inner extraDefBeforeAllWithNode :: (oldOuter -> IO newOuter) -> SpecDefForest (newOuter ': oldOuter ': otherOuters) inner extra -> SpecDefTree (oldOuter ': otherOuters) inner extraDefWrapNode :: (IO () -> IO ()) -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefAroundAllNode :: ((outer -> IO ()) -> IO ()) -> SpecDefForest (outer ': outers) inner extra -> SpecDefTree outers inner extraDefAroundAllWithNode :: ((newOuter -> IO ()) -> HList (oldOuter ': otherOuters) -> IO ()) -> SpecDefForest (newOuter ': oldOuter ': otherOuters) inner extra -> SpecDefTree (oldOuter ': otherOuters) inner extraDefAfterAllNode :: (HList outers -> IO ()) -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefParallelismNode :: Parallelism -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraControl the level of parallelism for a given group of tests
DefRandomisationNode :: ExecutionOrderRandomisation -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraControl the execution order randomisation for a given group of tests
DefTimeoutNode :: (Timeout -> Timeout) -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefRetriesNode :: (Word -> Word) -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefFlakinessNode :: FlakinessMode -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraDefExpectationNode :: ExpectationMode -> SpecDefForest outers inner extra -> SpecDefTree outers inner extraFunctor (SpecDefTree a c)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefFoldable (SpecDefTree a c)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefTraversable (SpecDefTree a c)Defined in sydtest-0.22.0.0 · Test.Syd.SpecDefMonadWriter (TestForest outers inner) (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMA synonym for easy migration from hspec
A synonym for easy migration from hspec
A synonym for easy migration from hspec
Convert a generic value into a pretty String, if possible.
Pretty print a generic value to stdout. This is particularly useful in the GHCi interactive environment.
module Test.Syd.Def
module Test.Syd.Expectation
module Test.Syd.HList
module Test.Syd.Modify
module Test.Syd.Output
module Test.Syd.Run
module Test.Syd.Runner
module Test.Syd.SpecDef
module Test.Syd.SpecForest
Monads in which IO computations may be embedded. Any monad built by applying a sequence of monad transformers to the IO monad will be an instance of this class.
Instances should satisfy the following laws, which state that liftIO is a transformer of monads:
liftIO :: IO a -> m aLift a computation from the IO monad. This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations (i.e. IO is the base monad for the stack).
import Control.Monad.Trans.State -- from the "transformers" library
printState :: Show s => StateT s IO ()
printState = do
state <- get
liftIO $ print stateHad we omitted liftIO, we would have ended up with this error:
• Couldn't match type ‘IO’ with ‘StateT s IO’
Expected type: StateT s IO ()
Actual type: IO ()The important part here is the mismatch between StateT s IO () and IO ().
Luckily, we know of a function that takes an IO a and returns an (m a): liftIO,
enabling us to run the program and see the expected results:
> evalStateT printState "hello"
"hello"
> evalStateT printState 3
3
MonadIO IODefined in base-4.20.2.0 · Control.Monad.IO.ClassMonadIO AcquireDefined in resourcet-1.3.0 · Data.Acquire.InternalMonadIO SetupFuncDefined in sydtest-0.22.0.0 · Test.Syd.Def.SetupFuncMonadIO QDefined in template-haskell-2.22.0.0 · Language.Haskell.TH.SyntaxMonadIO m => MonadIO (PropertyM m)Defined in QuickCheck-2.15.0.1 · Test.QuickCheck.MonadicMonadIO m => MonadIO (ZeptoT m)Defined in attoparsec-0.14.4 · Data.Attoparsec.ZeptoMonadIO m => MonadIO (CatchT m)Defined in exceptions-0.10.9 · Control.Monad.Catch.PureMonadIO m => MonadIO (ListT m)Defined in opt-env-conf-0.11.0.0 · OptEnvConf.NonDetMonadIO m => MonadIO (ResourceT m)Defined in resourcet-1.3.0 · Control.Monad.Trans.Resource.InternalMonadIO m => MonadIO (MaybeT m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.MaybeMonad m => MonadIO (QuoteToQuasi m)Defined in th-compat-0.1.6 · Language.Haskell.TH.Syntax.CompatMonadIO (TestDefM outers inner)Defined in sydtest-0.22.0.0 · Test.Syd.Def.TestDefMMonadIO m => MonadIO (RandT g m)Defined in MonadRandom-0.6.2 · Control.Monad.Trans.Random.LazyMonadIO m => MonadIO (RandT g m)Defined in MonadRandom-0.6.2 · Control.Monad.Trans.Random.StrictMonadIO m => MonadIO (ValidationT e m)Defined in opt-env-conf-0.11.0.0 · OptEnvConf.ValidationMonadIO m => MonadIO (ExceptT e m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.ExceptMonadIO m => MonadIO (IdentityT m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.IdentityMonadIO m => MonadIO (ReaderT r m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.ReaderMonadIO m => MonadIO (SelectT r m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.SelectMonadIO m => MonadIO (StateT s m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.State.LazyMonadIO m => MonadIO (StateT s m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.State.StrictMonadIO m => MonadIO (WriterT w m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.Writer.CPS(Monoid w, MonadIO m) => MonadIO (WriterT w m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.Writer.Lazy(Monoid w, MonadIO m) => MonadIO (WriterT w m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.Writer.Strict(Monoid w, Functor m, MonadIO m) => MonadIO (AccumT w m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.Accum(Selective f, MonadIO f) => MonadIO (ExceptT e f)Defined in selective-0.7.0.1 · Control.Selective.Trans.ExceptMonadIO m => MonadIO (ConduitT i o m)Defined in conduit-1.3.6.1 · Data.Conduit.Internal.ConduitMonadIO m => MonadIO (ParsecT s u m)Defined in parsec-3.1.18.0 · Text.Parsec.PrimMonadIO m => MonadIO (ContT r m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.ContMonadIO m => MonadIO (RWST r w s m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.RWS.CPS(Monoid w, MonadIO m) => MonadIO (RWST r w s m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.RWS.Lazy(Monoid w, MonadIO m) => MonadIO (RWST r w s m)Defined in transformers-0.6.1.1 · Control.Monad.Trans.RWS.StrictMonadIO m => MonadIO (Pipe l i o u m)Defined in conduit-1.3.6.1 · Data.Conduit.Internal.Pipe