Hacker News new | past | comments | ask | show | jobs | submit login

You may have just looked at some poor projects. In fact, Haskell has a two really great testing frameworks:

HUnit, directly based on JUnit: http://hackage.haskell.org/package/HUnit

Quickcheck, which uses randomized testing: http://hackage.haskell.org/package/QuickCheck

HUnit will be very familiar to you, Quickcheck is definitely more interesting. You specify some invariants and the heuristic algorithm tries to come up with random inputs to break your function. It's potentially less accurate as good unit tests, but it's also a ton less work.

I can just say something like "This function takes an array of integers as input, and I expect an output array of the same size, where all numbers are even, and there are no duplicates" (in math-y form, of course), and quickcheck will try however man random inputs I specify to try to find a case that breaks that invariant.

Consider a well known Haskell library, attoparsec. It has extensive tests and benchmarks: https://github.com/bos/attoparsec

That being said, there are those in the Haskell community who take Haskell's referential transparency and equational reasoning to a whole new level and don't write tests, but instead write proofs.

For an example, see the popular Pipes library: https://github.com/Gabriel439/Haskell-Pipes-Library/blob/mas...




In addition to the libraries mentioned above, there's also some very good testing frameworks (which can run test suites composed of HUnit and Quickcheck tests), such as HSpec and tasty (and various extensions such as tasty-golden for golden tests and tasty-quickcheck for quickcheck tests). I've used these in various projects of mine; as with other languages, sometimes TDD is the right approach, sometimes you write a few tests afterwards to make sure everything works, and sometimes you can get away with no testing at all.

That said, I do feel that the type of testing I do in Haskell is often quite different from other languages. Due to the strict type system, some types of errors can be eliminated at compile time, and thus do not need to be tested for. Of course, as the parent pointed out, some people take this to a (very awesome) extreme, but even in a less rigorous form the static guarantees can eliminate many things that I would write unit tests for in other languages.

Finally, you may also be interested in SmallCheck, an alternative to QuickCheck. From its documentation:

> The big difference [between SmallCheck and QuickCheck] is that instead of using a sample of randomly generated values, SmallCheck tests properties for all the finitely many values up to some depth, progressively increasing the depth used. For data values, depth means depth of construction. For functional values, it is a measure combining the depth to which arguments may be evaluated and the depth of possible results.

This means that SmallCheck will often find small and interesting counterexamples to the properties you wish to affirm. (As an aside, note that writing property-based tests is a skill, just like writing good unit tests.)

tl;dr: Testing can sometimes be less necessary, but is certainly not unnecessary, and there are some very high quality and well-documented libraries for testing in Haskell.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: