The questionWhat place does unit testing have in the functional or hybrid world?

This is kind of a tough post for me to write – since the whole point is that I’m still a little fuzzy about how the idea of unit testing connects with the new (to me) world of functional and hybrid-functional programming languages.

I am not entirely sure how generalize-able the things are that I am discovering.  I come from a straightforward background of enterprise and web-scale software development.  I’ve done it mostly with Java and its ecosystem, with a quick walk through the C# and .NET world a few years back.

Throughout the course of my career – I’ve come to settle on a several things that I deeply believe in.  Two of which are pertinent here – that there are a collection of principles that are common to all software development regardless of the particular technology (currently, most precisely spelled out as the SOLID principles) and that unit testing, because of the impact it has on our thought process, results in better, more modular software.

I started slipping down the functional programming rabbit hole without realizing it several years ago.  I went on an interview – and the folks interviewing me were asking me about my exposure to Scala.  I hadn’t even heard there was a Scala 🙂  The job didn’t end out working out – but after googling Scala, I slowly fell in love with it.  I’m still not any kind of functional programming master – but the ability to think in terms of classes and objects, while beginning to leverage higher-order functions and all the goodness that functional programming brings to the table was and is incredibly inspiring.

Scala has been called a tasteful hybrid.  I like that.  Incidentally, As I’ve continued to stumble down the rabbit hole, I’ve started to become really excited by Haskell.

At any rate, I’ve also come to believe that there is a Great Convergence happening.  A convergence between Object Oriented thinking and Functional thinking.  We tend to think of these things as mutually exclusive – but I would suggest that not only are they NOT mutually exclusive – the thinking about both are zeroing in on the same thing.  They’re zeroing in on a set of underlying principles about how to write well-structured software that speaks to the human reading it as well as it does to the machine that is executing it.

The SOLID principles that I mention above are perhaps not a perfect representation of the actual underlying principles – but they are definitely the best and closest articulation currently available.

Just to address one problem that I believe obscures our vision here – when we think of FP being at odds with OO, I would suggest that we’re actually thinking of the Imperative style that a lot of OO practitioners leverage as a matter of habit.  But OO programming does not imply Imperative programming, which is the thing that is *actually* at odds with FP, and not necessarily converging on the same set of principles.

As an example – one thing that people think of as a commonly accepted OO practice, but that actually violates SOLID principles, is the idea of having a class that encapsulates BOTH data and behavior.  This is ALWAYS, necessarily a violation of SRP.  But when folks make the argument that OO is going a different direction than FP, they often cite examples of this.  Those that are seeking to understand and apply the underlying principles that lead to code that speaks to the reader and not only the machine, are not writing classes like this – they are writing OO code that is converging more and more into the space that FP is at or is heading to (I have to be careful here – I’m still a bit of a FP neophyte – so I want to be careful about speaking too strongly for any portion of the FP community).

So stepping back…

The questionWhat place does unit testing have in the functional or hybrid world?

So I’ve tried several approaches and thumbed through a number of GitHub repositories to try to gauge where things are at. And I have yet to come across anything particularly definitive.

Taking a couple more steps back – throughout my career in the mainstream OO world (again, primarily Java with a short stint in C#), I have observed that Unit Testing, for whatever reason, leads developers to write more modular code that more closely follows good underlying software principles (e.g. SOLID).  And because of this, the code is easier to understand and to think about.  I do not believe this needs scientific rigor or detailed data to prove – for me, it’s a matter of honestly assessing even a small degree of practical experience.

I can see no reason why the move from classes as the carrier of meaning to first-class functions as the carrier of meaning would change this effect at all.

So this being the case, as I dug into Scala, I began to try several approaches to bringing Unit Testing to bear…

As we’ve said a couple of times here – Unit Testing applies pressure toward more closely meeting those underlying software development principles.  One of the principles that gets a lot of play, since it has historically required sophisticated frameworks to meet in the Java world, is the Single Responsibility Principle with regards to dependencies.  That is, in order to isolate the choice and creation of dependencies, purpose-specific frameworks like Spring or Google Guice were needed.

So my first step was to pursue that isolation directly.  I tried Guice, then I tried the cake pattern, then I customized the cake pattern to be as minimal as possible, then I tried implicitly passing around dependencies as needed…getting more and more minimal as I discovered the implications of the FP constructs available in Scala.

And then at some point I even started asking myself why I even needed a class – if I’m really following SRP, a class seems to ALWAYS be too much….though, it provides a good organizing structure, much like a package.

My production code seemed to proceed in the same direction – getting smaller and smaller.  More meaning expressed in fewer keystrokes.

It didn’t click with me at first – but this has a massive impact on the meaning of unit testing.  Ten lines of for-loop code, with variables to track the iteration, logic to perform the iteration, boundary checks and of course actual business logic can be boiled down to a single line of code with functional constructs.  A single line of code that only consists of the new meaning that you’re looking to express.  This is a big deal.

My Java unit testing practice – was to always have a method doing one atomic thing – and to unit test every method.  In the Scala world – this tips the balance, even for a practiced unit tester, toward too much investment for the return on structural clarity.

The questionWhat place does unit testing have in the functional or hybrid world?

So my conclusion here is two-fold:

  1. We don’t really know yet – but we’re working on it.
  2. As with everything in FP, it’s a FAR more fluid, artful, subjective and personal thing than it was in the more structured world of the last generation of languages.

Also – I’d like to highlight, if the tone hasn’t come through in this post, that this is something of a cry for help.  If you have any additional insight on this – please email.  I’m very interested to see where this starts to land.  Or, if it already has landed and I’m just not aware of it – that would be great to know as well.

Thanks!
Kyle