Java Forum / General / March 2007
JUNIT questions
Taria - 28 Feb 2007 10:12 GMT Whee! Lol, sorry, I think I'm insane after reading a ton of documentation trying to figure JUNIT out. :p
Aside from having problems figuring out a simple Linked List program, my assignment is to write a JUNIT testing program to go with it. I sat at the keyboard, fumbling through many different sites trying to conjure something up and I'm having trouble trying to populate the initial linked list. bleah.
Ok, so I went back to an easier type of program to implement JUNIT since I'm already having trouble with initializing a linked list. I followed a tutorial, copied their very simple "add money" program and proceeded to write a JUNIT program to go with that (not part of my assignment directly but I was hoping this would help.)
Did it? Well, sorta. The red bar flashes at me and I am clueless how to go about debugging an error that JUNIT has found. All the tutorials I have gone through usually addresses the green bar but not what to do when the method is not functioning properly. My experience with past debuggers is that some step you thru the program's execution and you are able to set up breaks, examine values of variables, etc. So, how do you use JUNIT the same way? Am I looking at JUNIT the wrong way?
Any tips or advice on this subject is appreciated. Marion
P.S. I did not include any code since I'm really using a tutorial's code (which is flawless and works). My own JUNIT did not work, it flashed red at me and this is where I'm stuck. :(
Chris Dollin - 28 Feb 2007 10:15 GMT > P.S. I did not include any code since I'm really using a tutorial's > code (which is flawless and works). My own JUNIT did not work, it > flashed red at me and this is where I'm stuck. :( It's a bit difficult to tell what's wrong with code without seeing it, or the error messages.
Are you running your JUnit test case from inside an IDE? Because that can be tres helpful - like showing you the failing test line.
 Signature Chris "electric hedgehog" Dollin "Reaching out for mirrors hidden in the web." - Renaissance, /Running Hard/
Mark Jeffcoat - 28 Feb 2007 11:18 GMT > Did it? Well, sorta. The red bar flashes at me and I am clueless how > to go about debugging an error that JUNIT has found. All the [quoted text clipped - 4 lines] > So, how do you use JUNIT the same way? Am I looking at JUNIT the > wrong way? JUnit's not a debugger; it runs tests suites, and reports on whether they pass or fail.
If they fail, JUnit can report which test failed, along with the difference between the expected value and the actual value or the exception that was thrown. (I run JUnit from Ant, so I don't know how you'd get that information in your IDE.)
If you'd like to use a debugger to fix the failure, you're welcome to do it, but you need to go find a debugger. After you've made your changes, use JUnit to re-run your tests.
 Signature Mark Jeffcoat Austin, TX
