https://github.com/pheymann/specdris
A test framework for Idris
https://github.com/pheymann/specdris
idris idris-ecosystem test-framework testing unit-testing unittest
Last synced: 19 days ago
JSON representation
A test framework for Idris
- Host: GitHub
- URL: https://github.com/pheymann/specdris
- Owner: pheymann
- License: mit
- Created: 2017-07-05T10:47:43.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2019-03-21T08:23:25.000Z (about 6 years ago)
- Last Synced: 2025-02-13T18:52:37.218Z (2 months ago)
- Topics: idris, idris-ecosystem, test-framework, testing, unit-testing, unittest
- Language: Idris
- Size: 60.5 KB
- Stars: 54
- Watchers: 6
- Forks: 9
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://travis-ci.org/pheymann/specdris)
# specdris
With this framework you can write spec-like **Unit Tests** in Idris:```Idris
import Specdris.Specmain : IO ()
main = spec $ do
describe "This is my math test" $ do
it "adds two natural numbers" $ do
(1 + 1) `shouldBe` 2
it "multiplies two natural numbers" $ do
(2 * 2) `shouldBe` 3
it "do fancy stuff with complex numbers" $ do
pendingWith "do this later"
```
You can also nest `describe`. When executed this spec it will produce the following output:```
This is my math test
+ adds two natural numbers
+ multiplies two natural numbers
[x] not equal --red
actual: 4
expected: 3
+ do fancy stuff with complex numbers
[] pending: do this later -- yellow
Failed: Total = 3, Failed = 1, Pending = 1 -- red
```You can also test your `IO` code:
```Idris
import Specdris.SpecIOmain : IO ()
main = specIO $ do
describe "This is my side effect test" $ do
it "say my name" $ do
name <- loadName
pure $ name `shouldBe` "Foo"
```You can find more information about `SpecIO` [here](#specio).
Both `spec` and `specIO` have backend-agnostic versions, respectively `spec'`
and `specIO'`, that use `IO'` rather than `IO`.## Install
This testing framework is written with `Idris 1.0`.Clone the repo from github with `git clone https://github.com/pheymann/specdris.git` and run:
```
cd specdris
./project --install# under windows
.\Project.ps1 --install
```### elba
If you use [elba](https://github.com/elba/elba) to manage your Idris packages,
you can also add specdris as a dev-dependency to be run during tests. Just add
the following to the `[dev_dependencies]` section of your package's
`elba.toml` manifest:```toml
[dev_dependencies]
# snip
"pheymann/specdris" = { git = "https://github.com/pheymann/specdris" }
```Then you'll be able to use specdris from all test targets.
## Documentation
### Expectations
Currently this framework provides you with:|Expectation|Alias|Description|
|----------|-----|-----------|
|`a shouldBe b`|`===`|is `a` equal to `b`|
|`a shouldNotBe b`|`/==`|is `a` unequal to `b`|
|`a shouldBeTrue`| |is `a` `True`|
|`a shouldBeFalse` | | is `a` `False`|
|`a shouldSatisfy pred`| | satisfies `a` a given predicate|
|`a shouldBeJust exp` | | if `a` is `Just a'` apply `exp` to `a'`; here `exp` is again a sequence of expectations |### Failed Test Cases
If an expectations in a test case failes the following expectations aren't executed and the
whole case is marked as failure:```Idris
it "failing test" $ do
1 `shouldBe` 1 -- success
2 `shouldBe` 1 -- failes
2 `shouldBe` 2 -- will not be executed
```### SpecIO
Besides the usual test cases you can also add effects as:#### BeforeAll
Executes an `IO ()` before running any test case:```Idris
specIO {beforeAll = putStrLn "hello"} $ do ...
```#### AfterAll
Executes an `IO ()` after all test cases are executed:```Idris
specIO {afterAll = putStrLn "bye"} $ do ...
```#### Around
Takes a function `IO SpecResult -> IO SpecResult` which can be used to execute `IO` code
before and after every test case:```Idris
around : IO SpecResult -> IO SpecResult
around resultIO = do putStrLn "hello"
result <- resultIO
putStrLn "bye"
pure resultspecIO {around = around} $ do
```### Shuffle/Randomise Test Case Execution
You can randomise your test case execution by applying `shuffle` to your spec:```Idris
mySpec : SpecTree
mySpec =
describe "my test"
it "a" $ 1 === 1
it "b" $ 2 === 2-- default seed
spec $ shuffle mySpec-- static seed
spec $ shuffle mySpec 1000-- current time
do seed <- System.time
spec $ shuffle mySpec seed
````shuffle` only changes execution order for tests (`it`) under a `decribe` and thus preserves the logical test structure.
### Creating your own Expectations
If you need other expections than these provided [here](https://github.com/pheymann/specdris/blob/master/src/Specdris/Expectations.idr)
you can implement them as follows:```Idris
shouldParse: (Show a, Eq, a) => Parser -> (actual : String) -> (expected : a) -> SpecResult
shouldParse: parser actual expected
= case parser actual of
(Right result) => result === expected
(Left err) => UnaryFailure actual $ "couldn't parse: " ++ err
```### Working with SpecState
It is possible to get the [SpecState](https://github.com/pheymann/specdris/blob/master/src/Specdris/Data/SpecState.idr#L8-L16)
record of a spec after its execution by using `specWithState` from *Spec* or *SpecIO*.#### Storing Console Output in SpecState
If you want to process the output after spec execution you can store it in [SpecState](https://github.com/pheymann/specdris/blob/master/src/Specdris/Data/SpecState.idr#L8-L16)
by setting `spec {storeOutput = True}` or `specIO {storeOutput = True}`. This also stops *specdris* from printing
it to the console.