HORIZON HASKELLDocslts/ghc-10.0.x8c2f8e82026-10-19Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8c2f8e8 · 2026-10-19

Modulehledger-lib-1.52.4GHC2021

Hledger.Utils.Test

  • 8 types
  • 2 classes
  • 34 values
valuewithResource
  1. :: IO a

    initialize the resource

  2. -> (a -> IO ())

    free the resource

  3. -> (IO a -> TestTree)

    IO a is an action which returns the acquired resource. Despite it being an IO action, the resource it returns will be acquired only once and shared across all the tests in the tree.

  4. -> TestTree
#

Acquire the resource to run this test (sub)tree and release it afterwards.

valueafter
  1. :: DependencyType

    whether to run the tests even if some of the dependencies fail

  2. -> String

    the pattern

  3. -> TestTree

    the subtree that depends on other tests

  4. -> TestTree

    the subtree annotated with dependency information

#

The after combinator declares dependencies between tests.

If a TestTree is wrapped in after, the tests in this tree will not run until certain other tests («dependencies») have finished. These dependencies are specified using an AWK pattern (see the «Patterns» section in the README).

Moreover, if the DependencyType argument is set to AllSucceed and at least one dependency has failed, this test tree will not run at all.

Tasty does not check that the pattern matches any tests (let alone the correct set of tests), so it is on you to supply the right pattern.

Examples

The following test will be executed only after all tests that contain Foo anywhere in their path finish.

after AllFinish "Foo" $
   

testCase "A test that depends on Foo.Bar" $ ...

Note, however, that our test also happens to contain Foo as part of its name, so it also matches the pattern and becomes a dependency of itself. This will result in a Test.Tasty.DependencyLoop exception. To avoid this, either change the test name so that it doesn't mention Foo or make the pattern more specific.

You can use AWK patterns, for instance, to specify the full path to the dependency.

after AllFinish "$0 == \"Tests.Foo.Bar\"" $
   

testCase "A test that depends on Foo.Bar" $ ...

Or only specify the dependency's own name, ignoring the group names:

after AllFinish "$NF == \"Bar\"" $
   

testCase "A test that depends on Foo.Bar" $ ...

valueafter_
  1. :: DependencyType

    whether to run the tests even if some of the dependencies fail

  2. -> Expr

    the pattern

  3. -> TestTree

    the subtree that depends on other tests

  4. -> TestTree

    the subtree annotated with dependency information

#

Like after, but accepts the pattern as a syntax tree instead of a string. Useful for generating a test tree programmatically.

Examples

Only match on the test's own name, ignoring the group names:

after_ AllFinish (EQ (Field NF) (StringLit "Bar")) $
   

testCase "A test that depends on Foo.Bar" $ ...

valuedependentTestGroup
  1. :: TestName

    name of the group

  2. -> DependencyType

    whether to run subsequent tests even if earlier ones have failed

  3. -> [TestTree]

    tests to execute sequentially

  4. -> TestTree
#

Create a named group of test cases or other groups. Tests are executed in order and each test is considered a dependency of the next one. If filtering by TestPattern (--pattern) is in action, any test matching the pattern also shields earlier tests from filtering out, even if they themselves do not match the pattern.

For parallel execution, see testGroup. For ordered test execution, but with default filtering behavior, see inOrderTestGroup.

Note that this is will only work when used with the default TestManager. If you use another manager, like tasty-rerun for instance, sequentiality might possibly be ignored.

valueinOrderTestGroup
  1. :: TestName

    name of the group

  2. -> [TestTree]

    tests to execute sequentially

  3. -> TestTree
#

Create a named group of test cases that will be played sequentially, in the exact order provided. Similarly to testGroup and in contrast to dependentTestGroup, filtering by TestPattern is applied uniformly.

Note that this is will only work when used with the default TestManager. If you use another manager, like tasty-rerun for instance, the fact that these tests should be run in the given order might possibly be ignored.

datadata DependencyType
#

These are the two ways in which one test may depend on the others.

This is the same distinction as the hard vs soft dependencies in TestNG.

Constructors

  • AllSucceed

    The current test tree will be executed after its dependencies finish, and only if all of the dependencies succeed.

  • AllFinish

    The current test tree will be executed after its dependencies finish, regardless of whether they succeed or not.

Instances3Eq, Read, Show
datadata TestTree
#

The main data structure defining a test suite.

It consists of individual test cases and properties, organized in named groups which form a tree-like hierarchy.

There is no generic way to create a test case. Instead, every test provider (tasty-hunit, tasty-smallcheck etc.) provides a function to turn a test case into a TestTree.

Groups can be created using testGroup.

datadata Timeout
#

Timeout to be applied to individual tests.

Constructors

Instances4Eq, Ord, Show, IsOption
  • Eq TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core

    Auto-derived instance, just to allow storing in a Data.Map.Map and such.

  • Ord TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core

    Auto-derived instance, just to allow storing in a Data.Map.Map and such.

  • Show TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core
  • IsOption TimeoutDefined in tasty-1.5.4 · Test.Tasty.Options.Core
