user34537
user34537

Reputation:

What are the conditions under which I really have to unit test code?

I was reading the Joel Test 2010 and it reminded me of an issue I had with unit testing.

How do I really unit test something? I don't unit test functions? Only full classes? What if I have 15 classes that are <20lines? Should I write a 35line unit test for each class bringing 1520 lines to 15(20+35) lines (that's from 300 to 825, nearly 3x more code)?

If a class is used by only two other classes in the module, should I unit test it or would the test against the other two classes suffice? What if they are all < 30lines of code, should I bother?

If I write code to dump data and I never need to read it such as another app is used. The other app isn't command line or it is but no way to verify if the data is good. Do I still need to unit test it?

What if the app is a utility and the total is <500lines of code? Or is used that week and will be used in the future but always needs to be reconfigured because it is meant for a quick batch process and each project will require tweaks because the desire output is unchanged? (I'm trying to say there's no way around it, for valid reasons it will always be tweaked) do I unit test it and if so how? (maybe we don't care if we break a feature used in the past but not in the present or future).

etc.

I think this should be a wiki. Maybe people would like to say an exactly of what they should unit test (or should not)? Maybe links to books are good. I tried one but it never clarified what should be unit tested, just the problems of writing unit testing and solutions.


Also if classes are meant to only be in that project (by design, spec or whatever other reason) and the class isn't useful alone (let's say it generates the html using data that returns html ready comments) do I really need to test it? say by checking if all public functions allow null comment objects when my project doesn't ever use null comment. It's those kind of things that make me wonder if I am unit testing the wrong code. Also tons of classes are throwaway when the project. It's the borderline throwaway or not very useful alone code which bothers me.

Upvotes: 20

Views: 5081

Answers (12)

Arthur Ronald
Arthur Ronald

Reputation: 33783

Some Time ago, i had The same question you have posted in mind. I studied a lot of articles, Tutorials, books and so on... Although These resources give me a good starting point, i still was insecure about how To apply efficiently Unit Testing code. After coming across xUnit Test Patterns: Refactoring Test Code and put it in my shelf for about one year (You know, we have a lot of stuffs To study), it gives me what i need To apply efficiently Unit Testing code. With a lot of useful patterns (and advices), you will see how you can become an Unit Testing coder. Topics as

  • Test strategy patterns
  • Basic patterns
  • Fixture setup patterns
  • Result verification patterns
  • Test double patterns
  • Test organization patterns
  • Database patterns
  • Value patterns

And so on...

I will show you, for instance, derived value pattern

A derived input is often employed when we need to test a method that takes a complex object as an argument. For example, thorough input validation testing requires we exercise the method with each of the attributes of the object set to one or more possible invalid values. Because The first rejected value could cause Termination of The method, we must verify each bad attribute in a separate call. We can instantiate The invalid object easily by first creating a valid object and then replacing one of its attributes with a invalid value.

A Test organization pattern which is related To your question (Testcase class per feature)

As The number of Test methods grows, we need To decide on which Testcase class To put each Test method... Using a Testcase class per feature gives us a systematic way To break up a large Testcase class into several smaller ones without having To change out Test methods.

But before reading

xUnit Test Patterns
(source: xunitpatterns.com)

My advice: read carefully

Upvotes: 2

Mohammad
Mohammad

Reputation: 6148

Unit testing is mostly for testing your units from aspect of functionality. You can test and see if a specific input come, will we receive the expected value or will we throw the right exception?

Unit tests are very useful. I recommend you to write down these tests. However, not everything is required to be tested. For example, you don't need to test simple getters and setters.

If you want to write your unit tests in Java via Eclipse, please look at "How To Write Java Unit Tests". I hope it helps.

Upvotes: 0

Erick Robertson
Erick Robertson

Reputation: 33082

I think it's impossible to write a comprehensive guide of exactly what you should and shouldn't unit test. There are simply too many permutations and types of objects, classes, and functions, to be able to cover them all.

I suggest applying personal responsibility to the testing, and determining the answer yourself. It's your code, and you're responsible for it working. If it breaks, you have to pay the consequences of fixing the code, repairing the data, taking responsibility for the lost revenue, and apologizing to the people whose application broke while they were trying to use it. Bottom line - your code should never break. So what do you have to do to ensure this?

Sometimes unit testing can work well to help you test out all of the specific methods in a library. Sometimes unit testing is just busy-work, because you can tell the code is working based on your use of the code during higher-level testing. You're the developer, you're responsible for making sure the code never breaks - what do you think is the best way to achieve that?

