Unit testing best practices
howtodoinjava.com
Unit testing best practices
1–10 of 17 posts
Re: Unit testing best practices
#2Re: Unit testing best practices
#3Use Guard to run tests after each file change - Constantly running and re-running your tests in the background lets you know faster when you break something, but also forces you to keep your tests fast.
Use a visual test runner - Using guard is great, but I also like a nice HTML page I can reload that ends up being red/green based on your tests. Going from red to green can be deeply satisfying for reasons I don't fully understand. RSpec has a nice HTML output for ruby.
Use a visual code coverage tool - Having 80% or 90% code coverage is a useless statistic, but having a tool that shows you what part of the code is being tested and what isn't is extremely useful. If nothing else it tells you where you need to add tests or what part of your code is hard/impossible to test. I like SimpleCov for ruby.
Re: Unit testing best practices
#4Testing private methods? Wrong. Don't do this. They'll be covered by your public API, if they aren't, delete them. If you need to test code that is private, you've got a missing abstraction. Pull that code out into a separate class, make the method public.
Testing you get a null reference when you send in null to a method? So what? You're testing Java/C#/etc... if you do this. Test for behaviour.
Need to use tear down methods? You're not unit testing anymore.
At least the article never recommended testing accessors... Again, please don't.
Re: Unit testing best practices
#5This article is wrong in numerous cases. Testing private methods? Wrong. Don't do this. They'll be covered by your public API, if they aren't, delete them. If you need to test code that is private, you've got a missing abstraction. Pull that code out into a separate class, make the method public. Testing you get a null reference when you send in null to a method? So what? You're testing Java/C#/etc... if you do this.…
I just had a quick look through my unit tests for place where I test a private method.
I have a method which looks through an array for a pair of adjacent variables, with a particular property (they have p V2 Anyway, this gets used lots of times by my algorithm. However, I added some unit tests because I wanted to make sure that the obvious corner cases (beginning and end of array, not occurring) get checked correctly. Hopefully these cases are hit by my input data, but it is hard to construct input data that has particular properties.
I could pull this out into another class, but the method is actually fairly small and not used anywhere else, so that seems like a bit of a waste really.
On checking you get a null reference when you pass null into a method. I make this part of the API of some of my functions (in my case C++, so null pointer actually). I want to check that actually happens, as opposed to some nasty crash. Isn't that checking for behaviour? What else should I do instead?
Re: Unit testing best practices
#6This article is wrong in numerous cases. Testing private methods? Wrong. Don't do this. They'll be covered by your public API, if they aren't, delete them. If you need to test code that is private, you've got a missing abstraction. Pull that code out into a separate class, make the method public. Testing you get a null reference when you send in null to a method? So what? You're testing Java/C#/etc... if you do this.…
I don't get some of your complaints. I just had a quick look through my unit tests for place where I test a private method. I have a method which looks through an array for a pair of adjacent variables, with a particular property (they have p V2 Anyway, this gets used lots of times by my algorithm. However, I added some unit tests because I wanted to make sure that the obvious corner cases (beginning and end of array…
You've got a missing class. The fact you're so concerned with testing it highlights this.
The fact it's private I should be free to rename, add or remove parameters. If I did this to your private method, I'd break unit tests, despite the code being private.
For the null reference problem, it depends on your language. But the point remains the same. For public API's, e.g something you let the outside world consume, checking for null etc.. will be required. For internal code, don't bother. Go as high as you can in the stack and fix the root cause of the null reference in the first place.
Re: Unit testing best practices
#7Earlier quoted context omitted.
I don't get some of your complaints. I just had a quick look through my unit tests for place where I test a private method. I have a method which looks through an array for a pair of adjacent variables, with a particular property (they have p V2 Anyway, this gets used lots of times by my algorithm. However, I added some unit tests because I wanted to make sure that the obvious corner cases (beginning and end of array…
"Anyway, this gets used lots of times by my algorithm" You've got a missing class. The fact you're so concerned with testing it highlights this. The fact it's private I should be free to rename, add or remove parameters. If I did this to your private method, I'd break unit tests, despite the code being private. For the null reference problem, it depends on your language. But the point remains the same. For public API…
On your second point, I do disagree. I like to view all functions, even internals one, as having a documented API, covering things like bad inputs. This means that all functions (in debugging/assertion mode at least) promise to sanity-check their inputs for null pointers, etc.
In C++ at least I find this a necessity, as a single wrong pointer can cause horrible memory corruption all over my code. The whole point of these assertions is to allow me to find the place in the stack where the null pointers are coming from without pulling all my hair out in the process!
Re: Unit testing best practices
#8Earlier quoted context omitted.
"Anyway, this gets used lots of times by my algorithm" You've got a missing class. The fact you're so concerned with testing it highlights this. The fact it's private I should be free to rename, add or remove parameters. If I did this to your private method, I'd break unit tests, despite the code being private. For the null reference problem, it depends on your language. But the point remains the same. For public API…
I've got a missing class, for a 5 line function called from one place? I suppose I can see your point of view, but I'm not sure I agree. On your second point, I do disagree. I like to view all functions, even internals one, as having a documented API, covering things like bad inputs. This means that all functions (in debugging/assertion mode at least) promise to sanity-check their inputs for null pointers, etc. In C+…
Re: Unit testing best practices
#9Earlier quoted context omitted.
"Anyway, this gets used lots of times by my algorithm" You've got a missing class. The fact you're so concerned with testing it highlights this. The fact it's private I should be free to rename, add or remove parameters. If I did this to your private method, I'd break unit tests, despite the code being private. For the null reference problem, it depends on your language. But the point remains the same. For public API…
I've got a missing class, for a 5 line function called from one place? I suppose I can see your point of view, but I'm not sure I agree. On your second point, I do disagree. I like to view all functions, even internals one, as having a documented API, covering things like bad inputs. This means that all functions (in debugging/assertion mode at least) promise to sanity-check their inputs for null pointers, etc. In C+…
If your paranoid about null pointers in C/C++, use asserts or static analysis.
Re: Unit testing best practices
#10"Create unit tests that target exceptions" , @Test(expected=NullPointerException.class) Don't do this, any point of your test can throw this exception. A try/catch with an assert avoids false negatives and documents where you were expecting the exception to be thrown. edit: typo
Setup code should be pretty simple and stable, so should very rarely suddenly start throwing new exceptions.
If you need to pinpoint which bit of code under test threw the exception, you're probably testing too much in one test.
Of course, the advice changes when you're using a unit testing framework as a runner for integration tests.