|
Packit |
b7c5e3 |
# Tasty
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
**Tasty** is a modern testing framework for Haskell.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It lets you combine your unit tests, golden tests, QuickCheck/SmallCheck
|
|
Packit |
b7c5e3 |
properties, and any other types of tests into a single test suite.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Features:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* Run tests in parallel but report results in a deterministic order
|
|
Packit |
b7c5e3 |
* Filter the tests to be run using patterns specified on the command line
|
|
Packit |
b7c5e3 |
* Hierarchical, colored display of test results
|
|
Packit |
b7c5e3 |
* Reporting of test statistics
|
|
Packit |
b7c5e3 |
* Acquire and release resources (sockets, temporary files etc.) that can be
|
|
Packit |
b7c5e3 |
shared among several tests
|
|
Packit |
b7c5e3 |
* Extensibility: add your own test providers and ingredients (runners) above and
|
|
Packit |
b7c5e3 |
beyond those provided
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
To find out what's new, read the **[change log][]**.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[change log]: https://github.com/feuerbach/tasty/blob/master/core/CHANGELOG.md
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## Example
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Here's how your `test.hs` might look like:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
```haskell
|
|
Packit |
b7c5e3 |
import Test.Tasty
|
|
Packit |
b7c5e3 |
import Test.Tasty.SmallCheck as SC
|
|
Packit |
b7c5e3 |
import Test.Tasty.QuickCheck as QC
|
|
Packit |
b7c5e3 |
import Test.Tasty.HUnit
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
import Data.List
|
|
Packit |
b7c5e3 |
import Data.Ord
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
main = defaultMain tests
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
tests :: TestTree
|
|
Packit |
b7c5e3 |
tests = testGroup "Tests" [properties, unitTests]
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
properties :: TestTree
|
|
Packit |
b7c5e3 |
properties = testGroup "Properties" [scProps, qcProps]
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
scProps = testGroup "(checked by SmallCheck)"
|
|
Packit |
b7c5e3 |
[ SC.testProperty "sort == sort . reverse" $
|
|
Packit |
b7c5e3 |
\list -> sort (list :: [Int]) == sort (reverse list)
|
|
Packit |
b7c5e3 |
, SC.testProperty "Fermat's little theorem" $
|
|
Packit |
b7c5e3 |
\x -> ((x :: Integer)^7 - x) `mod` 7 == 0
|
|
Packit |
b7c5e3 |
-- the following property does not hold
|
|
Packit |
b7c5e3 |
, SC.testProperty "Fermat's last theorem" $
|
|
Packit |
b7c5e3 |
\x y z n ->
|
|
Packit |
b7c5e3 |
(n :: Integer) >= 3 SC.==> x^n + y^n /= (z^n :: Integer)
|
|
Packit |
b7c5e3 |
]
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
qcProps = testGroup "(checked by QuickCheck)"
|
|
Packit |
b7c5e3 |
[ QC.testProperty "sort == sort . reverse" $
|
|
Packit |
b7c5e3 |
\list -> sort (list :: [Int]) == sort (reverse list)
|
|
Packit |
b7c5e3 |
, QC.testProperty "Fermat's little theorem" $
|
|
Packit |
b7c5e3 |
\x -> ((x :: Integer)^7 - x) `mod` 7 == 0
|
|
Packit |
b7c5e3 |
-- the following property does not hold
|
|
Packit |
b7c5e3 |
, QC.testProperty "Fermat's last theorem" $
|
|
Packit |
b7c5e3 |
\x y z n ->
|
|
Packit |
b7c5e3 |
(n :: Integer) >= 3 QC.==> x^n + y^n /= (z^n :: Integer)
|
|
Packit |
b7c5e3 |
]
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
unitTests = testGroup "Unit tests"
|
|
Packit |
b7c5e3 |
[ testCase "List comparison (different length)" $
|
|
Packit |
b7c5e3 |
[1, 2, 3] `compare` [1,2] @?= GT
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
-- the following test does not hold
|
|
Packit |
b7c5e3 |
, testCase "List comparison (same length)" $
|
|
Packit |
b7c5e3 |
[1, 2, 3] `compare` [1,2,2] @?= LT
|
|
Packit |
b7c5e3 |
]
|
|
Packit |
b7c5e3 |
```
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
And here is the output of the above program:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
![](https://raw.github.com/feuerbach/tasty/master/screenshot.png)
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
(Note that whether QuickCheck finds a counterexample to the third property is
|
|
Packit |
b7c5e3 |
determined by chance.)
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## Packages
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[tasty][] is the core package. It contains basic definitions and APIs and a
|
|
Packit |
b7c5e3 |
console runner.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[tasty]: http://hackage.haskell.org/package/tasty
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
In order to create a test suite, you also need to install one or more «providers» (see
|
|
Packit |
b7c5e3 |
below).
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Providers
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
The following providers exist:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* [tasty-hunit](http://hackage.haskell.org/package/tasty-hunit) — for unit tests
|
|
Packit |
b7c5e3 |
(based on [HUnit](http://hackage.haskell.org/package/HUnit))
|
|
Packit |
b7c5e3 |
* [tasty-golden][] — for golden
|
|
Packit |
b7c5e3 |
tests, which are unit tests whose results are kept in files
|
|
Packit |
b7c5e3 |
* [tasty-smallcheck](http://hackage.haskell.org/package/tasty-smallcheck) —
|
|
Packit |
b7c5e3 |
exhaustive property-based testing
|
|
Packit |
b7c5e3 |
(based on [smallcheck](http://hackage.haskell.org/package/smallcheck))
|
|
Packit |
b7c5e3 |
* [tasty-quickcheck](http://hackage.haskell.org/package/tasty-quickcheck) — for randomized
|
|
Packit |
b7c5e3 |
property-based testing (based on [QuickCheck](http://hackage.haskell.org/package/QuickCheck))
|
|
Packit |
b7c5e3 |
* [tasty-hedgehog](https://github.com/qfpl/tasty-hedgehog) — for randomized
|
|
Packit |
b7c5e3 |
property-based testing (based on [Hedgehog](http://hackage.haskell.org/package/hedgehog))
|
|
Packit |
b7c5e3 |
* [tasty-hspec](http://hackage.haskell.org/package/tasty-hspec) — for
|
|
Packit |
b7c5e3 |
[Hspec](http://hspec.github.io/) tests
|
|
Packit |
b7c5e3 |
* [tasty-program](http://hackage.haskell.org/package/tasty-program) — run
|
|
Packit |
b7c5e3 |
external program and test whether it terminates successfully
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[tasty-golden]: http://hackage.haskell.org/package/tasty-golden
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It's easy to create custom providers using the API from `Test.Tasty.Providers`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Ingredients
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Ingredients represent different actions that you can perform on your test suite.
|
|
Packit |
b7c5e3 |
One obvious ingredient that you want to include is one that runs tests and
|
|
Packit |
b7c5e3 |
reports the progress and results.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Another standard ingredient is one that simply prints the names of all tests.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It is possible to write custom ingredients using the API from `Test.Tasty.Runners`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Some ingredients that can enhance your test suite are:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* [tasty-ant-xml](http://hackage.haskell.org/package/tasty-ant-xml) adds a
|
|
Packit |
b7c5e3 |
possibility to write the test results in a machine-readable XML format, which
|
|
Packit |
b7c5e3 |
is understood by various CI systems and IDEs
|
|
Packit |
b7c5e3 |
* [tasty-rerun](http://hackage.haskell.org/package/tasty-rerun) adds support for
|
|
Packit |
b7c5e3 |
minimal test reruns by recording previous test runs and using this information
|
|
Packit |
b7c5e3 |
to filter the test tree. For example, you can use this ingredient to only run
|
|
Packit |
b7c5e3 |
failed tests, or only run tests that threw an exception.
|
|
Packit |
b7c5e3 |
* [tasty-html](http://hackage.haskell.org/package/tasty-html) adds the
|
|
Packit |
b7c5e3 |
possibility to write the test results as a HTML file
|
|
Packit |
b7c5e3 |
* [tasty-stats](http://hackage.haskell.org/package/tasty-stats) adds the
|
|
Packit |
b7c5e3 |
possibility to collect statistics of the test suite in a CSV file.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Other packages
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* [tasty-th](http://hackage.haskell.org/package/tasty-th) automatically
|
|
Packit |
b7c5e3 |
discovers tests based on the function names and generate the boilerplate code for
|
|
Packit |
b7c5e3 |
you
|
|
Packit |
b7c5e3 |
* [tasty-hunit-adapter](http://hackage.haskell.org/package/tasty-hunit-adapter)
|
|
Packit |
b7c5e3 |
converts existing HUnit test suites into tasty test suites
|
|
Packit |
b7c5e3 |
* [tasty-discover](https://github.com/lwm/tasty-discover) automatically discovers
|
|
Packit |
b7c5e3 |
your tests.
|
|
Packit |
b7c5e3 |
* [tasty-expected-failure](https://github.com/nomeata/tasty-expected-failure) provides
|
|
Packit |
b7c5e3 |
test markers for when you expect failures or wish to ignore tests.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## Options
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Options allow one to customize the run-time behavior of the test suite, such
|
|
Packit |
b7c5e3 |
as:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* mode of operation (run tests, list tests, run tests quietly etc.)
|
|
Packit |
b7c5e3 |
* which tests are run (see «Patterns» below)
|
|
Packit |
b7c5e3 |
* parameters of individual providers (like depth of search for SmallCheck)
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Setting options
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
There are two main ways to set options:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
#### Runtime
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
When using the standard console runner, the options can be passed on the
|
|
Packit |
b7c5e3 |
command line or via environment variables. To see the available options, run
|
|
Packit |
b7c5e3 |
your test suite with the `--help` flag. The output will look something like this
|
|
Packit |
b7c5e3 |
(depending on which ingredients and providers the test suite uses):
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
```
|
|
Packit |
b7c5e3 |
% ./test --help
|
|
Packit |
b7c5e3 |
Mmm... tasty test suite
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Usage: test [-p|--pattern ARG] [-t|--timeout ARG] [-l|--list-tests]
|
|
Packit |
b7c5e3 |
[-j|--num-threads ARG] [-q|--quiet] [--hide-successes] [--color ARG]
|
|
Packit |
b7c5e3 |
[--quickcheck-tests ARG] [--quickcheck-replay ARG]
|
|
Packit |
b7c5e3 |
[--quickcheck-show-replay ARG] [--quickcheck-max-size ARG]
|
|
Packit |
b7c5e3 |
[--quickcheck-max-ratio ARG] [--quickcheck-verbose]
|
|
Packit |
b7c5e3 |
[--smallcheck-depth ARG]
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Available options:
|
|
Packit |
b7c5e3 |
-h,--help Show this help text
|
|
Packit |
b7c5e3 |
-p,--pattern ARG Select only tests that match pattern
|
|
Packit |
b7c5e3 |
-t,--timeout ARG Timeout for individual tests (suffixes: ms,s,m,h;
|
|
Packit |
b7c5e3 |
default: s)
|
|
Packit |
b7c5e3 |
-l,--list-tests Do not run the tests; just print their names
|
|
Packit |
b7c5e3 |
-j,--num-threads ARG Number of threads to use for tests execution
|
|
Packit |
b7c5e3 |
-q,--quiet Do not produce any output; indicate success only by
|
|
Packit |
b7c5e3 |
the exit code
|
|
Packit |
b7c5e3 |
--hide-successes Do not print tests that passed successfully
|
|
Packit |
b7c5e3 |
--color ARG When to use colored output. Options are 'never',
|
|
Packit |
b7c5e3 |
'always' and 'auto' (default: 'auto')
|
|
Packit |
b7c5e3 |
--quickcheck-tests ARG Number of test cases for QuickCheck to generate
|
|
Packit |
b7c5e3 |
--quickcheck-replay ARG Replay token to use for replaying a previous test run
|
|
Packit |
b7c5e3 |
--quickcheck-show-replay ARG
|
|
Packit |
b7c5e3 |
Show a replay token for replaying tests
|
|
Packit |
b7c5e3 |
--quickcheck-max-size ARG
|
|
Packit |
b7c5e3 |
Size of the biggest test cases quickcheck generates
|
|
Packit |
b7c5e3 |
--quickcheck-max-ratio ARG
|
|
Packit |
b7c5e3 |
Maximum number of discared tests per successful test
|
|
Packit |
b7c5e3 |
before giving up
|
|
Packit |
b7c5e3 |
--quickcheck-verbose Show the generated test cases
|
|
Packit |
b7c5e3 |
--smallcheck-depth ARG Depth to use for smallcheck tests
|
|
Packit |
b7c5e3 |
```
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Every option can be passed via environment. To obtain the environment variable
|
|
Packit |
b7c5e3 |
name from the option name, replace hyphens `-` with underscores `_`, capitalize
|
|
Packit |
b7c5e3 |
all letters, and prepend `TASTY_`. For example, the environment equivalent of
|
|
Packit |
b7c5e3 |
`--smallcheck-depth` is `TASTY_SMALLCHECK_DEPTH`. To turn on a switch (such as
|
|
Packit |
b7c5e3 |
`TASTY_HIDE_SUCCESSES`), set the variable to `True`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
If you're using a non-console runner, please refer to its documentation to find
|
|
Packit |
b7c5e3 |
out how to configure options during the run time.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
#### Compile-time
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
You can also specify options in the test suite itself, using
|
|
Packit |
b7c5e3 |
`localOption`. It can be applied not only to the whole test tree, but also to
|
|
Packit |
b7c5e3 |
individual tests or subgroups, so that different tests can be run with
|
|
Packit |
b7c5e3 |
different options.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It is possible to combine run-time and compile-time options, too, by using
|
|
Packit |
b7c5e3 |
`adjustOption`. For example, make the overall testing depth configurable
|
|
Packit |
b7c5e3 |
during the run time, but increase or decrease it slightly for individual
|
|
Packit |
b7c5e3 |
tests.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
This method currently doesn't work for ingredient options, such as `--quiet` or
|
|
Packit |
b7c5e3 |
`--num-threads`. You can set them by setting the corresponding environment
|
|
Packit |
b7c5e3 |
variable before calling `defaultMain`:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
```haskell
|
|
Packit |
b7c5e3 |
import Test.Tasty
|
|
Packit |
b7c5e3 |
import System.Environment
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
main = do
|
|
Packit |
b7c5e3 |
setEnv "TASTY_NUM_THREADS" "1"
|
|
Packit |
b7c5e3 |
defaultMain _
|
|
Packit |
b7c5e3 |
```
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Patterns
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It is possible to restrict the set of executed tests using the `--pattern`
|
|
Packit |
b7c5e3 |
option. The syntax of patterns is the same as for test-framework, namely:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
- An optional prefixed bang `!` negates the pattern.
|
|
Packit |
b7c5e3 |
- If the pattern ends with a slash, it is removed for the purpose of
|
|
Packit |
b7c5e3 |
the following description, but it would only find a match with a
|
|
Packit |
b7c5e3 |
test group. In other words, `foo/` will match a group called `foo`
|
|
Packit |
b7c5e3 |
and any tests underneath it, but will not match a regular test
|
|
Packit |
b7c5e3 |
`foo`.
|
|
Packit |
b7c5e3 |
- If the pattern does not contain a slash `/`, the framework checks
|
|
Packit |
b7c5e3 |
for a match against any single component of the path.
|
|
Packit |
b7c5e3 |
- Otherwise, the pattern is treated as a glob, where:
|
|
Packit |
b7c5e3 |
- The wildcard `*` matches anything within a single path component
|
|
Packit |
b7c5e3 |
(i.e. `foo` but not `foo/bar`).
|
|
Packit |
b7c5e3 |
- Two wildcards `**` matches anything (i.e. `foo` and `foo/bar`).
|
|
Packit |
b7c5e3 |
- Anything else matches exactly that text in the path (i.e. `foo`
|
|
Packit |
b7c5e3 |
would only match a component of the test path called `foo` (or a
|
|
Packit |
b7c5e3 |
substring of that form).
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
For example, `group/*1` matches `group/test1` but not
|
|
Packit |
b7c5e3 |
`group/subgroup/test1`, whereas both examples would be matched by
|
|
Packit |
b7c5e3 |
`group/**1`. A leading slash matches the beginning of the test path; for
|
|
Packit |
b7c5e3 |
example, `/test*` matches `test1` but not `group/test1`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Running tests in parallel
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
In order to run tests in parallel, you have to do the following:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* Compile (or, more precisely, *link*) your test program with the `-threaded`
|
|
Packit |
b7c5e3 |
flag;
|
|
Packit |
b7c5e3 |
* Launch the program with `+RTS -N -RTS`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Timeout
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
To apply timeout to individual tests, use the `--timeout` (or `-t`) command-line
|
|
Packit |
b7c5e3 |
option, or set the option in your test suite using the `mkTimeout` function.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Timeouts can be fractional, and can be optionally followed by a suffix `ms`
|
|
Packit |
b7c5e3 |
(milliseconds), `s` (seconds), `m` (minutes), or `h` (hours). When there's no
|
|
Packit |
b7c5e3 |
suffix, seconds are assumed.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Example:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
./test --timeout=0.5m
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
sets a 30 seconds timeout for each individual test.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Options controlling console output
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
The following options control behavior of the standard console interface:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
-q,--quiet
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Run the tests but don't output anything. The result is indicated only by the
|
|
Packit |
b7c5e3 |
exit code, which is 1 if at least one test has failed, and 0 if all tests
|
|
Packit |
b7c5e3 |
have passed. Execution stops when the first failure is detected, so not all
|
|
Packit |
b7c5e3 |
tests are necessarily run.
|
|
Packit |
b7c5e3 |
This may be useful for various batch systems, such as commit hooks.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
--hide-successes
|
|
Packit |
b7c5e3 |
Report only the tests that has failed. Especially useful when the
|
|
Packit |
b7c5e3 |
number of tests is large.
|
|
Packit |
b7c5e3 |
-l,--list-tests
|
|
Packit |
b7c5e3 |
Don't run the tests; only list their names, in the format accepted by
|
|
Packit |
b7c5e3 |
--pattern .
|
|
Packit |
b7c5e3 |
--color
|
|
Packit |
b7c5e3 |
Whether to produce colorful output. Accepted values: never ,
|
|
Packit |
b7c5e3 |
always , auto . auto means that colors will
|
|
Packit |
b7c5e3 |
only be enabled when output goes to a terminal and is the default value.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Custom options
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
It is possible to add custom options, too.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
To do that,
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
1. Define a datatype to represent the option, and make it an instance of
|
|
Packit |
b7c5e3 |
`IsOption`
|
|
Packit |
b7c5e3 |
2. Register the options with the `includingOptions` ingredient
|
|
Packit |
b7c5e3 |
3. To query the option value, use `askOption`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
See the [Custom options in Tasty][custom-options-article] article for some examples.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## Project organization and integration with Cabal
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
There may be several ways to organize your project. What follows is not
|
|
Packit |
b7c5e3 |
Tasty's requirements but my recommendations.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Tests for a library
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Place your test suite sources in a dedicated subdirectory (called `tests`
|
|
Packit |
b7c5e3 |
here) instead of putting them among the main library sources.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
The directory structure will be as follows:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
my-project/
|
|
Packit |
b7c5e3 |
my-project.cabal
|
|
Packit |
b7c5e3 |
src/
|
|
Packit |
b7c5e3 |
...
|
|
Packit |
b7c5e3 |
tests/
|
|
Packit |
b7c5e3 |
test.hs
|
|
Packit |
b7c5e3 |
Mod1.hs
|
|
Packit |
b7c5e3 |
Mod2.hs
|
|
Packit |
b7c5e3 |
...
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
`test.hs` is where your `main` function is defined. The tests may be
|
|
Packit |
b7c5e3 |
contained in `test.hs` or spread across multiple modules (`Mod1.hs`, `Mod2.hs`,
|
|
Packit |
b7c5e3 |
...) which are then imported by `test.hs`.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Add the following section to the cabal file (`my-project.cabal`):
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
test-suite test
|
|
Packit |
b7c5e3 |
default-language:
|
|
Packit |
b7c5e3 |
Haskell2010
|
|
Packit |
b7c5e3 |
type:
|
|
Packit |
b7c5e3 |
exitcode-stdio-1.0
|
|
Packit |
b7c5e3 |
hs-source-dirs:
|
|
Packit |
b7c5e3 |
tests
|
|
Packit |
b7c5e3 |
main-is:
|
|
Packit |
b7c5e3 |
test.hs
|
|
Packit |
b7c5e3 |
build-depends:
|
|
Packit |
b7c5e3 |
base >= 4 && < 5
|
|
Packit |
b7c5e3 |
, tasty >= 0.7 -- insert the current version here
|
|
Packit |
b7c5e3 |
, my-project -- depend on the library we're testing
|
|
Packit |
b7c5e3 |
, ...
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
### Tests for a program
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
All the above applies, except you can't depend on the library if there's no
|
|
Packit |
b7c5e3 |
library. You have two options:
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* Re-organize the project into a library and a program, so that both the
|
|
Packit |
b7c5e3 |
program and the test suite depend on this new library. The library can be
|
|
Packit |
b7c5e3 |
declared in the same cabal file.
|
|
Packit |
b7c5e3 |
* Add your program sources directory to the `Hs-source-dirs`. Note that this
|
|
Packit |
b7c5e3 |
will lead to double compilation (once for the program and once for the test
|
|
Packit |
b7c5e3 |
suite).
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## FAQ
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
1. How do I make some tests execute after others?
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Currently, your only option is to make all tests execute sequentially by
|
|
Packit |
b7c5e3 |
setting the number of tasty threads to 1 ([example](#num_threads_example)).
|
|
Packit |
b7c5e3 |
See [#48](https://github.com/feuerbach/tasty/issues/48) for the discussion.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
## Press
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Blog posts and other publications related to tasty. If you wrote or just found
|
|
Packit |
b7c5e3 |
something not mentioned here, send a pull request!
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
* [Holy Haskell Project Starter](http://yannesposito.com/Scratch/en/blog/Holy-Haskell-Starter/)
|
|
Packit |
b7c5e3 |
* [First time testing, also with FP Complete](http://levischuck.com/posts/2013-11-13-first-testing-and-fpcomplete.html)
|
|
Packit |
b7c5e3 |
(tasty has been added to stackage since then)
|
|
Packit |
b7c5e3 |
* [24 Days of Hackage: tasty](http://ocharles.org.uk/blog/posts/2013-12-03-24-days-of-hackage-tasty.html)
|
|
Packit |
b7c5e3 |
* [Resources in Tasty](http://ro-che.info/articles/2013-12-10-tasty-resources.html)
|
|
Packit |
b7c5e3 |
* [Custom options in Tasty][custom-options-article]
|
|
Packit |
b7c5e3 |
* [Resources in Tasty (update)](http://ro-che.info/articles/2013-12-29-tasty-resources-2.html)
|
|
Packit |
b7c5e3 |
* [Announcing tasty-rerun](http://ocharles.org.uk/blog/posts/2014-01-20-announcing-tasty-rerun.html)
|
|
Packit |
b7c5e3 |
* [Code testing in Haskell revisited (with Tasty)](http://lambda.jstolarek.com/2014/01/code-testing-in-haskell-revisited-with-tasty/)
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[custom-options-article]: http://ro-che.info/articles/2013-12-20-tasty-custom-options.html
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
Maintainers
|
|
Packit |
b7c5e3 |
-----------
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[Roman Cheplyaka](https://github.com/feuerbach) is the primary maintainer.
|
|
Packit |
b7c5e3 |
|
|
Packit |
b7c5e3 |
[Oliver Charles](https://github.com/ocharles) is the backup maintainer. Please
|
|
Packit |
b7c5e3 |
get in touch with him if the primary maintainer cannot be reached.
|