views:

253

answers:

7

Where do we start using Unit testing?
I have some doubts about where to start using Unit testing.
I am doing unit testing with Junit in RAD. And I am doing it after all code is ready to deploy or may be after deployment. I am confused why we are doing unit testing after code is almost ready to deploy.
My question is when we should start unit testing?

I have some more questions.....
What I am doing in my unit testing is I took one method from a class and create a test class for that method.
In that class I give some input values to the method and expect respected output values from the database.
Now here the single test class does taking input values->passing it to method->calling the method from original class->database connection->fetching value from DB->return it to test class.

If test successfully runs then Junit console shows Green Bar else Red bar.
Red bar with the cause of error.But it doesn't generate any unit test report.

Now here is my question...
Am I doing correct unit testing? Since a single unit test method comprises all code flow and gives result...

+3  A: 

You should really write your tests as early as possible, ideally before you write your implementation.

This is a book that I've found useful on the subject and may be worth a read... http://www.amazon.com/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530

To try and address your second point, what you are describing is an "integration test" i.e it is not just testing your unit of code, but also your databases connectivity, configuration, data and the like.

Unit tests should only test the specific "part" of code that you are concerned with. i.e. Calling your method should just test that method. It should not be concerned with Database conectivity and data access. You can achieve this using "Mock" objects to act as a temporary replacement for your dependencies.

See: http://msdn.microsoft.com/en-us/library/aa730844.aspx

Whilst this document is from Microsoft and you're using java, the same principles apply.

Hope this helps.

ChrisV
+1 for the Kent's book.
Adeel Ansari
+4  A: 

The best time to start unit testing, if you haven't already, is now. The most effective use of unit tests is Test-Driven Development (TDD), in which you write the tests for each method as you implement it (write a test that fails and then implement the method to make it pass). However, it's not too late to add tests later on. JUnit tests solidify certain assumptions about the code that could change later on. If the assumption changes, the test breaks and you might save yourself from some bugs that would have beeen really hard to detect.

I don't know of a report facility, but you can add a JUnit ANT task which will output the test results to your build console (or log, if ant output is captured).

Your database tests sound like small integration tests rather than unit tests. That's good, but if the tests are too slow you might want to consider using mock objects (via a framework like JMock or EasyMock) to replace real DB connections with fake ones. This isolates the logic of the method from the state and behavior of the database and lets you run tests without worrying about whether the DB is running and stocked with test data.

Useful links :

http://en.wikipedia.org/wiki/Test-driven_development

http://www.jmock.org/

http://easymock.org/

http://ideoplex.com/id/25/ant-and-junit

http://ant.apache.org/manual/OptionalTasks/junit.html

http://misko.hevery.com/code-reviewers-guide/ (Guide to writing unit-testable code)

[Edit - in response to comment]: About whether what you've done is correct unit testing, technically the answer is 'no'. As I said, it's more of an integration test, which is good, but it does too much and has too many dependencies to be considered a real unit test. Ideally, a unit test will test the logic in a method and not the dependencies. The guide to writing testable code mentioned above (as well as the associated blog of Misko Hevery) gives some good advice about how to write code with seams to insert mocks of dependencies. Michael Feathers goes into depth on the subject in his excellent book Working Effectively with Legacy Code.

The key factor is dependency injection: Testable methods don't look for their dependencies - they receive them in the constructor or as arguments. If this requires too much refactoring, there are some tricks you can try, such as moving the code that looks for dependencies into protected or package-visible methods you can override. So then you run the tests on a subclass which returns mock objects from those methods.

+2  A: 

You should develop your unit tests as early as possible. In fact the best solution would be to develop them even before you implement the classes to test. Then you run them every time significant functionality is added to your classes.

Unit tests, as their name implies, are used to test a "unit" of operation. You shouldn't have a single test performing too much. Also a unit test should be testing functionality from a single class.

What you describe here seems more like system testing. This is something good to have, but it is a complete different thing than unit testing.

kgiannakakis
A: 

Doing certified development requires you to follow a defined devellopment model. The mostly used model is the V model, that, simply said, defines requirements, specs, subspecs (e.g. specs for components, modules or units) etc. top down on the left branch of the V. You than finally reach the bottom of the V when the specs define an atomic unit that can not reasonably be broken into smaller parts.

On the right branch of the V model you perform validations that the develloped module complies with its specs and/or reqs. It is typical use to create a test in parallel or before implementing the UUT (unit under test). This way you asure that any module fits into its framework from begin on and even when doing some rework.

As others have said, keep the tests as simple as possible using mocks etc whenever possible. You should also automate your tests, at least those that relate to modules residing near the bottom of the V, as those tests usually are run much more often than those near the top.

Doing proper reports is much easier when your tests have a well defined output. We usually have a struct of an enum (passed, failed, error) a status number and a message text.

LuI
A: 

In my opinion, testing should be done from the moment you finish writing your first method.

Testing methods as you write them helps with a lot of things. For one, when something goes wrong and your only clue is that it's in a particular class, if that class has countless methods and properties, it's hard to figure out what went wrong. Obviously not if you're having a syntax error, but semantic errors become very tricky when you're throwing a million methods into the fray.

Ensuring that each individual method works, which is the most granular level of assurance, speaks volumes of the stability of the complete class. If you have a concrete definition of what a particular method should do, Unit testing not only prevents edge-case semantic errors, but it also helps you plan out the flow of your program before hand, which can help you avoid massive refactoring, or worse, rewriting.

For effective testing, make sure you're breaking your class up into as many methods as possible. I know some might disagree with this, but significant portions of logic that perform actions in a context far removed from the rest of the function should be moved into their own function so it can be tested independently. I wouldn't perform SQL queries in your unit test. Instead, use mock objects to mimic the database. Testing the database isn't unit testing.

Not only will this help you with ensuring the integrity of your application, but it will also help you in the future when parts of the class need to be refactored. There's no sense in hunting down three lines of logic in a 100 line function. If those portions of logic are in their own method, you can rest assured that your method isn't failing due to that logic. If that monster of a function were failing, you would have fewer clues as to which part of the function is actually causing the error.

I know this all might sound redundant, but my point is testing early and testing often not only helps the stability of your program, but it helps you write clean code and avoid the headache of hunting down small errors.

Andrew Noyes
A: 

My question is when we should start unit testing?

Not "after all code is ready to deploy". Not "after deployment". That's too late. As many others have advised, the best time is (just) before code is written, TDD-style.

Now here is my question... Am I doing correct unit testing? Since a single unit test method comprises all code flow and gives result...

You're not doing "correct" unit testing. The unit you're testing is the class method, but it's also testing the database connection, which generally makes tests too slow to run as frequently as we'd like, and brittle. That's not to say that your tests are useless - they may well be useful - they're just not good unit tests.

Assume your database had the right data in it and your program had a solid connection to it. What value would your method be getting from the database in the course of your test? Just put that value directly in, to test the functionality of this method. So it runs even without the database. What's that? Your method doesn't work that way? Maybe it's doing too much. Maybe it's (a) getting data from the database and (b) making a calculation. Maybe you really want to test just (b) (I think you do). So split (a) and (b) apart, to give yourself a seam (per Michael Feathers' terminology) at which you can inject the test data from a test method. What do you have now? Better design. Each method doing just one thing. Looser coupling. And you got there because your tests led you there. That is test-driven development.

Carl Manaster
Thanks, I find it helpful...
A: 

Everytime you make a change or write new code you should include tests for each and every combination of inputs. Writing code never ends, someone, sometime will have to come back and make a fix or enhancement and your tests will help them know that changes they make havent broken anything.

mP