andrewmcdonagh - 28 Feb 2007 13:51 GMT > > Did it? Well, sorta. The red bar flashes at me and I am clueless how > > to go about debugging an error that JUNIT has found. All the [quoted text clipped - 20 lines] > Mark Jeffcoat > Austin, TX The latest Eclipse and IntelliJ IDEs can also run your JUnit tests themselves. Because of this integration, you can simply double click on the Junit failure/exception message and they open the necessary file with the focus on the appropriate method.
Its very handy
For the benefit of the OP, on the debugging issue, I've long stopped using a debugger by creating one single junit test and writing just enough to make it pass, rinse & repeat. If the small amount of code I write to make the test pass, doesn't work, and I can't easily see whats wrong... I delete it and start again. Sounds crazy I know, but it tends to be faster than debugging.
'Fake it until you make it' is key to this. It allows use to write 'Just Enough to Make it Pass'.
E.g.
Start with a test..
void testAddingTwoPositives() { assertEquals("Wrong answer", 2, Calc.add(1, 1) ); }
'fake it until you make it'...
Class Calc { public static int add(int first, int second) { return 2; } }
All tests pass at this point and it took no time at all...
Now lets write a test to force us to create it...
void testAddingTwoNegatives() { assertEquals("Wrong answer", -2, Calc.add(-1, -1) ); }
Test fails...
so change the Calc implementation....
Class Calc { public static int add(int first, int second) { return first + second; } }
now all tests pass!
This is a small example, but it should show you how you can write unit tests, without having the implementation there to make them work. And it shows how you can make them work quickly, but not fully, so that later tests force your design to become better.
Andrew
Taria - 28 Feb 2007 18:01 GMT > > JUnit's not a debugger; it runs tests suites, and reports > > on whether they pass or fail. I thought it wasn't...thank you for confirming my suspicion.
> > If they fail, JUnit can report which test failed, along with > > the difference between the expected value and the actual value [quoted text clipped - 4 lines] > > welcome to do it, but you need to go find a debugger. After > > you've made your changes, use JUnit to re-run your tests. I'm happy to use a debugger because a debugger has always been my friend. But I asked my professor about this and he said I didn't need too. (Confusion sets in again.)
Andrew wrote:
> The latest Eclipse and IntelliJ IDEs can also run your JUnit tests > themselves. Because of this integration, you can simply double click > on the Junit failure/exception message and they open the necessary > file with the focus on the appropriate method. Yes, I use eclipse..it's intimidating but once I got something to work, it is handy I will admit that. :p
> For the benefit of the OP, on the debugging issue, I've long stopped > using a debugger by creating one single junit test and writing just > enough to make it pass, rinse & repeat.
> it tends to be faster than debugging. > > All tests pass at this point and it took no time at all...
> This is a small example, but it should show you how you can write unit > tests, without having the implementation there to make them work. And > it shows how you can make them work quickly, but not fully, so that > later tests force your design to become better. Ok, this part needs lots of digesting, I'm 20 minutes from a class and can't concentrate fully but I need to get this part down...thank you Andrew for that hint how to use JUNIT without using a debugger. This method is so diverse from my past experiences of fixing flawed code that I can tell you right now, I'm incredulous about the very idea. My professor said the very same thing in different words, I appreciate the example, he didn't supply that part, however.
Again, I thank everyone that has responded to my question, I must rush to class..I hate the "you're late" dirty professor looks.
Mark Jeffcoat - 28 Feb 2007 23:46 GMT > I'm happy to use a debugger because a debugger has always been my > friend. But I asked my professor about this and he said I didn't need > too. (Confusion sets in again.) He means something like, "Once you've gotten good enough at writing tests (before you write your code), you won't need to use the debugger to find your errors, because the failing test will tell you where to look."
This is a fine goal to shoot for, but there's not quite enough mystical power in JUnit that it will make all your programs bug-free just by including the library.
A good way to steer yourself towards that goal is to, whenever you find yourself falling back on the debugger, ask yourself what test you could have written in advance that would have detected the problem you just fixed. Next time you're in a similar situation, write that test.
Iterate until you achieve perfection. [No warranty is offered or implied: Your mileage may vary, as this algorithm may not terminate. Too bad, really.]
 Signature Mark Jeffcoat Austin, TX