If you think unit testing is a waste of time in a specific circumstance - it probably is. If you've tested the code in all of the application use-case scenarios and they all work, the code is probably good.

If anything is happening in the code that you don't understand - even if the end result is acceptable - then you need to do some more testing to make sure there's nothing you don't understand.

To me, this seems like common sense.

Upvotes: 0

sarnold
sarnold

Reputation: 104090

One possibility is to reduce the 'test code' to a language that describes your tests, and an interpreter to run the tests. Teams I have been a part of have used this to wonderful ends, allowing us to write significantly more tests than the "lines of code" would have indicated.

This allowed our tests to be written much more quickly and greatly increased the test legibility.

Upvotes: 1

Sagar Varpe
Sagar Varpe

Reputation: 3599

for java u can use junit

JUnit

JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.

* Getting Started
* Documentation
* JUnit related sites/projects
* Mailing Lists
* Get Involved

Getting Started To get started with unit testing and JUnit read the article: JUnit Cookbook. This article describes basic test writing using JUnit 4.

You find additional samples in the org.junit.samples package:

* SimpleTest.java - some simple test cases
* VectorTest.java - test cases for java.util.Vector

JUnit 4.x only comes with a textual TestRunner. For graphical feedback, most major IDE's support JUnit 4. If necessary, you can run JUnit 4 tests in a JUnit 3 environment by adding the following method to each test class:

public static Test suite() { return new JUnit4TestAdapter(ThisClass.class); }

Documentation

JUnit Cookbook
    A cookbook for implementing tests with JUnit.
Javadoc
    API documentation generated with javadoc.
Frequently asked questions
    Some frequently asked questions about using JUnit.
Release notes
    Latest JUnit release notes
License
    The terms of the common public license used for JUnit.

The following documents still describe JUnit 3.8.

The JUnit 3.8 version of this homepage
Test Infected - Programmers Love Writing Tests
    An article demonstrating the development process with JUnit.
JUnit - A cooks tour 

JUnit Related Projects/Sites

* junit.org - a site for software developers using JUnit. It provides instructions for how to integrate JUnit with development tools like JBuilder and VisualAge/Java. As well as articles about and extensions to JUnit.
* XProgramming.com - various implementations of the xUnit testing framework architecture. 

Mailing Lists There are three junit mailing lists:

* JUnit announce: [email protected] Archives/Subscribe/Unsubscribe
* JUnit users list: [email protected] Archives/Subscribe/Unsubscribe
* JUnit developer list: [email protected] Archives/Subscribe/Unsubscribe

Get Involved JUnit celebrates programmers testing their own software. As a result bugs, patches, and feature requests which include JUnit TestCases have a better chance of being addressed than those without. JUnit source code is now hosted on GitHub.

Upvotes: 1

Jon
Jon

Reputation: 1047

I am part of a team that have just started adding test code to our existing, and rather old, code base.
I use 'test' here because I feel that it can be very vague as to weather it is a unit test, or a system test, or an integration test, or whatever. The differences between the terms have large grey areas, and don't add a lot of value.

Because we live in the real world, we don't have time to add test code for all of the existing functionality. We still have Dave the test guy, who finds most bugs. Instead, as we develop we write tests. You know how you run your code before you tell your boss that it works? Well, use a unit framework (we use Junit) to do those runs. And just keep them all, rather than deleting them. Whatever you normally do to convince yourself that it works. Do that.

If it is easy to write the code, do it. If not, leave it to Dave until you think of a good way to do automate it, or until you get that spare time between projects where 'they' are trying to decide what to put into the next release.

Upvotes: 1

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76876

I am going to answer what I believe are the main points of your question. First, how much test-code should you write? Well, Test-Driven Development can be of some help here. I do not use it as strictly as it is proposed in theory, but I find that writing a test first often helps me to understand the problem I want to solve much better. Also, it will usually lead to good test-coverage.

Secondly, which classes should you test? Again, TDD (or more precisely some of the principles behind it) can be of help. If you develop your system top down and write your tests first, you will have tests for the outer class when writing the inner class. These tests should fail if the inner class has bugs.

TDD is also tightly coupled with the idea of Design for Testability.

My answer is not intended to solve all your problems, but to give you some ideas.

Upvotes: 0

Owen S.
Owen S.

Reputation: 7855

Here's what I'm hearing, whether you meant it this way or not: a whole litany of issues and excuses why unit testing might not be applicable to your code. In other words: "I don't see what I'll be getting out of unit tests, and they're a lot of bother to write; maybe they're not for me?"

