Day 73 - Testing

November 14, 2018
Haskell Testing

Testing in Haskell

As in any language, testing is crucial for driving and creating good, maintainable code. And for me, this would be the only criticism of the book, the testing chapter, for being both too vague with the specific implementation with regards to test layout and for introducing it so far into the book.

Throughout the book, functions were tested by loading the file into the GHCi and interpreting the compiler error, which is essential to a strictly typed language. But it hasn’t allowed me to code in a TDD manner.

Saying that, I LOVE the book and it’s taught me a lot of core principles that were lacking in my knowledge base

HSpec

The testing library I have been using is Hspec, for no particular reason, it’s just the one the book recommended. However their is Tasty which I’ve come across which I might explore at a later date.

Hspec supports both property (property testing is idiomatic to Haskell and strictly-typed languages) and unit testing.

My issues

I ran into many issues when implementing hpec, below are the 3 root causes :

package.yaml Vs .cabal

As far as I am aware, the package.yaml and .cabal files are both build files and serve the same purpose, but editing both of them can interfere. The actual definition can be found here which states package.yaml file is a bit more abstracted version of the .cabal file and therefore the .yaml file should be used.

Issue 1

I was adding dependencies to the .cabal file and it was throwing a warning error message.

Project Layout

In Haskell the layout of a project should be done in a way where you have all your functions in the library and only a very small main executable in the app directory, which executes functions by importing the library.

Issue 2

I had the main bulk of my code in the main directory and, you cannot import the main directory into your testing spec. And my spec file was called LibSpec.hs.

Test Layout

When writing tests with hspec, on execution it automatically looks for a main function in a file called Spec.

However a better way to implement Hspec and enable a clear test structure which reflects the src directory is to use Automatic spec discovery This is where a file called Spec.hs is inserted in to the test directory with the test executable in the package.yaml directed towards this file, and a Language Pragma written inside:

{-# OPTIONS_GHC -F -pgmF hspec-discover #-}

This Language Pragma basically searches all of the files inside the test directory ending in spec for functions with the function name and type signature spec:

spec :: spec
spec = undefined

This way, whenever you execute the tests stack test, all of the tests are executed at once. A good practice for test layout is to create a test for each source code you have.

E.g. LibSpec.hs , TypeSpec.hs to correspond to the source code files Lib.hs and Type.hs

Issue 3

Not doing the above!

Day 107 - What do you call a typeclass from the 80's?

December 18, 2018
Haskell Functors

Day 102 - Katas but not yet Functors

December 14, 2018
Haskell Kata

Day 98 - ToDo List ft. Functor/Applicative

December 10, 2018
Haskell Testing
comments powered by Disqus