From: Rhino on 18 Mar 2010 18:03 Eric Sosman <esosman(a)ieee-dot-org.invalid> wrote in news:hntvh4$hho$1(a)news.eternal-september.org: > On 3/18/2010 3:22 PM, Rhino wrote: >> I think I understand the basics of using JUnit - I'm still using >> JUnit3 for the moment - but I want to ask some things that I don't >> find clear in the documentation that I've found. >> >> Would it be reasonable to say all of the following? >> >> 1. For each class that I develop, I should have one JUnit class that >> extends TestCase and that this TestCase class should test each of the >> methods in the class I developed? > > Sort of, I'd say. Private and even package-private classes > might get a waiver, the idea being that their "contracts" are only > with the public classes that "employ" them. Non-public nested > classes, same thing: If they're really just "implementation details" > of their containing classes, they might not need separate testing. > (For some inner classes, it won't be possible to test in isolation.) > > "Each method" may be a overkill, too. Getters and setters come > to mind as "too simple to test" -- usually. I've never heard of > anyone writing a unit test for the hashCode()/equals() pair (their > agreement should be verified, but it's not clear that testing is > the best way to go about it). > I had a feeling that question was going to be a bit controversial ;-) I asked a similar question a few weeks back and some people said that you should test absolutely everything, even seemingly trivial code like getters/setters. I don't recall ever having a bug in anything quite that trivial so I'm still a little dubious about the merit of testing really simple code but I can well imagine that an employer would insist on testing absolutely EVERYTHING so maybe I should write my tests to that standard.... I'm still not sure HOW to test some kinds of code but I'll ask about those individually when that comes up. For now, I'm just trying to get the basics down. >> [...] Whenever >> the values of the two input parameters are valid, bar() should >> produce a valid result, which I can predict and put in a test that >> would look like this: >> >> int actualResult = myclass.bar(4); >> int expectedResult = 2; >> assertTrue("The actual result, " + actualResult + ", does not equal >> the expected result, " + expectedResult, >> actualResult==expectedResult); >> >> But bar() also anticipates bad values for input parameters and throws >> IllegalArgumentException for those. What would my test for that look >> like? Any case I've ever written like that returns a Black icon. How >> would I write a case involving an Exception so that it gives a Green >> icon as the result? > > try { > int actual = myclass.bar(invalid); > assertTrue("Got result " + actual + " from " + invalid > + " instead of an exception", false); > } > catch (IllegalArgumentException ex) { > // Thanks; I needed that! > } > Now THAT is helpful! In fact, it means that I can consolidate all of the testing for a given method into a single method in the TestCase class rather than having a substantial number of tiny test methods for a given method in the class I developed. And that's where I was hoping to end up when I asked the question in the first place. THANK YOU!! -- Rhino --- news://freenews.netfront.net/ - complaints: news(a)netfront.net ---
From: Rhino on 18 Mar 2010 18:05 Jim <jkorman(a)alltel.net> wrote in news:5j55q5hsbg9ekbhpgrchn4b42fonlkfe6m(a)4ax.com: > On Thu, 18 Mar 2010 15:38:05 -0400, Eric Sosman > <esosman(a)ieee-dot-org.invalid> wrote: > >>On 3/18/2010 3:22 PM, Rhino wrote: >>> I think I understand the basics of using JUnit - I'm still using >>> JUnit3 for the moment - but I want to ask some things that I don't >>> find clear in the documentation that I've found. >>> >>> Would it be reasonable to say all of the following? >>> >>> 1. For each class that I develop, I should have one JUnit class that >>> extends TestCase and that this TestCase class should test each of >>> the methods in the class I developed? >> >> Sort of, I'd say. Private and even package-private classes >>might get a waiver, the idea being that their "contracts" are only >>with the public classes that "employ" them. Non-public nested >>classes, same thing: If they're really just "implementation details" >>of their containing classes, they might not need separate testing. >>(For some inner classes, it won't be possible to test in isolation.) >> >> "Each method" may be a overkill, too. Getters and setters come >>to mind as "too simple to test" -- usually. I've never heard of >>anyone writing a unit test for the hashCode()/equals() pair (their >>agreement should be verified, but it's not clear that testing is >>the best way to go about it). > <snip> > > Have to disagree about equals() at least. Having a unit test for > equals ensures that when you make changes to your class you > don't break the method. As me how I know ;-) > > Jim I've been lucky enough not to get burned by one of those yet - at least as far as I know! - but you make a good point. Murphy's Laws, right? Anything that can go wrong, will go wrong. It probably makes sense to test even really trivial-looking code.... -- Rhino --- news://freenews.netfront.net/ - complaints: news(a)netfront.net ---
From: Rhino on 18 Mar 2010 18:06 Daniel Pitts <newsgroup.spamfilter(a)virtualinfinity.net> wrote in news:80xon.116238$0N3.45411(a)newsfe09.iad: > On 3/18/2010 12:38 PM, Eric Sosman wrote: >> On 3/18/2010 3:22 PM, Rhino wrote: >>> But bar() also anticipates bad values for input parameters and >>> throws IllegalArgumentException for those. What would my test for >>> that look like? Any case I've ever written like that returns a Black >>> icon. How would I write a case involving an Exception so that it >>> gives a Green icon as the result? >> >> try { >> int actual = myclass.bar(invalid); >> assertTrue("Got result " + actual + " from " + invalid >> + " instead of an exception", false); >> } >> catch (IllegalArgumentException ex) { >> // Thanks; I needed that! >> } >> > > I think there is a "fail(String )" method you can call instead of > assertTrue(String, false). At least, on the versions of JUnit I have > used. > > You're absolutely right about that. I tried it the way Eric suggested first, then tried it with the "fail(String)" that you mentioned here and both worked perfectly. Thank you! -- Rhino --- news://freenews.netfront.net/ - complaints: news(a)netfront.net ---
From: Eric Sosman on 18 Mar 2010 20:44 On 3/18/2010 5:13 PM, Jim wrote: > On Thu, 18 Mar 2010 15:38:05 -0400, Eric Sosman > <esosman(a)ieee-dot-org.invalid> wrote: >> [...] >> "Each method" may be a overkill, too. Getters and setters come >> to mind as "too simple to test" -- usually. I've never heard of >> anyone writing a unit test for the hashCode()/equals() pair (their >> agreement should be verified, but it's not clear that testing is >> the best way to go about it). > <snip> > > Have to disagree about equals() at least. Having a unit test for > equals ensures that when you make changes to your class you > don't break the method. As me how I know ;-) Sorry if I wasn't clear: By referring to the "pair," I meant trying to test that x.equals(y) -> x.hashCode() == y.hashCode(), or that x.hashCode() != y.hashCode() -> !x.equals(y). Testing equals() alone may make sense. Testing hashCode() alone almost certainly doesn't. The implications must hold, but I'm not convinced testing is the right way to verify that they do. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Arne Vajhøj on 18 Mar 2010 21:58
On 18-03-2010 15:22, Rhino wrote: > I think I understand the basics of using JUnit - I'm still using JUnit3 > for the moment - but I want to ask some things that I don't find clear in > the documentation that I've found. > > Would it be reasonable to say all of the following? > > 1. For each class that I develop, I should have one JUnit class that > extends TestCase and that this TestCase class should test each of the > methods in the class I developed? That is the standard. Unless you have a good reason to deviate, then follow that model. > 2. When I look at the JUnit window in Eclipse to see the results of that > TestCase class, all of them should have a Green icon beside them? In > other words, should each test be written to show a positive result? That > would seem to make life a lot easier in one way: whenever I ran a > TestCase that was written that way, any bug would be easy to spot because > it didn't have the Green icon beside it. Yes. I even believe that all green will be collapsed. > 3. Is a TestSuite just a group of TestCases that can all be invoked from > the same JUnit class? For instance, given a project Foo, would I > typically have a single TestSuite for Foo that, when invoked, runs the > TestCases for each of the classes that makes up Foo? Yes. > Basically, I'm having a bit of confusion over exactly how much you put in > each class that extends TestCase (sorry for the strange wording but I > want to distinguish between the class that is being tested and the class > that is doing the testing and don't know the most concise wording) and > what a TestSuite should comprise. > > Also, I'm very uncertain about the individual methods in each class that > extends TestCase and what sorts of results they should return. Should all > test methods result in a Green icon? > > I can see where that would be very convenient: you simply run the test > case and even if it has dozens of methods, you just scan down the list > and make sure all of them have Green icons. If they do, all your tests > just passed and you can move on to the next thing. > > On the other hand, I'm not completely sure how to accomplish that. I'm > picturing a method like bar() which takes two input parameters. Whenever > the values of the two input parameters are valid, bar() should produce a > valid result, which I can predict and put in a test that would look like > this: > > int actualResult = myclass.bar(4); > int expectedResult = 2; > assertTrue("The actual result, " + actualResult + ", does not equal the > expected result, " + expectedResult, actualResult==expectedResult); > > But bar() also anticipates bad values for input parameters and throws > IllegalArgumentException for those. What would my test for that look > like? Any case I've ever written like that returns a Black icon. How > would I write a case involving an Exception so that it gives a Green icon > as the result? try { dosomethingbad(); fail("dosomething bad did not fail"); } catch(FoobarException ex) { // expected } Arne |