Lew - 01 Mar 2007 05:53 GMT "Taria" <mchew02@hotmail.com> writes:
>> I'm happy to use a debugger because a debugger has always been my >> friend. But I asked my professor about this and he said I didn't need >> too. (Confusion sets in again.)
> He means something like, "Once you've gotten good enough > at writing tests (before you write your code), you won't [quoted text clipped - 4 lines] > enough mystical power in JUnit that it will make all your > programs bug-free just by including the library. Tests are not for the programmer alone. Tests are not for debugging alone. Tests are not things that happen alone.
Tests are not debugging.
Tests and debugging are complementary techniques.
Debugging is what the programmer does when the test fails.
The program can be bug free and fail tests. It can execute the wrong requirements flawlessly. Tests help figure this out.
- Lew
Chris Uppal - 01 Mar 2007 18:09 GMT > Debugging is what the programmer does when the test fails. And (more importantly, IMO) what the programmer does when s/he want to understand the dynamic behaviour of the program.
(Arguably that isn't "debugging", as such, but it uses the debugger.
BTW. I have come to the conclusion that many programmers fear the debugger and avoid using it as if it was some sort of symptom of failure[*]. I interpret the "you don't use a debugger if your unit tests are right" attitude as one example of this. Yet the debugger is the only tool we have for interacting with running programs; ignoring it is like going to the zoo but only looking at photos of animals.)
-- chris
[*] Me too, for a long time.
Arne Vajhøj - 03 Mar 2007 04:39 GMT > BTW. I have come to the conclusion that many programmers fear the debugger and > avoid using it as if it was some sort of symptom of failure[*]. I interpret > the "you don't use a debugger if your unit tests are right" attitude as one > example of this. Yet the debugger is the only tool we have for interacting > with running programs; ignoring it is like going to the zoo but only looking at > photos of animals.) For a lot of real world bugs debugging is not practical. The bug may not happen if debugged due to timing. Or it will just take a thousand years to step through.
Arne
Chris Uppal - 03 Mar 2007 18:31 GMT [me:]
> > BTW. I have come to the conclusion that many programmers fear the > > debugger and avoid using it as if it was some sort of symptom of [quoted text clipped - 6 lines] > may not happen if debugged due to timing. Or it will just take > a thousand years to step through. There are certainly such cases, yes, but I don't think they are so common as you seem to be suggesting. That a tool cannot be used in some small number of applications doesn't reduce its value much, and doesn't reduce its value in the /other/ applications at all.
-- chris
Arne Vajhøj - 04 Mar 2007 03:01 GMT > [me:] >>> BTW. I have come to the conclusion that many programmers fear the [quoted text clipped - 11 lines] > applications doesn't reduce its value much, and doesn't reduce its value in > the /other/ applications at all. In server based Java usage I would say it is a very common case.
Arne
Chris Uppal - 04 Mar 2007 19:52 GMT > In server based Java usage I would say it [having no debugger] is a > very common case. If so, and at least if it's a development server, then there is something /very seriously/ wrong with the debugging tools or development environment.
I was under the impression that tools like Eclipse and Netbeans were perfectly capable of debugging code running inside servers/app containers. Am I wrong ?
-- chris
Arne Vajhøj - 06 Mar 2007 00:47 GMT >> In server based Java usage I would say it [having no debugger] is a >> very common case. [quoted text clipped - 4 lines] > I was under the impression that tools like Eclipse and Netbeans were perfectly > capable of debugging code running inside servers/app containers. Am I wrong ? ????
In the post you replied to I wrote:
#For a lot of real world bugs debugging is not practical. The bug #may not happen if debugged due to timing. Or it will just take #a thousand years to step through.
So why do you think I am claiming debug tools are bad ?
Arne
Chris Uppal - 06 Mar 2007 17:14 GMT > In the post you replied to I wrote: > [quoted text clipped - 3 lines] > > So why do you think I am claiming debug tools are bad ? For exactly /one/ reason -- you used the phrase "a lot".
Now, it may be that all you meant was that this happens often (considered in the abstract) without making any claim that it happens often /in proportion/ to other bugs. I.e. over a developer's lifetime he may see 1,000,000 bugs, of which 10,000 are not approachable with a debugger (the numbers are, of course, completely imaginary). In that case no one would deny that 10,000 bugs is "a lot", but that number is small in relation to the overall number.
My impression is that you are making a stronger claim than that -- that a large minority (at least) of bugs are not approachable with a debugger. And that claim, whether or not you do in fact support it, is the one that I think is false for more application domains. (The big counter-example is embedded systems).
Maybe I have been misreading you, but you have seemed to me to be taking a position something like "debuggers are too often useless, so don't encourage people to use them". Whereas /my/ position was that people are avoiding using debuggers when they should not (our of fear, laziness, predjudice, unwillingness to learn something new, or because they work in an poorly-designed development environment).
That's all I meant.
-- chris
Arne Vajhøj - 14 Mar 2007 01:21 GMT >> In the post you replied to I wrote: >> [quoted text clipped - 5 lines] > > For exactly /one/ reason -- you used the phrase "a lot". ????
I give two very specific reasons for which I do not consider debuggers practical in many cases.
And you post:
#If so, and at least if it's a development server, then there is something /very #seriously/ wrong with the debugging tools or development environment.
#I was under the impression that tools like Eclipse and Netbeans were perfectly #capable of debugging code running inside servers/app containers. Am I wrong ?
And now you say that is because I indicated that it was a frequent problem.
Whether it is a frequent problem or not does not excuse you from completely ignore my specific reasons and invent one on my behalf and explain why that is wrong !
> Now, it may be that all you meant was that this happens often (considered in > the abstract) without making any claim that it happens often /in proportion/ to [quoted text clipped - 8 lines] > false for more application domains. (The big counter-example is embedded > systems). Sigh.
I even wrote where it is the case:
#In server based Java usage I would say it is a very common case.
Server based Java is probably like 80% of all Java. And in a huge part of real world server based Java problems using a debugger is hopeless.
That you also changed the above sentence from what I wrote to something completely different that matched what you try to put in my mouth:
#In server based Java usage I would say it [having no debugger] is a #very common case.
is not what I would consider proper quote technique.
> Maybe I have been misreading you, but you have seemed to me to be taking a > position something like "debuggers are too often useless, so don't encourage > people to use them". Whereas /my/ position was that people are avoiding using > debuggers when they should not (our of fear, laziness, predjudice, > unwillingness to learn something new, or because they work in an > poorly-designed development environment). A debugger is an excellent tool for those learning Java.
It is even an excellent tool for relative easy real world problems.
It is not an effective tool for the most difficult real world problems.
I will not say that people should not use debuggers. They should use them if possible. They should just be aware of their practical limitations.
Arne
Taria - 28 Feb 2007 21:44 GMT With what I know now in hand from previous posts, I go back to my JUNIT code, hit run and a red bar appears(denoting failed methods) and the list that goes with it.
My JUNIT program is built as a result from trying to teach myself how to write a simple JUNIT program from a tutorial. Their JUNIT program is almost identical to mines, when I replace my code with theirs, they get a green bar, my JUNIT code gets a red one. :x (I'm so special! lol) But what this tells me is that the JUNIT code is faulty not the class I'm testing. Ok, fine, let's go from there.
I tried to compare the tutorial code with mines and my code is almost identical. I have different values to the initialization routine which shouldn't matter. Other than that..I don't know why I'm getting a red bar.
Here is the class tested with JUNIT code: public class Money {
int dollars; int cents; String name;
public Money(int dollars, int cents, String name) { this.dollars = dollars; this.cents = cents; this.name = name; }
public int getDollars() { return this.dollars; }
public int getCents() { return this.cents; }
public String getName() { return this.name; }
public Money add(Money money2) { int sumDollars = this.dollars + money2.getDollars(); int sumCents = this.cents + money2.getCents(); return new Money(sumDollars, sumCents, this.name); }
public static void main(String[] args) { Money money1 = new Money(100, 46, "USD"); System.out.println("Dollars = " + money1.getDollars() + ", Cents = " + money1.getCents() + ", Name = " + money1.getName()); } }
And now my JUNIT code: import junit.framework.TestCase;
public class MoneyTest extends TestCase {
private Money testMoney;
protected void setUp() throws Exception { super.setUp(); Money testMoney = new Money (5, 7, "USD"); }
public void testGetDollars() { assertEquals("Testing GetDollars:",5,this.testMoney.getDollars()); }
public void testGetCents() { assertEquals("Testing GetCents:",7,this.testMoney.getCents()); }
public void testGetName() { assertEquals ("Testing GetName: ","USD",this.testMoney.getName()); }
public void testAdd() { Money testMoney2 = new Money (150,3,"USD"); //do the operation add Money sum = this.testMoney.add(testMoney2); assertEquals ("Testing Adding of Dollars: ",155,sum.getDollars()); assertEquals ("Testing Adding of Cents: ",10,sum.getCents()); }
}
I realize that writing JUNIT code for accessors is not really needed but I did them as an exercise to get more familiar with JUNIT. Also, I noted I named my JUNIT program the wrong way, it should be "TestMoney" not "MoneyTest." Forgive me! Lol, my very first virgin JUNIT program. *hides*
Anyhow, any thoughts appreciated!
Taria - 28 Feb 2007 21:51 GMT Never mind! I found my error!! yay! I see my error, I declared a new object instead of assigning a value to it. :)
andrewmcdonagh - 28 Feb 2007 23:24 GMT > With what I know now in hand from previous posts, I go back to my > JUNIT code, hit run and a red bar appears(denoting failed methods) and [quoted text clipped - 6 lines] > lol) But what this tells me is that the JUNIT code is faulty not > the class I'm testing. Ok, fine, let's go from there. ouch.... (best never to make such a public statement without first checking it out with peers... Junit is 6 years old and used by thousands of teams...there's little or no bugs left in it and certainly none that would cause your problem)
> I tried to compare the tutorial code with mines and my code is almost > identical. I have different values to the initialization routine [quoted text clipped - 3 lines] > Here is the class tested with JUNIT code: > public class Money {
> } > [quoted text clipped - 5 lines] > "TestMoney" not "MoneyTest." Forgive me! Lol, my very first virgin > JUNIT program. *hides* Don't know where yougo that from, its pretty conventional to name the test class like you originally did 'XyzTest'.
But then again, its convention and doesn't really matter, as Junit framework uses reflection to load test classes and methods, so the class names are irrelevant. Not method names though...for Junit 3.x your methods have to be called 'public void testXyz'. Junit 4.x does away with this and uses Annotations.
e.g.
@Test public void addTwoPositives() { }
> Anyhow, any thoughts appreciated! The String arguments for the assert methods are for failure messages, so 'Testing add of Dollars: ' does not make sense when theres an error.
I'd have written the test as...
public void testAddingUSDollars() { Money testMoney2 = new Money (150, 3, "USD");
Money sum = this.testMoney.add(testMoney2);
assertEquals ("Wrong amount of Dollars ", 155, sum.getDollars()); assertEquals ("Wrong amount of Cents",10,sum.getCents()); }
Also, no need for the comment in the middle...the test is named 'add'. Self commenting code is a far better style than hard to read code with comments - but it is hard for some to do, fo rsome reason.
Consider a (very) simplified example...
public int find(String[] args, String target) {
if (args.length > 0) {
for (int index = 0; index < args.length; index++) { if (args[index].equals(target) { return index; } }
}
throw new RuntimeException("Target: " + target+ " not found!"); }
versus...
public int find(String[] args, String target) {
checkArgsNotEmpty(args);
for (int index = 0; index < args.length; index++) { if (args[index].equals(target) { return index; }
throw new RuntimeException("Target: " + target+ " not found!"); }
private void checkArgsNotEmpty(String[] args) { if (args.length == 0) throw new RuntimeException("Target: " + target+ " not found!"); }
Aside from that, you are on your way... keep going with it... Junit skills is VERY marketable now as there very few who can do it well.
Once you get these basics down well, you will want to start looking at Mock Objects.... (tip, roll your own mocks, don't try and use a Mock framework)
Andrew
Taria - 04 Mar 2007 20:24 GMT > > With what I know now in hand from previous posts, I go back to my > > JUNIT code, hit run and a red bar appears(denoting failed methods) and [quoted text clipped - 11 lines] > thousands of teams...there's little or no bugs left in it and > certainly none that would cause your problem) Thanks Andrew for your tips. I'm self teaching myself and this is just the way I have devised, I gotta start somewhere. I appreciate your guidelines along the way.
And just for clarification, you were quick to assume I was putting JUNIT down as being 'wrong' but I'd like to point out I was refering to my JUNIT code and not the software JUNIT itself. It is my fault for this miscommunication, I should have been a little clearer to you, but when dealing with 'newbies' of the field, they are likely to be refering to themselves when calling something incorrect rather than the installation itself.
Excuse me for not being able to communicate eloquently, literally and exactly everything that I"ve written. I'll try to be more lucid when posting my assessment about something. (Now I know why the President has writers to write his speeches. lol)
Thanks all for your interesting perspectives. I've gotten great background on the uses of JUNIT. I'm relieved the debugger hasn't become obsolete (a silly fear I know).
Marion
impaler - 28 Feb 2007 11:19 GMT > Whee! Lol, sorry, I think I'm insane after reading a ton of > documentation trying to figure JUNIT out. :p [quoted text clipped - 26 lines] > code (which is flawless and works). My own JUNIT did not work, it > flashed red at me and this is where I'm stuck. :( If it's red, the test failed.
What do you want to test? What do you assert? Please give more details on what exactly you did and what do you want to test. With code examples of course. Regards
andrewmcdonagh - 28 Feb 2007 11:52 GMT > Whee! Lol, sorry, I think I'm insane after reading a ton of > documentation trying to figure JUNIT out. :p [quoted text clipped - 26 lines] > code (which is flawless and works). My own JUNIT did not work, it > flashed red at me and this is where I'm stuck. :( unit testing can be difficult when starting out...don't worry to much.
The basic premise you should keep in mind is the 3 As...
Arrange - your test data/objects
Act - perform the thing you want to test
Assert - check the expected results happened.
Andrew
Here's a set of Junit tests for the LinkedList class that is part of Java 1.5 (Using generics).
package example;
import java.util.LinkedList; import java.util.List;
import junit.framework.TestCase;
public class LinkedListTest extends TestCase {
public void testAddingOneElement() { List<String> aList = new LinkedList<String>();
aList.add("One");
assertEquals("Wrong number of list elements", 1, aList.size()); assertEquals("Wrong value!", "One", aList.get(0)); }
public void testAddingMutlipleElements() { List<String> aList = new LinkedList<String>();
aList.add("One"); aList.add("Two"); aList.add("Three");
assertEquals("Wrong number of list elements", 3, aList.size()); assertEquals("Wrong value!", "One", aList.get(0)); assertEquals("Wrong value!", "Two", aList.get(1)); assertEquals("Wrong value!", "Three", aList.get(2)); }
public void testRemovingOneElement() { List<String> aList = new LinkedList<String>();
aList.add("One");
assertEquals("Setup check failed, should have one entry", 1, aList.size());
aList.remove("One");
assertEquals("List not empty as expected!", 0, aList.size()); }
public void testRemovingMiddleElement() { List<String> aList = new LinkedList<String>();
aList.add("One"); aList.add("Two"); aList.add("Three");
assertEquals("Setup check failed, should have one entry", 3, aList.size());
aList.remove("Two");
assertEquals("Wrong size!", 2, aList.size());
assertEquals("Wrong value!", "One", aList.get(0)); assertEquals("Wrong value!", "Three", aList.get(1)); } }
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|