Safe Haskell | None |
---|
Helps you build a tree of tests that run against a series of items. This is best illustrated with an example.
Let's say that you have a list of Int. You want to make sure that every Int in the list is odd and that every Int is greater than zero. You also want to make sure that at least 5 Ints in the list are greater than 20.
Pdct
from Data.Prednote.Pdct will help you, but only so much: a
Pdct
can test individual Int, but by itself it will not help you
run a check against a whole list of Int. Of course you can build
such a test fairly easily with any
and all
, but what if you
want to view the results of the tests verbosely? That's where this
module comes in.
{-# LANGUAGE OverloadedStrings #-} import System.Console.Rainbow import Data.Prednote.TestTree import Data.Prednote.Pdct isOdd :: Pdct Int isOdd = operand "is odd" odd greaterThan0 :: Pdct Int greaterThan0 = operand "greater than zero" (> 0) greaterThan20 :: Pdct Int greaterThan20 = operand "greater than 20" (> 20) myOpts :: TestOpts Int myOpts = TestOpts { tIndentAmt = 2 , tPassVerbosity = TrueSubjects , tFailVerbosity = TrueSubjects , tGroupPred = const True , tTestPred = const True , tShowSkippedTests = True , tGroupVerbosity = AllGroups , tSubjects = mySubjects , tStopOnFail = False } mySubjects :: [Int] mySubjects = [2, 4, 6, 8, 10, 18, 19, 20, 21, 22, 24, 26] tests :: [TestTree Int] tests = [ isOdd, greaterThan0, greaterThan20 ] main :: IO () main = do let (cks, passed, failed) = runTests myOpts 0 tests t <- termFromEnv printChunks t cks putStrLn $ "number of tests passed: " ++ show passed putStrLn $ "number of tests failed: " ++ show failed
- type Name = Text
- type TestFunc a = IndentAmt -> Verbosity -> Verbosity -> [a] -> Level -> (Pass, [Chunk])
- data TestTree a = TestTree Name (Payload a)
- data Payload a
- test :: Name -> TestFunc a -> TestTree a
- eachSubjectMustBeTrue :: Name -> (a -> Text) -> Pdct a -> TestTree a
- nSubjectsMustBeTrue :: Name -> (a -> Text) -> Int -> Pdct a -> TestTree a
- group :: Name -> [TestTree a] -> TestTree a
- data Verbosity
- = Silent
- | PassFail
- | FalseSubjects
- | TrueSubjects
- | Discards
- data GroupVerbosity
- = NoGroups
- | ActiveGroups
- | AllGroups
- type Level = Int
- type PassCount = Int
- type FailCount = Int
- runTests :: TestOpts a -> Level -> [TestTree a] -> ([Chunk], PassCount, FailCount)
- showTestTree :: IndentAmt -> Level -> TestTree a -> [Chunk]
- data TestOpts a = TestOpts {
- tIndentAmt :: Int
- tPassVerbosity :: Verbosity
- tFailVerbosity :: Verbosity
- tGroupPred :: Name -> Bool
- tTestPred :: Name -> Bool
- tShowSkippedTests :: Bool
- tGroupVerbosity :: GroupVerbosity
- tSubjects :: [a]
- tStopOnFail :: Bool
- type ShortCircuit = Bool
- type Pass = Bool
- evalTree :: TestOpts a -> Level -> TestTree a -> (ShortCircuit, [Either [Chunk] (Pass, [Chunk])])
The TestTree
= IndentAmt | |
-> Verbosity | Use this verbosity for tests that pass |
-> Verbosity | Use this verbosity for tests that fail |
-> [a] | |
-> Level | |
-> (Pass, [Chunk]) |
A test is a function of this type. The function must make chunks in a manner that respects the applicable verbosity.
Tests
eachSubjectMustBeTrue :: Name -> (a -> Text) -> Pdct a -> TestTree aSource
Passes if every subject is True.
nSubjectsMustBeTrue :: Name -> (a -> Text) -> Int -> Pdct a -> TestTree aSource
Passes if at least n subjects are True.
Grouping tests
Simple test runners
How verbose to be when reporting the results of tests. It would be possible to have many more knobs to control this behavior; this implementation is a compromise and hopefully provides enough verbosity settings without being too complex.
Silent | Show nothing at all |
PassFail | Show only whether the test passed or failed |
FalseSubjects | Show subjects that are False. In addition, shows all evaluation steps that led to the subject being False; however, does not show discarded evaluation steps. Does not show True subjects at all. |
TrueSubjects | Show subjects that are True. (This is cumulative, so False
subjects are shown too, as they would be using |
Discards | Shows discarded subjects. Cumulative, so also does what
|
data GroupVerbosity Source
How verbose to be when showing names of groups.
NoGroups | Show no group names at all. However, groups will still be indented. |
ActiveGroups | Show groups that are not skipped. |
AllGroups | Show all groups, and indicate which groups are skipped. |
How many levels of indentation to use. Typically you will start this at zero. It is incremented by one for each level as functions descend through the tree.
runTests :: TestOpts a -> Level -> [TestTree a] -> ([Chunk], PassCount, FailCount)Source
Runs each test in a list of tests (though each test might not run
if tStopOnFail
is True.) Reports on how many passed and how many
failed. (if tStopOnFail
is True, the FailCount will never exceed
1.)
Showing the test tree
showTestTree :: IndentAmt -> Level -> TestTree a -> [Chunk]Source
Shows a tree, without evaluating it.
Tree evaluator
Options for running tests.
TestOpts | |
|
type ShortCircuit = BoolSource
True if the tree returned a result without completely evaluating
all parts of the tree. This can occur if tStopOnFail
is True and
one of the tests in the tree failed.
:: TestOpts a | Most options |
-> Level | The tree will indented by this many levels; typically you will want to start this at 0. |
-> TestTree a | |
-> (ShortCircuit, [Either [Chunk] (Pass, [Chunk])]) | The first element of the tuple is True if the tree was not
fully evaluated. This can happen if |
Evaluates a tree. This function is the basis of runTests
, which
is typically a bit easier to use.