3 ms·
I'm learning Haskell and I find this project very helpful and educating. There's one thing I'm wondering about, and that's the lack of (unit) tests. I'm coming
by misja 12y ago
I'm learning Haskell and I find this project very helpful and educating.
There's one thing I'm wondering about, and that's the lack of (unit) tests. I'm coming from the Java world and I'm used to write unit and integration tests for most of the code I write. But I have noticed that in Haskell projects this is not so common.
Why is that? Is it a cultural thing, or is Haskell's strict type system and immutability so helpful that unit tests are not so necessary comparing to for instance Java?
- gamegoblin 12y agoYou 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 http://hackage.haskell.org/package/HUnit Quickcheck, which uses randomized testing: http://hackage.haskell.org/package/QuickCheck 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 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/master/laws.md https://github.com/Gabriel439/Haskell-Pipes-Library/blob/mas...
- PieSquared 12y agoIn 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.
- dllthomas 12y agoI think it is true that unit tests are not so necessary compared to Java, but I think many in the Haskell community (myself included) have a tendency to rely too heavily on this. Tests aren't unnecessary in Haskell. gamegoblin is absolutely correct that there is some great tooling for tests in Haskell.
- Dewie 12y agoI think unit tests are overrated. No, not because testing is overrated, but because unit tests aren't the only way you can test software. QuickCheck for Haskell is a fuzzy testing library, for example.
- egonschiele 12y agoJust poor practices on my part :) Here's another project of mine that has tests and gets run on travis-ci: https://github.com/egonSchiele/salmon https://github.com/egonSchiele/salmon
- implicit 12y agoMy experience is that you can generally skate along on Haskell's type system and get further into a project without hitting the complexity threshold where you need tests to confidently make improvements. Bigger and longer-lived projects benefit enormously from an automated test suite no matter what they're written in.
- marcosdumay 12y agoYou'll always need tests. That said, when you refactor a program in Haskell, instead of running the tests and some functionality falling, usually the compiler itself will tell you there's a problem at line X of file Y. That use case of tests is just not there - and that's the main selling point of unit tests. Thus, I'd expect Haskell developers to not write as much of this kind of tests. But again, you'll always need some kind of it.