sonicboom
sonicboom

Reputation: 5028

Test driven development - when/what to test?

I am trying to get started with TDD but right away I am unsure of when and what I should be testing. The first two tasks in a new project I'm working on are as follows.

1) Receive some JSON formatted data on a REST endpoint and save it in the database. Say the data was several car records -

{ "cars": [{ "make": "ford", "color": "blue", "year": "2010", "for_sale": true }, { "make": "bmw", "color": "black", "year": "2011", "for_sale": false } ] }

So that data arrives at a REST endpoint and I need to save it in the database. Do I need a test for this task and if so what should it look like?

2) Retrieve some records from the database and display them in a view/webpage (i.e. using some templating system). Say the records are the car records above and they should be displayed as follows -

<ul id="cars">
    <li id="car-1">
        <div><span>Make:</span><span>Ford</span>
        </div>
        <div><span>Color:</span><span>blue</span>
        </div>
        <div><span>Year:</span><span>2010</span>
        </div>
        <div><span>For sale:</span><span>Yes</span>
        </div>
    </li>
    <li id="car-2">
        <div><span>Make:</span><span>BMW</span>
        </div>
        <div><span>Color:</span><span>black</span>
        </div>
        <div><span>Year:</span><span>2011</span>
        </div>
        <div><span>For sale:</span><span>No</span>
        </div>
    </li>
</ul>

So do I need a test for this task and if so what should it look like?

Upvotes: 1

Views: 233

Answers (1)

Andrew M
Andrew M

Reputation: 9459

What language, platforms etc are you using? Perhaps we can find some examples for you.

TDD is tricky at first, and a task like this (with Database and web parts) requires testing at several levels.

First divide the task up into single-responsibilities (which probably map to classes) that can be unit tested. For example, a class that takes JSON input, and hydrates an object with properties on it, TDD that class. Database layers are hard to unit test, we normal use the Repository pattern which we then mock when testing other classes.

DB unit testing is hard, so consider an "acceptance" or "integration" test around the database. That might be a test that connects to a real test database, puts in some test data, pulls it out again, and verifies that it looks right. In theory, you then don't even care what database it is, as long as the stuff you store comes out again, you know it's working.

HTML / web testing it also best done at a high level using tools such as selenium webdriver, which allows you to write test code that fires up a real browser, interacts with your page, and asserts that the content/behaviour is as expected.

This stuff is really good learnt by pair programming with someone who already knows it, or perhaps by attending a class or training course. There are also lots of books blogs and tutorials, which let you learn in a sandbox, which is simpler than trying to learn by yourself on a real project, where the pressure to get stuff done is in conflict with learning.


Edit: Java and Play framework. OK, I don't know the play framework specifically, but from a quick look it probably does the JSON parsing for you if you set it up right, which reduces the json parse function to boilerplate code. There's not a huge amount of value in TDD here, but you can if you want. Similarly, there's an active-record style db layer? So there's not a lot of value in testing code your library has provided (and dbs are hard/impossible/pointless* to unit test) .


Edit:Edit - this turns out to be icky, Apparently Play uses static controller methods which makes it hard to unit test (because you can't inject dependencies - which makes mocking difficult). I'm afraid without doing hours of research I can't help with the specifics, but integration tests are probably the way to go here, which test several of your units of code together, including the DB.

So in summary:

  • Don't sweat TDD on the boilerplate. Keep boilerplate isolated and thing (ie controllers ONLY do web stuff, then hand over to other classes. Repositories only save and retrieve objects, not rules/decisions/manipulations.
  • When you start adding more business logic to the guts of your app - keep it isolated in business classes (ie - away from the web or db boilerplate) that you can unit test easily. Definitely TDD this stuff.
  • Try integration tests across your app to test the DB. Have a real test DB behind your app, use the app to save something, retrieve it, and then assert it's correct.
  • use something like Selenium to test the web pages.

*delete according to your testing beliefs.

Upvotes: 3

Related Questions