Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an interview coming up soon next week and there's a few things on their list of responsibilties for this software development job (the job position title is vague, it says java developer) that I am worried about:

  • Unit test features
  • Debug new features
  • Provide recommendation on test case design (what is this?)

I am worried because in my past software projects, I have not bothered writing unit tests. I know how to use JUnit to write tests in Eclipse and the process but it's just that I have not much experience writing tests. For example, I rely on data from the web, which varies a lot from each other, and process this data. How can I write test cases for every single type of data? Also, if the data is from a local database, how would I write a test case that checks that data from tables are being read properly?

I've used the debug feature in Eclipse whenever I could, but sometimes, when I am accessing a library which doesn't come ith source code for (e.g. commercial 3rd party Jars), the step into feature would stop. So for most cases, I just System.out.println to discover where the bug is happening. Is there a better method?

How can I practice in the short period of time to be somewhat competent in writing unit test?

share|improve this question
    
Welcome to Programmers, javastudent. There are a couple of questions on the site that already cover what you are asking: How to write “good” unit tests?, How do you write unit test cases?. – PersonalNexus Jan 6 '12 at 19:13
    
I've read the first question just now, but I still don't have a picture of what is a "good" unit test. – javastudent Jan 6 '12 at 19:14
1  
"I still don't have a picture of what is a "good" unit test". That comes with practice and reading existing code. Also. "I just System.out.println to discover where the bug is happening". Unit tests aren't really used for debugging. What are you really doing? Writing new code? Or fixing bugs in existing code? Please update the question to clarify. – S.Lott Jan 6 '12 at 19:21
2  
println? OMG use a debugger! – Mike Nakis Jan 6 '12 at 19:58
    
@MikeNakis, yes but if you've used jars with no source available, the debug step into will terminate. Using the jar decompiler plugin in eclipse still doesn't work perfectly. – javastudent Jan 7 '12 at 1:30
up vote 8 down vote accepted

The only way to practice is to just do it. I'm still learning how to write effective unit tests myself. Unfortunately, you need hours behind the wheel to get true feeling for what good unit tests looks like. The only shortcut I could think of is working 16 hours a day instead of 8 and you'll learn twice as fast, but only until fatigue sets in.

Few things I'd suggest:

  • Make sure you are working on a task that is not time critical. Time pressures and the feeling that you must be done right away, is what typically causes people to take short cuts and either a) not produce any tests, b) produce very little or c) produce tests which are very hard to maintain because you never took the time to refactor them.

  • Approach the task of writing unit tests with the same requirements for code quality (if not more strict) as you would production code. Some people think that unit tests are not being released, so it's not as important to follow good practices and then they end up with tests which are very fragile and extremely hard to maintain.

  • Allocate enough time to not only write the test but also any helper classes that would make yours (and others on your team) life easier. From my own experience, it seems that people tend to take shortcuts when writing tests because certain tasks are too long to code properly and because it takes even longer to factor code out into a library, they end up copy/pasting code between unit test projects. I started a unit test helper library for our group with the intention that it would speed up development of future tests (some common functionality in the library: simple code for recording/verifying mock object actions, code for working with files to help unit tests which need to feed external data, standard hooks to override win32 calls...).

  • Get into a habit of practicing TDD where you write tests before the code. At first it seems like unit tests are a lot of overhead, but since you must exercise the production code you've just written anyway, TDD more than makes up for it because it becomes incredibly easy to verify functionality of the production code so even when not considering all the long-term benefits, it will immediately start paying back the time it took you to write the tests.

This outlines how to learn to write good unit tests. If you want to simply "know" what a good unit test is, there's a number of really good books out there. (I'd start with The Art of Unit Testing)

share|improve this answer
    
TDD has an extra benefit. It is the specification in runnable code, so you can verify for yourself that it is exactly what is does. – user1249 Jan 6 '12 at 20:44
    
sure, TDD have many great benefits. I just wanted to highlight that one of immediate benefits is saving time during initial debugging which directly offsets the very first argument against TDD, it takes more time. – DXM Jan 6 '12 at 21:05
1  
@javastudent: actually that wasn't your question :) SE is a Q&A site and generally discussions like in comments are frowned upon. Sooner or later comment threads like these get a friendly slap. A lot of TDD value starts becoming very apparent when a) multiple people are working on a product and b) you've already built a product and now maintaining/extending it. If you work solo on a project small enough where you can keep everything in your head, you can certainly get away without doing TDD. On the other hand, when you have unit tests, you don't need to do nearly as much (if any) upfront... – DXM Jan 9 '12 at 1:17
1  
... design. Without TDD you would typically sit down, attempt to "design" entire component and then start writing it. Once written if you have to change it, especially design, changes become increasingly expensive since you will introduce bugs into what was already tested. But with TDD, you can afford to start delivering features even if later you will move lots of stuff around and introduce design patterns as needed because as soon as you break something, your tests will tell you. So even solo, TDD helps write code of least-complexity because you can introduce design only when it's needed. – DXM Jan 9 '12 at 1:22
1  
@javastudent: "just write a code you know ... works from previous projects"-that's a very dangerous line of thinking. No two applications have identical functionality and requirements. If they did, they should be one application. If code is identical, don't keep moving it, but create a library and keep it in one place. Also different clients of what appears identical might invoke the code slightly differently, so a)without unit tests you can never guarantee original code didn't have any bugs and b)you don't know if you will introduce bugs in different code if your usage is a little different – DXM Jan 9 '12 at 1:25

Create a simple class and write unit tests for it. Only through practice will you be able to understand how it is done. If necessary, find examples of unit tests in open source projects or refer to some online tutorials for guidance.

Good luck on your interview!

share|improve this answer

The software community is divided on the matter of unit tests.

I recommend that you don't write unit tests, they are mostly useless. They are written because "it's good practice", "mature teams/developers write unit tests" or some other industry dogma.

Integration or end to end tests are on other hand a sign of the team really caring about quality.

Anyway, let's get to some specific points of your question.

  1. Writing tests for code which accepts data from the web.

Start with happy path test case. This test is there to show that the code works in its basic scenario. This is super useful to validate that your code changes didn't break the app in a major way.

If the logic accepting data is complicated write happy path test for all major branches of this logic.

In my experience this test pays for itself very quickly, usually within hours after it's written. Believe me, this test just keeps on giving.

Then you can write a test which proves security works and that your API returns 401/403 when appropriate.

After that, write tests with data which misses required fields. In a lot of cases you can write the code for it once and execute it with different missing field.

  1. Test data

The purist way to write tests is to write them in a way that they create all data necessary for the test and then delete all that data after the test. In practice this is often not possible and one popular strategy is to flashback/restore the db regularly (e.g. once a day, or every time you run the tests).

Database tests will often assume some baseline data is present in the database - this is OK.

  1. Printing for 'debugging'.

It's 2016 and debugging is easier and easier but I believe that adding lines to logs is still the way to go when you cannot step through the code.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.