value(@=?)
  1. :: (Eq a, Show a, HasCallStack)
  2. => a

    The expected value

  3. -> a

    The actual value

  4. -> Assertion
#

Asserts that the specified actual value is equal to the expected value (with the expected value on the left-hand side).

value(@?)
  1. :: (AssertionPredicable t, HasCallStack)
  2. => t

    A value of which the asserted condition is predicated

  3. -> String

    A message that is displayed if the assertion fails

  4. -> Assertion
#

An infix and flipped version of assertBool. E.g. instead of

assertBool "Non-empty list" (null [1])

you can write

null [1] @? "Non-empty list"

@? is also overloaded to accept IO Bool predicates, so instead of

do
  e <- doesFileExist "test"
  e @? "File does not exist"

you can write

doesFileExist "test" @? "File does not exist"
value(@?=)
  1. :: (Eq a, Show a, HasCallStack)
  2. => a

    The actual value

  3. -> a

    The expected value

  4. -> Assertion
#

Asserts that the specified actual value is equal to the expected value (with the actual value on the left-hand side).

valueassertEqual
  1. :: (Eq a, Show a, HasCallStack)
  2. => String

    The message prefix

  3. -> a

    The expected value

  4. -> a

    The actual value

  5. -> Assertion
#

Asserts that the specified actual value is equal to the expected value. The output message will contain the prefix, the expected value, and the actual value.

If the prefix is the empty string (i.e., ""), then the prefix is omitted and only the expected and actual values are output.

valueassertFailure
  1. :: HasCallStack
  2. => String

    A message that is displayed with the assertion failure

  3. -> IO a
#

Unconditionally signals that a failure has occured. All other assertions can be expressed with the form:

   if conditionIsMet
       then return ()
       else assertFailure msg
valueassertString
  1. :: HasCallStack
  2. => String

    The message that is displayed with the assertion failure

  3. -> Assertion
#

Deprecated. Why not use assertBool instead?

Signals an assertion failure if a non-empty message (i.e., a message other than "") is passed.

valuetestCaseSteps :: TestName -> ((String -> IO ()) -> Assertion) -> TestTree
#

Create a multi-step unit test.

Example:

main = defaultMain $ testCaseSteps "Multi-step test" $ \step -> do
  step "Preparing..."
  -- do something

  step "Running part 1"
  -- do something

  step "Running part 2"
  -- do something
  assertFailure "BAM!"

  step "Running part 3"
  -- do something

The step calls are mere annotations. They let you see which steps were performed successfully, and which step failed.

You can think of step as putStrLn, except putStrLn would mess up the output with the console reporter and get lost with the others.

For the example above, the output will be

Multi-step test: FAIL
  Preparing...
  Running part 1
  Running part 2
    BAM!

1 out of 1 tests failed (0.00s)

Note that:

  • Tasty still treats this as a single test, even though it consists of multiple steps.

  • The execution stops after the first failure. When we are looking at a failed test, we know that all displayed steps but the last one were successful, and the last one failed. The steps after the failed one are not displayed, since they didn't run.

typetype HasCallStack = IP "callStack" CallStack
#

Request a CallStack.

NOTE: The implicit parameter ?callStack :: CallStack is an implementation detail and should not be considered part of the CallStack API, we may decide to change the implementation in the future.

classclass Assertable t where
#

Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.

Allows the extension of the assertion mechanism.

Since an Assertion can be a sequence of Assertions and IO actions, there is a fair amount of flexibility of what can be achieved. As a rule, the resulting Assertion should be the body of a TestCase or part of a TestCase; it should not be used to assert multiple, independent conditions.

If more complex arrangements of assertions are needed, Test and Testable should be used.

Methods

Instances4Assertable
typetype Assertion = IO ()
#

An assertion is simply an IO action. Assertion failure is indicated by throwing an exception, typically HUnitFailure.

Instead of throwing the exception directly, you should use functions like assertFailure and assertBool.

Test cases are composed of a sequence of one or more assertions.

typetype AssertionPredicate = IO Bool
#

Deprecated. This class or type seems dubious. If you have a good use case for it, please create an issue for tasty. Otherwise, it may be removed in a future version.

The result of an assertion that hasn't been evaluated yet.

Most test cases follow the following steps:

  1. Do some processing or an action.

  2. Assert certain conditions.

However, this flow is not always suitable. AssertionPredicate allows for additional steps to be inserted without the initial action to be affected by side effects. Additionally, clean-up can be done before the test case has a chance to end. A potential work flow is:

  1. Write data to a file.

  2. Read data from a file, evaluate conditions.

  3. Clean up the file.

  4. Assert that the side effects of the read operation meet certain conditions.

  5. Assert that the conditions evaluated in step 2 are met.