-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | The Haskell Test Framework -- -- The Haskell Test Framework (HTF for short) lets you define unit -- tests (http://hunit.sourceforge.net), QuickCheck properties -- (http://www.cs.chalmers.se/~rjmh/QuickCheck/), and black box -- tests in an easy and convenient way. The HTF uses a custom -- preprocessor that collects test definitions automatically. -- Furthermore, the preprocessor allows the HTF to report failing test -- cases with exact file name and line number information. -- -- The documentation of the Test.Framework.Tutorial module -- provides a tutorial for the HTF. @package HTF @version 0.3.1 module Test.Framework.Pretty class Pretty a pretty :: (Pretty a) => a -> Doc prettyList :: (Pretty a) => [a] -> Doc showPretty :: (Pretty a) => a -> String (<=>) :: Doc -> Doc -> Doc instance Pretty Bool instance Pretty Int instance (Pretty a) => Pretty [a] instance Pretty Char module Test.Framework.Location -- | An abstract type representing locations in a file. data Location fileName :: Location -> String lineNumber :: Location -> Int showLoc :: Location -> String -- | Create a new location. makeLoc :: String -> Int -> Location module Test.Framework.TestManager type TestID = String type Assertion = IO () data Test data TestSuite type Filter = FlatTest -> Bool data FlatTest FlatTest :: TestSort -> TestID -> (Maybe Location) -> Assertion -> FlatTest data TestSort UnitTest :: TestSort QuickCheckTest :: TestSort BlackBoxTest :: TestSort class TestableHTF t quickCheckTestFail :: Maybe String -> Assertion quickCheckTestError :: Maybe String -> Assertion unitTestFail :: String -> IO a blackBoxTestFail :: String -> Assertion makeQuickCheckTest :: TestID -> Location -> Assertion -> Test makeUnitTest :: TestID -> Location -> IO a -> Test makeBlackBoxTest :: TestID -> Assertion -> Test makeTestSuite :: TestID -> [Test] -> TestSuite makeAnonTestSuite :: [Test] -> TestSuite addToTestSuite :: TestSuite -> [Test] -> TestSuite testSuiteAsTest :: TestSuite -> Test runTest :: (TestableHTF t) => t -> IO () runTestWithArgs :: (TestableHTF t) => [String] -> t -> IO () runTestWithFilter :: (TestableHTF t) => Filter -> t -> IO () instance Eq TestSort instance Show TestSort instance Read TestSort instance TestableHTF TestSuite instance TestableHTF Test -- | A black box test in the terminology of the HTF consists of a -- driver program that is run in various input files. For each input -- file, the HTF checks that the driver program exits with the correct -- exit code and that it produces the expected output. module Test.Framework.BlackBoxTest data BBTArgs BBTArgs :: String -> String -> String -> String -> Bool -> Diff -> Diff -> BBTArgs bbtArgs_stdinSuffix :: BBTArgs -> String bbtArgs_stdoutSuffix :: BBTArgs -> String bbtArgs_stderrSuffix :: BBTArgs -> String bbtArgs_dynArgsName :: BBTArgs -> String bbtArgs_verbose :: BBTArgs -> Bool bbtArgs_stdoutDiff :: BBTArgs -> Diff bbtArgs_stderrDiff :: BBTArgs -> Diff defaultBBTArgs :: BBTArgs blackBoxTests :: FilePath -> String -> String -> BBTArgs -> IO [Test] -- | The type of a function comparing the content of a file against a -- string, similar to the unix tool diff. The first parameter is -- the name of the file containing the expected output. If this parameter -- is Nothing, then no output is expected. The second parameter is -- the actual output produced. If the result is Nothing then no -- difference was found. Otherwise, a Just value contains a string -- explaining the different. type Diff = Maybe FilePath -> String -> IO (Maybe String) defaultDiff :: Diff module Test.Framework.QuickCheckWrapper testableAsAssertion :: (Testable t, WithQCArgs t) => t -> Assertion data TestableWithQCArgs class WithQCArgs a withQCArgs :: (WithQCArgs a, Testable a) => (Args -> Args) -> a -> TestableWithQCArgs asTestableWithQCArgs :: (WithQCArgs a, Testable a) => a -> TestableWithQCArgs instance [overlap ok] WithQCArgs TestableWithQCArgs instance [overlap ok] WithQCArgs a instance [overlap ok] Testable TestableWithQCArgs -- | You should not use the functions provided by this module directly. -- Instead, for each function assertXXX_ defined in this module, -- there exist a preprocessor macro assertXXX, which provides -- the Location parameter automatically. | module Test.Framework.HUnitWrapper assertBool_ :: Location -> Bool -> Assertion assertEqual_ :: (Eq a, Show a) => Location -> a -> a -> Assertion assertEqualP_ :: (Eq a, Pretty a) => Location -> a -> a -> Assertion assertEqualNoShow_ :: (Eq a) => Location -> a -> a -> Assertion assertNotEmpty_ :: Location -> [a] -> Assertion assertEmpty_ :: Location -> [a] -> Assertion assertSetEqual_ :: (Eq a, Show a) => Location -> [a] -> [a] -> Assertion assertThrows_ :: (Exception e) => Location -> a -> (e -> Bool) -> Assertion assertThrowsSome_ :: Location -> a -> Assertion assertLeft_ :: (Show b) => Location -> Either a b -> IO a assertLeftNoShow_ :: Location -> Either a b -> IO a assertRight_ :: (Show a) => Location -> Either a b -> IO b assertRightNoShow_ :: Location -> Either a b -> IO b assertJust_ :: Location -> Maybe a -> IO a assertFailure :: String -> IO a module Test.Framework -- | Create a new location. makeLoc :: String -> Int -> Location -- | This module provides a short tutorial on how to use the HTF. It -- assumes that you are using GHC for compiling your Haskell code. (It is -- possible to use the HTF with other Haskell environments, only the -- steps taken to invoke the custom preprocessor of the HTF may differ in -- this case.) -- -- Suppose you are writing a function for reversing lists: -- --
-- myReverse :: [a] -> [a] -- myReverse [] = [] -- myReverse [x] = [x] -- myReverse (x:xs) = myReverse xs ---- -- To test this function using the HTF, you first create a new source -- file with a OPTIONS_GHC pragma in the first line. -- --
-- {-# OPTIONS_GHC -F -pgmF htfpp #-}
--
--
-- This pragma instructs GHC to run the source file through
-- htfpp, the custom preprocessor of the HTF.
--
-- The following import statements are also needed:
--
-- -- import System.Environment ( getArgs ) -- import Test.Framework ---- -- The actual unit tests and QuickCheck properties are defined like this: -- --
-- test_nonEmpty = do assertEqual [1] (myReverse [1]) -- assertEqual [3,2,1] (myReverse [1,2,3]) -- -- test_empty = assertEqual ([] :: [Int]) (myReverse []) -- -- prop_reverse :: [Int] -> Bool -- prop_reverse xs = xs == (myReverse (myReverse xs)) ---- -- When htfpp consumes the source file, it replaces the -- assertEqual tokens (and other assert-like tokens, -- see Test.Framework.HUnitWrapper) with calls to -- assertEqual_, passing the current location in the file as the -- first argument. Moreover, the preprocessor collects all top-level -- definitions starting with test_ or prop_ in a test -- suite with name allHTFTests of type TestSuite. -- -- Definitions starting with test_ denote unit tests and must be -- of type Assertion. Definitions starting with prop_ -- denote QuickCheck properties and must be of type T such that -- T is an instance of the type class Testable. -- -- To run the tests, use the runTestWithArgs function, which takes -- a list of strings and the test. -- --
-- main = -- do args <- getArgs -- runTestWithArgs args reverseTests ---- -- Here is the skeleton of a .cabal file which you may want to -- use to compile the tests. -- --
-- Name: HTF-tutorial -- Version: 0.1 -- Cabal-Version: >= 1.6 -- Build-type: Simple -- -- Executable tutorial -- Main-is: Tutorial.hs -- Build-depends: base, HTF ---- -- Compiling the program just shown (you must include the code for -- myReverse as well), and then running the resulting program -- with no further commandline arguments yields the following output: -- --
-- Main:nonEmpty (Tutorial.hs:17) -- *** Failed! assertEqual failed at Tutorial.hs:18 -- expected: [3,2,1] -- but got: [3] -- -- Main:empty (Tutorial.hs:19) -- +++ OK -- -- Main:reverse (Tutorial.hs:22) -- *** Failed! Falsifiable (after 3 tests and 1 shrink): -- [0,0] -- Replay argument: "Just (847701486 2147483396,2)" -- -- * Tests: 3 -- * Passed: 1 -- * Failures: 2 -- * Errors: 0 ---- -- (To check only specific tests, you can pass commandline arguments to -- the program: the HTF then runs only those tests whose name contain at -- least one of the commandline arguments as a substring.) -- -- You see that the message for the first failure contains exact location -- information, which is quite convenient. Moreover, for the QuickCheck -- property Main.reverse, the HTF also outputs a string -- represenation of the random generator used to check the property. This -- string representation can be used to replay the property. (The replay -- feature may not be useful for this simple example but it helps in more -- complex scenarios). -- -- To replay a property you simply use the string representation of the -- generator to define a new QuickCheck property with custom arguments: -- --
-- prop_reverseReplay =
-- withQCArgs (a -> a { replay = read "Just (1060394807 2147483396,2)" })
-- prop_reverse
--
--
-- To finish this tutorial, we now give a correct definition for
-- myReverse:
--
-- -- myReverse :: [a] -> [a] -- myReverse [] = [] -- myReverse (x:xs) = myReverse xs ++ [x] ---- -- Running our tests again on the fixed definition then yields the -- desired result: -- --
-- Main:nonEmpty (Tutorial.hs:17) -- +++ OK -- -- Main:empty (Tutorial.hs:19) -- +++ OK -- -- Main:reverse (Tutorial.hs:22) -- +++ OK, passed 100 tests. -- -- Main:reverseReplay (Tutorial.hs:24) -- +++ OK, passed 100 tests. -- -- * Tests: 4 -- * Passed: 4 -- * Failures: 0 -- * Errors: 0 ---- -- The HTF also allows the definition of black box tests. See the -- documentation of the Test.Framework.BlackBoxTest module for -- further information. module Test.Framework.Tutorial