jeudi 3 décembre 2015

TDD - unit tests which drive development but not tautological

I have started to do some TDD and am enjoying the process but have come up against a problem.

I'm tending to write tests which are kind of 'wishful thinking' tests. By this I mean writing tests which assert that the unit has called methods which don't currently exist and then done something with the results - this requires a fair bit of mocking/stubbing. This has led me to write some nice code (I think) which has nice clean interfaces between different blocks of logic.

However, I've just had a look through some tests for a module I wrote and a lot of them seem like they are pretty pointless. They are basically asserting that what is written in the code, is written in the code. They will break as soon as I do any refactoring.

A toy problem I have been experimenting with: say I need to write a javascript source function for use in the jQuery autocomplete plugin.

The function needs to:

  • check if data has already been pulled from the server (and if not do it)
  • use that data to create an array of possible suggestions
  • filter the array based on what the user has typed so far (for a bit of added complexity, in my experiments I have been assuming I want to actually create two arrays here - one which contains all the terms which start with the users input and one which contains all the terms which just contain the users input minus the ones in the first array)
  • combine the arrays and pass them back to callback function

I see myself as having two options. I have been down both routes to compare.

I could start by writing tests that only test the business logic of my function (perhaps only mocking out a call to an ajax function that gets stuff from the server). Testing only that the function returns what it should do. This way I ended up with tests that won't break if I decide to refactor. But I also ended up with kind of messy code that I will probably want to refactor.

Or I could go down the 'wishful thinking' route - write tests that assert calls to (currently) imaginary methods and spread out the logic into smaller chunks. This drives development as the tests require that I write code to call those methods and then that I write more tests for the methods themselves etc.. I ended up with nicer code this time but I also seemed to end up with a bunch of tautological tests.

Am I missing something? Is there a happy middle ground to be had? Could any experienced TDDers give examples of what tests they would start with?

Aucun commentaire:

Enregistrer un commentaire