I’m excited to announce the first release of a test framework I’ve been musing about for over a year! Skeletest takes inspiration from pytest and jest, two test frameworks that IMO are some of the best test frameworks out there. Skeletest is batteries-included and opinionated, but it’s also extendable and hookable.
Skeletest features that no other Haskell test frameworks have:
- Built-in explainable predicates
- Show source code of failure (example)
- Assert on values without a Show instance (example, snapshot)
-
P.con
magic for checking predicates on fields in a data type, e.g.P.con User{name = P.eq "alice"}
(example) - Markers to tag tests for selection from CLI or modify in hooks
- For example, some Skeletest tests are marked as integration tests, which are skipped by default (e.g. not run in Hackage CI), and can be selected on CLI with
@integration
- For example, some Skeletest tests are marked as integration tests, which are skipped by default (e.g. not run in Hackage CI), and can be selected on CLI with
- Fixtures to share setup/provisioning logic (example test using this fixture)
- Nicely formatted snapshot files for easy auditability (example)
- Allow multiple snapshots in one test
- Select tests by filepath
- Test discovery comes out of the box
- Built-in xfail/skip modifiers
How does it compare to existing test frameworks?
hspec
- Can’t define custom flags
- Can’t hook into test execution
- No built-in support for golden tests.
hspec-golden
exists, but because hspec isn’t extendable, you can’t just add a--update
flag, you have to run a separatehgold
executable
tasty
- Barebones framework, requires adding multiple libraries for unit testing, property testing, etc.
sydtest
Actually pretty solid, has a lot of nice features
- Can’t define custom flags
- Can’t hook into test execution
- Built-in golden test
- Fairly detailed failure messages, can’t do more complex predicates like
explainable-predicates
, though - Not a fan of random test order by default
Writing the tests for Skeletest itself has been such a pleasant experience, I’m really excited to see if that holds true in the wild as well. The project is only a month old, so it’s still rough and fresh, but I’m optimistic about what’s possible!
Note: To preempt some comments I know some of you will want to bring up — yes, this framework is intended to be the default test framework for a new build tool I’m experimenting with. I know people are very passionate about build tools and package managers and Cabal and Stack, and I do very much want to have that discussion, but let’s do that in a separate thread, after I flesh out my ideas a bit more.