You know what? You may be right. Unit tests are not a panacea. There are huge, wide swaths of testing that unit testing can't cover.

I think, though, that you're misestimating the cost of maintenance, and what things can break in your code. So here are my thoughts:

  • Should I test small classes? Yes, if there are things in that class that can possibly break.
  • Should I test functions? Yes, if there are things in this function that can possibly break. Why wouldn't you? Or is your concern over whether it's considered a unit or not? That's just quibbling over names, and shouldn't have any bearing on whether you should write unit tests for it! But it's common in my experience to see a method or function described as a unit under test.
  • Should I unit test a class if it's used by two other classes? Yes, if there's anything that can possibly break in that class. Should I test it separately? The advantage of doing so is to be able to isolate breakages straight down to the shared class, instead of hunting through the using classes to see if it was they that broke or one of their dependencies.
  • Should I test data output from my class if another program will read it? Hell yes, especially if that other program is a 3rd-party one! This is a great application of unit tests (or perhaps system tests, depending on the isolation involved in the test): to prove to yourself that the data you output is precisely what you think you should have output. I think you'll find that has the power to simplify support calls immeasurably. (Though please note it's not a substitute for good acceptance testing on that customer's end.)
  • Should I test throwaway code? Possibly. Will pursuing a TDD strategy get your throwaway code out the door faster? It might. Will having solid unit-tested chunks that you can adapt to new constraints reduce the need to throw code away? Perhaps.
  • Should I test code that's constantly changing? Yes. Just make sure all applicable tests are brought up to date and pass! Constantly changing code can be particularly susceptible to errors, after all, and enabling safe change is another of unit testing's great benefits. Plus, it probably puts a burden on your invariant code to be as robust as possible, to enable this velocity of change. And you know how you can convince yourself whether a piece of code is robust...
  • Should I test features that are no longer needed? No, you can remove the test, and probably the code as well (testing to ensure you didn't break anything in the process, of course!). Don't leave unit test rot around, especially if the test no longer works or runs, or people in your org will move away from unit tests and you'll lose the benefit. I've seen this happen. It's not pretty.
  • Should I test code that doesn't get used by my project, even if it was written in the context of my project? Depends on what the deliverable of your project is, and what the priorities of your project are. But are you sure nobody outside of your project will use it? If they won't, and you aren't, perhaps it's just dead code, in which case see above. From my point of view, I wouldn't feel I'd done a complete job with a class if my testing didn't cover all its important functionality, whether the project used all that functionality or not. I like classes that feel complete, but I keep an eye towards not overengineering a bunch of stuff I don't need. If I put something in a class, then, I intend for it to be used, and will therefore want to make sure it works. It's an issue of personal quality and satisfaction to me.

Upvotes: 27

Stephen C
Stephen C

Reputation: 719446

Relative LOC counts for code and tests are pointless. What matters more is test coverage. What matters most is finding the bugs.

When I'm writing unit tests, I tend to focus my efforts on testing complicated code that is more likely to contain bugs. Simple stuff (e.g. simple getter and setter methods) is unlikely to contain bugs, and can be tested indirectly by higher-level unit tests.

Upvotes: 2

djna
djna

Reputation: 55957

You seem to be concerned that there could be more test-code than the code-under-test.

I think the ratios could we be higher than you say. I would expect any serious test to exercise a wide range of inputs. So your 20 line class might well have 200 lines of test code.

I do not see that as a problem. The interesting thing for me is that writing tests doesn't seem to slow me down. Rather it makes me focus on the code as I write it.

So, yes test everything. Try not to think of testing as a chore.

Upvotes: 1

cherouvim
cherouvim

Reputation: 31928

How can you do all those calculations? Ideally you should never be in a situation where you could count the lines of your completed class and then start writting the unit test from scratch. Those 2 types of code (real code and test code) should be developed and evolved together, and the only LOC metric that should really worry you in the end is 0 LOCs for test code.

Upvotes: 4

Marcelo Cantos
Marcelo Cantos

Reputation: 186078

Don't get fixated on counting lines of code. Write as much test code as you need to convince yourself that every key piece of functionality is being thoroughly tested. As an extreme example, the SQLite project has a tests:source-code ratio of more than 600:1. I use the term "extreme" in a good sense here; the ludicrous amount of testing that goes on is possibly the predominant reason that SQLite has taken over the world.

Upvotes: 17

Related Questions