Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use unit tests? [closed]

I understand how to implement unit tests, I'm just struggling figure out when to use them.

Let's say I have a basic Reminders App. A user can add/edit/delete reminders and view them in a tableview. What parts of the app would I want to set up unit tests for?

like image 458
mnort9 Avatar asked Oct 03 '12 18:10

mnort9


3 Answers

Ideal world answer would say that every line of code you wrote should be unit tested.

But let's forget about that for a moment and move back to real world. Write tests for code that is important and having another line of defense is worth it. In other words, does it make much sense testing constructor that simply assigns value to one field? Most likely not. Is it worth to unit test parser extracting account data from complex XML your client provides? Probably yes.

Where does this difference comes from? Two major reasons:

  • it's less likely that constructor code will suffer from unpredictable changes (vs. much-evolving parser code to meet up with changing requirements/optimizations/refactorings)
  • constructor code is fairly simple and you've wrote such code many times already, tests might not offer you huge advantage in spotting issues; quick glance at such code and you'll be most likely able to tell what's going on (vs. complex XML parser code)

Why making the distinction? Why testing this and not that? Wouldn't it be easier to simply test everything (as ideal world answer would suggest)?

No. Because of time and money constraints. Writing code takes both. And there's only certain amount of money somebody is willing to pay for your product just as there's only certain amount of time he's going for wait for it to be delivered. Some tests are simply not worth it (again, constructor code example). Remember that unit tests are not immune to diminishing returns (having 80% code base covered with tests might take extra 20% development time and later save 20% time spent on debugging/maintenance, while going for another 10% might be twice as time consuming yet yield much lesser gains).

Again, you probably want to ask "Where's the line?" When do you decide "Ok, unit tests for this piece of code are not really needed"? Unfortunately, this kind of judgement comes with experience. Write code, read code, see what others (possibly more experienced developers) do and learn.

If I were to give couple of generic advises (what to unit test), those would be:

  • start with business/domain logic code
  • make sure to test all kind of converters/parsers/calculators (those are fairly easy to test, tend to change often [either due to changing requirements or refactorings] and by their nature are error prone)
  • avoid testing simple one-liner methods, unless that one line is crucial in some way
  • write tests for bugs that you discover (and keep them!)
  • don't follow magic fairy-tales of "good code must have 99.99% test coverage" blindly
  • reading questions on topic at programmers.stackexchange.com can often give you different perspective to approach problems
like image 194
k.m Avatar answered Oct 07 '22 20:10

k.m


Test all the code you write. And if you want to be really cool, write the test first. If you have a method on a model or controller, you should also have a test for it.

Without knowing more about your code, its hard to advise. But it sounds like you would have a controller (like RemindersController) and a model (like Reminder). This would be a basic outline I would start with:

  • RemindersController

    • should add a new reminder
    • should update an existing reminder
    • should delete an existing reminder
  • Reminder

    • initWithMessage:atTime: should set a message
    • initWithMessage:atTime: should set a time
like image 30
Alex Wayne Avatar answered Oct 07 '22 19:10

Alex Wayne


Assuming that you're storing your reminders somewhere, perhaps in the plist. You could write a unit test to generate a Reminder object, store it, retrieve the data, and finally generate a usable Reminder class object.

That way you know several things:

A: Your Reminder generation is working

B: Your method of storing the data is working

C: Going from Data to your Reminder object is working

However, you should not expect to be able to Unit test the actual "functionality" of your app. Such as touch events or navigation controls. These should be left to Acceptance testing which is an entirely different discussion.

like image 37
SethHB Avatar answered Oct 07 '22 19:10

SethHB