Java Forum / General / December 2005
JUnit et al approach - criticisms
VisionSet - 27 Nov 2005 17:10 GMT Does anyone have anything negative to say about using JUnit or a similar approach in the overall lifecycle of their project?
-- Mike W
Thomas Hawtin - 27 Nov 2005 17:42 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? That's a difficult one. Issues with JUnit implementation of the concept, certainly. I actually think unit testing has a very localised effect on the running of a project, and needn't impact on other aspects of the life-cycle. Kind of like having a common set of code formatting conventions.
The only negative thing I can come up with is that writing tests is really, really boring. Pissing about with debuggers, traces, printfs and bug reports is much more interesting (true).
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
VisionSet - 27 Nov 2005 17:45 GMT > I actually think unit testing has a very localised effect on > the running of a project, and needn't impact on other aspects of the > life-cycle. mmm, depends when you write the tests I suppose.
-- Mike W
Thomas Hawtin - 27 Nov 2005 18:07 GMT >>I actually think unit testing has a very localised effect on >>the running of a project, and needn't impact on other aspects of the >>life-cycle. > > mmm, depends when you write the tests I suppose. Together with the code is traditional.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
VisionSet - 27 Nov 2005 18:12 GMT > >>I actually think unit testing has a very localised effect on > >>the running of a project, and needn't impact on other aspects of the [quoted text clipped - 3 lines] > > Together with the code is traditional. Okay, it depends when you write the code! Or what weight of RUP you are following - something I'm a bit at odds with, the lighter weight approaches seem to emphasise unit testing more.
-- Mike W
slippymississippi@yahoo.com - 11 Dec 2005 17:22 GMT > The only negative thing I can come up with is that writing tests is > really, really boring. I think that's where test-driven-development really proves its mettle. You write your methods and tests as stubs. Then you flesh out a test to satisfy your requirement, flesh out a method that satisfies the test, and then run the Junit test. How it reacts will give you insight into what problems you might have with your design. Refactor, then test again, until your method is tight. Boom, thirty minutes have gone by, and you move on to the next method. In one day, you can have a complex class completely fleshed out and fully tested, with a suite of JUnit tests that will let you know if anything gets broken by future code changes. Because of this, you jump confidently into massive refactoring exercises without a blink, where before you would vascillate in the face of such an exercise for hours or even days.
Roedy Green - 27 Nov 2005 17:45 GMT >Does anyone have anything negative to say about using JUnit or a similar >approach in the overall lifecycle of their project? Frank Zappa named his daughter Moon Unit. This is a blatant rip off of the Zappa name.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Andrew McDonagh - 27 Nov 2005 22:40 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? > > -- > Mike W Curious, why would testing in any form or with any framework be a negative thing?
Keep in mind, JUnit (and its other language variants dUnit,cppUnit, sUnit, NUnit, etc) are just unit testing frameworks and as such can be used in may ways.
The reason I mention this, is because whilst there is value in unit testing our code, these particular frameworks have come about to support TestDrivenDevelopment (TDD).
TDD uses unit tests as a means of capturing the design that we create, much like UML diagrams capture design.
TDD is a design methodology not a testing one.
The TDD cycle being:
1 Make a Failing test 2 Make the test pass 3 Refactor to remove duplication
However, every time this cycle has been completed, the existing tests start to also be a regression test suite for the code at the unit level.
TDD's unit tests (or more right -Programmer tests) do not replace acceptance/integration tests - they support them.
As for JUnit - I have only good things to say about it - I've learnt more about real OO, design, development & testing in the 4 years I've been using it, than in the previous 6 years developing.
Andrew
Mike Schilling - 28 Nov 2005 00:43 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? The JUnit approach (that the first failure ends the test) seems unproductive to me. At times it's apt, but there are other times where I'd like to continue the test and generate a report of all the failures rather than only be told about the first one.
Andrew McDonagh - 28 Nov 2005 00:57 GMT >>Does anyone have anything negative to say about using JUnit or a similar >>approach in the overall lifecycle of their project? [quoted text clipped - 3 lines] > continue the test and generate a report of all the failures rather than only > be told about the first one. Why?
Normally any subsequent failures are just by productions of the initial failure. So, fixing the first failures usually fixes all of the others.
The later failures in these cases are just noise.
Andrew
Mike Schilling - 28 Nov 2005 01:04 GMT >>>Does anyone have anything negative to say about using JUnit or a similar >>>approach in the overall lifecycle of their project? [quoted text clipped - 8 lines] > Normally any subsequent failures are just by productions of the initial > failure. So, fixing the first failures usually fixes all of the others. Often, that's true. Sometimes not. JUnit has no provision for the latter case.
stevengarcia@yahoo.com - 10 Dec 2005 21:17 GMT It depends on how you write your tests and execute them, if you use the JUnit task in Ant you can run all of your tests and see which ones failed at the end.
Adam Maass - 28 Nov 2005 06:17 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? I *like* JUnit; I have a great deal of confidence that the code for which I have JUnit tests works as expected.
Drawbacks to JUnit:
1. It is hard to get an entire project to adopt JUnit if not everyone believes in automated unit tests.
2. It is sometimes (often, in our case) difficult to write a *unit* test for each class in isolation.
3. Doing the work to get adequate test coverage from a unit test suite is generally a thankless job -- unless management buys in to the notion that it is worthwhile and makes the time to get it done.
4. Maintaining the test suite along with the code it tests is sometimes painful. (I just changed some code and I have a failing test. Is the test failing because it's a real failure of the code or because the test case is now incorrect?)
5. You have to train the people who write the tests what constitutes a good test. (IE, random or pseudorandom inputs are a bad idea; fixed paths on a filesystem are a bad idea; etc.)
Thomas Hawtin - 28 Nov 2005 13:26 GMT > 1. It is hard to get an entire project to adopt JUnit if not everyone > believes in automated unit tests. And get them to believe that what they are doing isn't some kind of magical special case.
> 2. It is sometimes (often, in our case) difficult to write a *unit* test for > each class in isolation. It often requires that code is written in a "purer" style.
> 3. Doing the work to get adequate test coverage from a unit test suite is > generally a thankless job -- unless management buys in to the notion that it > is worthwhile and makes the time to get it done. If you've got management who consider unit testing gold plating... then you've probably got worse problems.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Mike Schilling - 29 Nov 2005 06:14 GMT > If you've got management who consider unit testing gold plating... then > you've probably got worse problems. Have you never had managers who said things like "We're in crunch mode, so we can't afford to do as much testing as we'd like to."? If so, you're a very lucky man.
Chris Uppal - 29 Nov 2005 09:57 GMT > Have you never had managers who said things like "We're in crunch mode, so > we can't afford to do as much testing as we'd like to."? I've had /customers/ who said that.
(To be fair, the customers had their own test plans, so we weren't installing underdone software, only /shipping/ it ;-)
-- chris
Mike Schilling - 29 Nov 2005 13:23 GMT >> Have you never had managers who said things like "We're in crunch mode, >> so [quoted text clipped - 5 lines] > installing > underdone software, only /shipping/ it ;-) It's still foolish. "We want to delay finding the bugs, so they'll be harder and more expensive to fix."
Chris Uppal - 29 Nov 2005 15:08 GMT > > > Have you never had managers who said things like "We're in crunch > > > mode, so [quoted text clipped - 8 lines] > It's still foolish. "We want to delay finding the bugs, so they'll be > harder and more expensive to fix." Not necessarily. Both customers (it's only happened to me twice) were large, experienced, and competent in the ways of IT. I think their reasoning was something like [in the following "we" means the customer, "they" means the mob I worked for]:
We have a hard deadline to go live with a system which, we hope, will include their software. If not then we go live anyway with reduced functionality. We have only a limited time available for testing and are worried that it might be insufficient. Therefore we must ensure that we are not wasting /any/ time on inefficient testing. We know (by definition) exactly what priority to give to which functions and aspects of the system, and therefore are able to prioritise testing appropriately. Whatever testing we leave to them risks them spending too little time on things that are important to us, or too much time on things that we don't care so much about.
Downside: a) They know the implementation of the system better that we do, and so they can do finer grained testing, and also can concentrate on things they consider (technically) high-risk.
But on the other hand: a) There are some critical things that /only/ we can test properly. b) They have proved pretty good at delivering working systems in the past. c) They can be testing in parallel with us, and so can look for the things in downside (a) above (but we may have to pay extra for that -- must talk to the lawyers). d) We can blame them just as easily for delivering a buggy product as we can for delivering late ;-) [*]
All in all I think it was certainly defensible, and probably sensible, decision making.
(BTW, why should an error found by their testing be any more or less expensive to fix than the same error found by our testing ?)
-- chris
([*] A more cynical version of the same idea, the customer's manager in charge of the project thinks: I have the choice of getting into acceptance testing on time, but with increased risk of the delivered product being unacceptable (which we would blame on the supplier), or of risking missing /my/ deadlines and being blamed myself for not managing the supplier properly. Hmm, /tough/ decision... In all truth, I doubt if the thinking really was quite as cynical in the cases I experienced, but one never knows.)
Mike Schilling - 29 Nov 2005 19:01 GMT > (BTW, why should an error found by their testing be any more or less > expensive > to fix than the same error found by our testing ?) Because the earlier you find a bug, the cheaper it is to fix it:
Fewer people will run into it. (Ideally, only one, if it's found before the code is released to a shared area.) Less of the system will be affected by the problem when there is less of the system. If fixing it requires redesign, less of the system will be affected by that.
Unless both of you are doing end-to-end testing of the complete system: then, there's no particular reason.
Andrew McDonagh - 29 Nov 2005 23:07 GMT >>(BTW, why should an error found by their testing be any more or less >>expensive [quoted text clipped - 11 lines] > Unless both of you are doing end-to-end testing of the complete system: > then, there's no particular reason. And then theres developer memory. When a bug is introduced as a directeffect of the work they are working upon (it identified before they are 'done' or asap after they are 'done', then they are more likely to 'know' (i.e. guess correctly) where the problem is. So they can reproduce and fix quicker & therefore cheaper.
Roedy Green - 29 Nov 2005 18:21 GMT On Tue, 29 Nov 2005 13:23:38 GMT, "Mike Schilling" <mscottschilling@hotmail.com> wrote, quoted or indirectly quoted someone who said :
>It's still foolish. "We want to delay finding the bugs, so they'll be >harder and more expensive to fix." There are cases where it is not foolish. E.g. You must have SOMETHING to show for Java One. That date is not negotiable. Even if it is buggy you can dance around the bugs in a demo.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Mike Schilling - 30 Nov 2005 01:41 GMT > On Tue, 29 Nov 2005 13:23:38 GMT, "Mike Schilling" > <mscottschilling@hotmail.com> wrote, quoted or indirectly quoted [quoted text clipped - 6 lines] > to show for Java One. That date is not negotiable. Even if it is > buggy you can dance around the bugs in a demo. If the project is of any complexity, skipping unit testing is more likely to result in nothing that's even demoable.
timjowers@gmail.com - 28 Nov 2005 14:15 GMT Even with Rational Robot and other test tools problem #4 hits you - especially when the test team is separate from the development team and swings their own hammer for the project mangement.
JUnit makes for great regression tests. Well, the test suite has to be made up properly. Testing tools like JMeter and others should be used. Automating tools like Automate, LoadRunner, etc. should be used. Banging out JUnits when an automated test can be recorded much more easily is assanine unless the JUnits strive towards full code and input coverage. What are the best JUnit-oriented tools? E.g. I used to use BlackIce and related SW which did memory profiling as well as generated drivers for C++ classes to do input handling testing so would like a tool that, given a Java class, would generate the JUnit and test with normal input tests (e.g. Integer.MIN, MAX, -1, 0, 1, etc.)
Integration of JUnit into a J2EE environment is tough.
Testing and writing JUnit tests are not one and the same. Test Driven Design ("TDD" was traditionally for Technical Design Document so the TDD acronym is overly overloaded.) is really a way of saying to gather requirements. The "tests" of Test Driven Design are really design validation tests and mostly not breakage tests, input range tests, bad input handling tests, performance, or integration tests.
Test Driven Design is another way of saying "Fail to plan, plan to fail" or any other old adage about how running in without a strategy is fatal. Likewise, saying "JUnit" is not a magic arrow to kill bugs.
Happy coding, TimJowers
stevengarcia@yahoo.com - 10 Dec 2005 21:26 GMT >1. It is hard to get an entire project to adopt JUnit if not everyone >believes in automated unit tests. Definitely true!
>2. It is sometimes (often, in our case) difficult to write a *unit* test for >each class in isolation. This might be true for 2% of all classes, but if you write your test first and then your production class so it passes the test, you will always avoid this problem. This is not always the easiest thing to do though.
>3. Doing the work to get adequate test coverage from a unit test suite is >generally a thankless job -- unless management buys in to the notion that it >is worthwhile and makes the time to get it done. If you are beginning work on a legacy system this can be EXTREMELY difficult and something I generally don't recommend. But all new code, going forward, should have tests along side of it.
>4. Maintaining the test suite along with the code it tests is sometimes >painful. (I just changed some code and I have a failing test. Is the test >failing because it's a real failure of the code or because the test case is >now incorrect?) Yea, I agree with that. When you have 100 test classes and 100 production classes you are maintaining a big codebase. One of the master skills of agile development is refactoring, not only production code but also test classes. I was not good at it a year ago, now I'm pretty good at this aspect of programming.
>5. You have to train the people who write the tests what constitutes a good >test. (IE, random or pseudorandom inputs are a bad idea; fixed paths on a >filesystem are a bad idea; etc.) Kind of like #1. BTW, random imputs in some cases are the proper way to write unit tests. It depends on what test you are writing.
Chris Uppal - 28 Nov 2005 09:03 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? I wouldn't want to put anyone off the idea of testing, but I do want to raise a couple of small warning about automated tests.
Don't get me wrong, I /like/ automated tests -- what I want to say is that they can have a downside too, and that you should be aware of it and compensate accordingly.
[BTW, nothing in the following is Java-specific, even though I mention some Java-based tools, they are only named as examples, and I may not even have used them myself.]
Testing means many different things to different people and in different contexts. There are several axes of variation, the two I'm interested in here are granularity, and attitude.
A wise man once told me that "testing is a deliberate attempt to break the system". I think that's a very good description of the attitude that should be present when testing -- or rather, should be applied during /some/ testing. And that's what I find is missing in almost any automated testing -- whether the wildly faddish TDD or classical overnight test suites -- the purpose of the test is to confirm that the system (or module) works. There is no active intent to make the system break, there is no intelligent exploration of corner-cases, there is no inspired guessing at possible-unanticipated combinations of inputs. Above all, there is no exploration of the problem space -- the suite tests the same combinations each time. (The big exception to this -- which I have very rarely seen used in practise -- is when automation is used for a brute-force, exhaustive, exploration of a significant sub-set of the problem space). I like to see some real testing (in the above sense) as part of the development effort. To me (and assuming that exhaustive testing is infeasible) that means interactive testing. Write a test harness or use something like BeanShell. Try things out, did they work ? Did they work /exactly/ how you expected ? Push things a bit. Did the disk-light flash when it shouldn't ? Did the screen flicker more than you expected during your GUIs repaint ? Try wildly implausible combinations. You are trying to break your own code -- which requires imagination and attention to detail. Some people like to step through code under the debugger looking for stuff that "works", but doesn't take quite the expected path through the cod; that's another example of the same kind of thinking.
Anyway, the warning I wanted to give about automated testing isn't just that it's not an adequate substitute for aggressive testing (in the above sense), but also that there's a risk that it will /displace/ aggressive testing. Once the automated tests are written (whether before, along-side, or after the code they apply to), it takes a great deal of self-discipline[*] not just to rely on those tests. Press the button, everything comes up green, "Good, it works!". That's not /testing/ -- it has a great deal of value, but it's confirming that the system works on some inputs, not trying to find the inputs that break it.
([*] /I/ don't have that much self-discipline, so -- although I've always put a great deal of effort into testing -- I've settled into a working pattern where I don't write automated tests until /after/ I'm satisfied that my stuff works. So my tests are actually regression tests from the very first, since a newly written test that fails is, according to my rules, a development failure (either the test itself is buggy -- happens frequently -- or I'm writing tests too soon). Actually, I quite often write brute-force/exhaustive tests at this point too, and failures there /are/ permitted.)
Now, obviously, it's not a black-and-white situation. Automated test suites can attempt to explore large chunks of the problem space -- if enough time is devoted to it by sufficiently skilled and determined programmers. (I take it as obvious that /comprehensive/ test suites are a mere wish-fulfilment fantasy -- the combinatorial explosion kills the idea stone dead.) But elaborate test suites have costs too. Which brings me to the second point -- granularity.
Code changes. Right from the start, it changes a lot. (I'm not talking about changes in response to changing requirements -- that's a different issue). IMO that change is a necessary part of getting a properly working and maintainable system. Tests, quite obviously, add "weight" to that, in the sense that any test for a piece of functionality that is changed will have to change too. If you refactor stuff (and you've got any tests written) then you'll have to refactor them too. Tests, of any sort, inhibit the natural process of change as a software design grows -- to take a silly example, there's not much point in testing the property-file handling you are writing this morning if this afternoon you are going to rip it out and replace it with Windows registry lookup... (Presumably a true TDDer would put that the other way around -- there's not much point in writing code to be tested by your property-file handling tests if you are just going to rip them out and replace them with Windows registry handling tests this afternoon ;-) You have to balance the cost of testing sub-components against the benefits, taking into account the near certainty of change. You can all-but eliminate the costs of testing stuff that will later be scrapped by concentrating on end-to-end testing, testing a single business function, rather than the components that interact to perform it, but then (A) you are only exploring an extremely impoverished slice of the problem space (not aggressive testing at all) and (B) you don't get the very real benefits of unit tests. So you'll probably decide that it's better to have at least /some/ unit testing, and try to optimise the amount so that it doesn't add too much weight to your development process. Clearly, the easier and simpler it is to invent, implement, and run each test, then more testing you can do before you pass the break-even point. And that's where my second warning comes in -- in my experience, writing scripted tests (JUnit, and similar) takes a lot of work, about an order of magnitude more work than doing the same tests in the kind of interactive environment I as talking about earlier. So, in my experience, I can do about an order of magnitude /more/ testing of code-still-under-development (without compromising my development fluidity) by avoiding the formal tools. The downside is that I do end up writing scripted tests /as well/ -- but only for the final code, and (as I've already said) I prefer to use two different styles of testing anyway.
-- chris
VisionSet - 28 Nov 2005 10:56 GMT > Code changes. Right from the start, it changes a lot. (I'm not talking about > changes in response to changing requirements -- that's a different issue). IMO [quoted text clipped - 4 lines] > refactor them too. Tests, of any sort, inhibit the natural process of change > as a software design grows Yes absolutely and that is my main bug bear. From what I've seen, and that is very little, those enthusiastic about JUnit writing tests early, have some really bad OO designs. And I can understand why, it's one thing mersillessly refactoring but when essentially that requires rewrites of the tests it is demorallising beyond belief. eXtreme programming extols the virtues of unit testing and stipulates writing the tests first. Oh it also does away with much of the design stage too and promotes evolving designs from the code - much in the way I work presently. Doesn't sound like the two go hand in hand to me.
-- Mike W
Timbo - 29 Nov 2005 14:18 GMT > A wise man once told me that "testing is a deliberate attempt to break the > system". Yes, this is a common view held in testing literature: a good test is a test that produces a failure.
> I think that's a very good description of the attitude that should be > present when testing -- or rather, should be applied during /some/ testing. [quoted text clipped - 15 lines] > repaint ? Try wildly implausible combinations. You are trying to break your > own code -- which requires imagination and attention to detail. While I agree 100% with your view on how inputs should be tested (many test scripts I see test only the normal case behaviours), I disagree that interactive testing is better at finding faults, and that unit testing and aggresive testing are mutually exclusive. If you are trying wildly implausible combinations of behaviour in an attempt to produce a failure in an interactive mode, then you should be testing that same behaviour in your automated tests. I don't really see why interactive testing would produce more interesting inputs if it's the same person writing the tests.
This is not to say that interactive scripts are worthless. They can be quite useful for debugging.
> Anyway, the warning I wanted to give about automated testing isn't just that > it's not an adequate substitute for aggressive testing (in the above sense), [quoted text clipped - 4 lines] > That's not /testing/ -- it has a great deal of value, but it's confirming that > the system works on some inputs That's exactly what testing is: confirming that a system works on SOME inputs. As Dijkstra famously said: "Testing confirms the presence of bugs, not their absence". While I agree that it takes a good deal of discipline to maintain test scripts, IMO, it is much more painful to sit down after every change and interactively test, which is also testing only some of the inputs. This will result in only testing the areas of the code that have changed, and not testing the result of that on the rest of the system/module.
> ([*] /I/ don't have that much self-discipline, so -- although I've always put a > great deal of effort into testing -- I've settled into a working pattern where > I don't write automated tests until /after/ I'm satisfied that my stuff works. I see no problem with that. Failure in testing processes generally comes at the regression level. It's straightforward to test that new functionality works as intended, but the effects of that change on the rest of the system has to be tested also. As long as those tests are automated, this makes the problem much more straightforward.
> in my experience, writing scripted tests (JUnit, and > similar) takes a lot of work, about an order of magnitude more work than doing > the same tests in the kind of interactive environment I as talking about > earlier. Is it really more difficult to add tests for new behaviour in a script than it is to interactively test that behaviour? A bonus is regression testing can be performed, and more importantly, the tests are better documented.
Tim
Chris Uppal - 01 Dec 2005 14:07 GMT > While I agree 100% with your view on how inputs should be tested > (many test scripts I see test only the normal case behaviours), I > disagree that interactive testing is better at finding faults, and > that unit testing and aggresive testing are mutually exclusive. If you have an adequate interactive testing environment, then interactive testing is an order of magnitude faster, and far less disruptive, than writing "formal" test code. (If your environment is not such that you have that order of difference, then I'd say that's a very serious flaw in your environment, not a strength of jUnit ;-) If creating scripted tests were as fast and fluid as interactive testing, then I would much more nearly agree with you.
Another point is that much testing does not need to be repeated. E.g. if I have written some simple buffer manipulation, and want to run a quick sanity check, then I'll try using inputs that are bunched around the buffer size. There's no point in "freezing" such tests as code, since it is only useful for the /specific/ code that I'm testing. If that code changes the the test would have to change (completely) too. Of course, if the buffer handling is in any way complex, then some proper regression tests should be created too (but that -- in my book -- is a different issue, and it should wait until the code has settled down).
One last point -- which to my mind is /extremely/ important, but which I failed to bring out in my earlier post -- is that each time you "play" with your code interactively, you will be running a /different/ test. Think of it as "beta" testing happening very early in the cycle. It's /precisely/ the lack of that variation which makes me uneasy about software (including my own) which is tested only via scripts.
-- chris
Timbo - 02 Dec 2005 10:54 GMT > If you have an adequate interactive testing environment, then interactive > testing is an order of magnitude faster, and far less disruptive, than writing > "formal" test code. (If your environment is not such that you have that order > of difference, then I'd say that's a very serious flaw in your environment, not > a strength of jUnit ;-) If creating scripted tests were as fast and fluid as > interactive testing, then I would much more nearly agree with you. Well, we'll have to agree to disagree here, because I think that if one's interactive testing is quicker than a test script, than you are not testing a componenent adequately enough. For your example of a buffer, one could write a automated script to test different sizes (0,1,many) and the boundary of that in a matter of minutes, which would be just as straightforward.
Either way, I'm guessing your interactive test code is something like 'main' program that drives the unit in question. If that's the case, I don't think it is much harder to write a test script that reads in files placed in a specific test directory, with each file specifying the input that you would otherwise be typing in, and the expected output. It may take a bit more time, but you then have a test suite that allows you to run your tests over and over after each change, and that is easily extensible (add new test input/output files), and easily changed.
> One last point -- which to my mind is /extremely/ important, but which I failed > to bring out in my earlier post -- is that each time you "play" with your code > interactively, you will be running a /different/ test. Think of it as "beta" > testing happening very early in the cycle. It's /precisely/ the lack of that > variation which makes me uneasy about software (including my own) which is > tested only via scripts. Yes, that is a very interesting point about running different tests each time. However, you may use different tests each time, but if the code-under-test has been changed, the tests you have run previously are no longer valid, because they have tested a different implementation.
Chris Uppal - 05 Dec 2005 10:50 GMT > Well, we'll have to agree to disagree here, because I think that > if one's interactive testing is quicker than a test script, than > you are not testing a componenent adequately enough. For your > example of a buffer, one could write a automated script to test > different sizes (0,1,many) and the boundary of that in a matter of > minutes, which would be just as straightforward. Minutes ! Good gracious, man, I don't have /minutes/ to waste!
;-)
Seriously, if writing a test distracted me for minutes, then that is indeed something that I would avoid. That would be killing the fluidity of development, not to mention causing an immense disturbance of my train of thought. As such it should be (IMO) postponed to a time when the software has settled down, and I am in a position to concentrate on writing test code that is not only sensible and reasonably thorough, but also clear and maintainable.
> Either way, I'm guessing your interactive test code is something > like 'main' program that drives the unit in question. No. By interactive I /mean/ interactive. The ideal environment for doing this sort of thing is Smalltalk (or, perhaps, Lisp), but tools like BeanShell, etc, can get you part of the way there. Actually, I don't know of any Java environment that /really/ supports interactive testing , but this is a pattern of working that I developed before Java even existed (and long before I started using Smalltalk). It's a matter of making best use of the available tools, and writing your own whenever necessary.
-- chris
Timbo - 07 Dec 2005 09:54 GMT >>Well, we'll have to agree to disagree here, because I think that >>if one's interactive testing is quicker than a test script, than [quoted text clipped - 6 lines] > > ;-) LOL!
> Seriously, if writing a test distracted me for minutes, then that is indeed > something that I would avoid. That would be killing the fluidity of > development, not to mention causing an immense disturbance of my train of > thought. As such it should be (IMO) postponed to a time when the software has > settled down, and I am in a position to concentrate on writing test code that > is not only sensible and reasonably thorough, but also clear and maintainable. Fair enough. I'm the opposite. I like to run the test scripts while I continue with other stuff (tidying up comments etc).
> No. By interactive I /mean/ interactive. Yeah, sorry, I meant an interactive 'main' program that drives the testing by prompting for input etc.
> The ideal environment for doing this > sort of thing is Smalltalk (or, perhaps, Lisp), but tools like BeanShell, etc, [quoted text clipped - 3 lines] > using Smalltalk). It's a matter of making best use of the available tools, and > writing your own whenever necessary. In my best Homer Simpson voice: MMmmmmm... Smalltalk.....
Have you tried that BlueJ (not BlueJay) interactive environment (I've never used it myself)? I seem to recall that was aimed at beginners for interacting with stand-alone units, although I don't really remember many details.
Chris Uppal - 10 Dec 2005 12:14 GMT > Have you tried that BlueJ (not BlueJay) interactive environment > (I've never used it myself)? I seem to recall that was aimed at > beginners for interacting with stand-alone units, although I don't > really remember many details. I have tried it and have even recommended it. It's important to realise that its primarily a /teaching/ tool -- and a tool for teaching OO at that. Some of the ideas behind it come about as close as one can conveniently get to "interacting with objects" rather than "writing code" being the central concept of a good (OO) development environment.
And of course, once one can talk directly to one's objects, testing (in the interactive sense I've been going on about) becomes easy. Indeed there's a sense in which that's all one ever does with them.
I have some ideas for a /fully/ interactive Java environment (needs bytecode rewriting plus a bit of JNI) but with the layers of fluff that Sun keep adding to the language, the gap between what's technically feasible (more-or-less anything) and what's actaully worthwhile doing /in Java/ gets bigger and bigger...
-- chris
Ian Pilcher - 28 Nov 2005 14:21 GMT > Does anyone have anything negative to say about using JUnit or a similar > approach in the overall lifecycle of their project? I only write code in my spare time, so take this accordingly. My main objection to the JUnit "philosophy" is that it does nothing to make testing non-observable behavior easier. Per the JUnit FAQs, they think that only observable behavior should be unit tested most of the time. I simply don't agree with this.
 Signature ======================================================================== Ian Pilcher i.pilcher@comcast.net ========================================================================
Andrew McDonagh - 28 Nov 2005 22:19 GMT >>Does anyone have anything negative to say about using JUnit or a similar >>approach in the overall lifecycle of their project? [quoted text clipped - 4 lines] > that only observable behavior should be unit tested most of the time. I > simply don't agree with this. What do you mean by 'non observable behavior'?
All code should had some effect upon the system else by definition that code is not doing anything and should be deleted.
Confused.
Andrew
Thomas Hawtin - 29 Nov 2005 00:01 GMT > What do you mean by 'non observable behavior'? > > All code should had some effect upon the system else by definition that > code is not doing anything and should be deleted. The behaviour may be difficult to observe. For instance, if there is a cache of some intermediate result, you'd have to do some performance testing to check.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Andrew McDonagh - 29 Nov 2005 01:00 GMT >> What do you mean by 'non observable behavior'? >> [quoted text clipped - 6 lines] > > Tom Hawtin sure it may be difficult, but its still observable therefore its has some effect upon the system which makes it testable.
Ian was saying that non-oberveable code isn't catered for - to which I and others say, is not needed as non-oberveable means no effect, no effect meaning whats the point in the code existing.
Chris Uppal - 29 Nov 2005 10:06 GMT > What do you mean by 'non observable behavior'? > > All code should had some effect upon the system else by definition that > code is not doing anything and should be deleted. There is much behaviour which is not observable. That is to say not legally observable according to the laws of the Java language. For instance: 1) any non-public member variable 2) any aspect of an object's state that is only reflected in its non-public behaviour 3) any part of the execution state of another thread 4) the locked/unlocked status of a monitor There are probably others. I would expect the first two of these to be the most problematic in practise.
Additionally, there may be external restrictions -- e.g. it may be possible for an application to log a message but not (without artificially boosting its privileges) be permitted to read the resulting log.
-- chris
Chris Uppal - 29 Nov 2005 11:35 GMT I wrote:
> 2) any aspect of an object's state that is only reflected in > its non-public behaviour I meant to revise that before posting, and then hit the send button prematurely. The sentence should read "any apect [...] that is only feasibly reflected in [...]". If the behaviour is genuinely /never/ public then it "doesn't matter", but there can certainly be cases where bugs could easily be detected by examining non-public behaviour but which would be difficult or inpractical to examine only using public behaviour.
-- chris
Mike Schilling - 29 Nov 2005 13:21 GMT >I wrote: > [quoted text clipped - 9 lines] > detected by examining non-public behaviour but which would be difficult or > inpractical to examine only using public behaviour. This is the best reason I know of for C++'s "friend" feature; it allows a test class to see the complete state of the class it's testing.
Andrew McDonagh - 05 Dec 2005 01:38 GMT >>What do you mean by 'non observable behavior'? >> [quoted text clipped - 3 lines] > There is much behaviour which is not observable. That is to say not legally > observable according to the laws of the Java language. For instance: UNit tests test the result of a call, of which there has to be some output, else the code isn't doing any thing useful.
Note: All of the following answers rely upon normal Java access privileges and do not assume the need to use any kind of reflection.
> 1) any non-public member variable If the ClassUnderTest (CUT) has a private member var that changes as a result of the test AND its change is the result that will tell the test if its passed, then we will need to somehow see that variable in one form or another. In other words, the CUT would normally have some other method that could be called to see if the private member has changed (note not talking solely about a simple getter here - but it may be the case).
The change may be that the private member has been nullified - in which case, by stimulating the CUT again we can check for change.
An example here would be having a Listener reference. Our test could give the CUT a MockListener which we verify is called when we stimulate as necessary, then call the public method to set the listener var to null then stimulate the CUT again and check the MockListener was NOT called a second time.
Either or any other way, if a CUT is changing the state of a member var and that change has no effect, then the member var is not needed - and so delete it.
> 2) any aspect of an object's state that is only reflected in > its non-public behaviour Can you give me an example of what you mean here, because I'd say that state was not needed if it can't be detected from outside.
> 3) any part of the execution state of another thread > 4) the locked/unlocked status of a monitor Testing the state of execution of another thread, multi-threadness and other threaded scenarios are not a unit tests, they are functional (ALA Acceptance) tests.
These types of test are not what Junit was developed for and so 'out of the box' it isn't supported very well. That being said that are add-ons to do just those types of tests.
The main reason they were considered to be part of the unit testing stage, is that they test functionality of the system, rather than the behavior of a Unit (Class). Acceptance/Functional tests are better developed in other testing tools that support a scripting interface that non-java developers can read, understand and use themselves to help create tests (See FitNesse.org, Selenium, Watir, etc)
We would not normally write tests to detect monitor status itself, but we could write tests to prove we don't get deadlocks.
Unit tests test individual classes/methods.
> There are probably others. I would expect the first two of these to be the > most problematic in practise. Weird, to me they are the easiest.
> Additionally, there may be external restrictions -- e.g. it may be possible for > an application to log a message but not (without artificially boosting its > privileges) be permitted to read the resulting log. A unit test is not a unit test if it relies upon external resources and/or restrictions that can not be substituted at runtime - they are acceptance tests.
In the example above, the unit test could very easily substitute the log object the class (not the application - cause then we are acceptance testing) is writing to, so it can verify the correct behavior.
This dependency injection (via constructor, setter, dynamically loaded from resource file, retrieved from a singleton, etc) necessary for testability results in a better more changeable & maintainable design.
> -- chris If this seems strange, feel free to knock up an SSCEE (or what ever its called this week) example to which you have something that is non-visible and so can't test and I'll show you how it could or if its not a unit test.
Andrew
Chris Uppal - 05 Dec 2005 10:38 GMT [choosing just this one paragraph as a representative of the whole post]
> A unit test is not a unit test if it relies upon external resources > and/or restrictions that can not be substituted at runtime - they are > acceptance tests. This is simply playing with words. I would not define "unit test" so narrowly, and I /certainly/ would not relate the concept of "acceptance test" to external resources in any way (they may use them, they may not). An acceptance test has alway (in my experience) been a test run by the /buyer/. Anyway, if we do use your restricted sense of "unit test" then I have never at any time indicated any restriction of the validity of /my/ comments to "unit tests". Indeed I have little or no interest in them, nor in the religion that appears to accompany the term when used so narrowly.
-- chris
Mike Schilling - 05 Dec 2005 20:36 GMT > [choosing just this one paragraph as a representative of the whole post] > [quoted text clipped - 9 lines] > test has > alway (in my experience) been a test run by the /buyer/. I think you're being too specific here. I use:
Unit test -- test that is part of a subsystem, verifying that a part of that subsystem behaves correctly. This may include both black- and white-box testing.
Acceptance test -- test that is part of a subsystem's client, testing the subsystem as called by that client. This is black-box testing only, since the client is allowed to know nothing of the subsystem's implementation.
To reemployment a subsystem safely, you need both unit tests and acceptance tests from all clients.
Chris Uppal - 10 Dec 2005 14:16 GMT > I think you're being too specific here. I use: > > Unit test -- test that is part of a subsystem, verifying that a part of > that subsystem behaves correctly. This may include both black- and > white-box testing. No significant disagreement there.
Only two points I'd add. One is that "unit testing" neither implies nor is implied by the use of an xUnit framework. (I doubt if you confuse the two, but I think some people do). The other is that given the fractal nature of software designs, almost any test is simultaneously a unit test at one level and an "integration test" at a lower level.
(I put "integration test" is scare quotes because that is not quite the usual meaning of the term, but I don't know of anything closer in common usage. Normally, in my experience, it is only used when a complete /system/ is being tested -- full end-to-end functionality.)
> Acceptance test -- test that is part of a subsystem's client, testing the > subsystem as called by that client. This is black-box testing only, since > the client is allowed to know nothing of the subsystem's implementation. Hmm. I would definitely call that odd use of the term. At least in an environment where one has genuine paying customers, the question that "acceptance testing" addresses is not "does the code work?", but "are we going to be paid?". And, for all the importance of the first question, the second has importance of a totally different order. I think few people would want to confuse the two ;-)
-- chris
Mike Schilling - 10 Dec 2005 16:32 GMT >> Acceptance test -- test that is part of a subsystem's client, testing the >> subsystem as called by that client. This is black-box testing only, [quoted text clipped - 10 lines] > want to > confuse the two ;-) Group A located in X that's using subsystem B written in Y back in 200Z are customers for the group from Y, as are A's end-users. I wish I had a full acceptance test suite for, say, Xerces, so I'd know whether it's safe to upgrade it. If there were more hours in a week, I would have one.
Chris Uppal - 13 Dec 2005 09:07 GMT > Group A located in X that's using subsystem B written in Y back in 200Z > are customers for the group from Y, as are A's end-users. I wish I had a > full acceptance test suite for, say, Xerces, so I'd know whether it's > safe to upgrade it. Sounds as if we can at least agree that "acceptance testing" is done by the consumer of the s/w rather than by the producer ?
-- chris
Mike Schilling - 13 Dec 2005 16:56 GMT >> Group A located in X that's using subsystem B written in Y back in 200Z >> are customers for the group from Y, as are A's end-users. I wish I had a [quoted text clipped - 4 lines] > the > consumer of the s/w rather than by the producer ? Sure; I never meant to suggest otherwise.
Andrew McDonagh - 13 Dec 2005 19:57 GMT >>Group A located in X that's using subsystem B written in Y back in 200Z >>are customers for the group from Y, as are A's end-users. I wish I had a [quoted text clipped - 5 lines] > > -- chris Who said differently?
Timbo - 12 Dec 2005 09:35 GMT > Only two points I'd add. One is that "unit testing" neither implies nor is > implied by the use of an xUnit framework. (I doubt if you confuse the two, but [quoted text clipped - 6 lines] > Normally, in my experience, it is only used when a complete /system/ is being > tested -- full end-to-end functionality.) I think you are right to use 'integration test' here. To me, testing two units together is integration testing, and testing full end-to-end functionality is just 'system testing'.
Andrew McDonagh - 12 Dec 2005 23:04 GMT >> Only two points I'd add. One is that "unit testing" neither implies >> nor is [quoted text clipped - 15 lines] > units together is integration testing, and testing full end-to-end > functionality is just 'system testing'. but what is a unit?
To TDDers, its a Class or group of classes depending upon how the code finally looks, nothing to do with how the code starts out.
This is because TDD is an evolutionary design technique.
We:
1) Write a failing test case. It doesn't compile because we haven't written the production code yet. Write just enough to Make it compile - stub the methods only. Watch the test fail - cause we haven't filled the method bodies out yet.
2) Now Write Just Enough of the method bodies to make the test pass.
3) Refactor the code to remove duplication - this is the big design improving part - easily done because we have a passing test to tell us if we made a mistake in our refactoring.
Repeat until finished.
Whilst it true that xUnit frameworks can be and are used by teams who don't do TDD, its authors wrote it to facilitate TDD. Currently the majority of JUnit users are TDDers .
Andrew
Timbo - 13 Dec 2005 14:34 GMT > but what is a unit? > > To TDDers, its a Class or group of classes depending upon how the code > finally looks, nothing to do with how the code starts out. Using OO terminology, I define a unit as a class. How to test that unit in isolation depends on its dependencies. If it depends on other classes from within the application, those should be stubbed during unit testing, otherwise it is integration testing. If you feel the CUT's dependents are simple enough, you may not feel the need to unit test it, and will probably just use the production classes instead of stubs, but that, in my mind, is not unit testing.
Tim
Mike Schilling - 13 Dec 2005 16:58 GMT >> but what is a unit? >> [quoted text clipped - 8 lines] > probably just use the production classes instead of stubs, but that, in my > mind, is not unit testing. To take this to an extreme, are you saying that if I create a class that represents XML QNames (i.e. that contains a namespace and a local name), and I want to test another class that uses them, I need to stib out my QName class to produce a true unit test? What if I have a class that contains only static constants?
Timbo - 14 Dec 2005 09:33 GMT >>>but what is a unit? >>> [quoted text clipped - 14 lines] > class to produce a true unit test? What if I have a class that contains > only static constants? If it's only static constants, then it's really a data structure, so no. But for your QName example, if it has getter/setter methods for example, then unit testing would require it to have it's own tests. I'm not saying that you should necessarily test it, but it's not pure unit testing otherwise.
Mike Schilling - 14 Dec 2005 15:00 GMT >>>>but what is a unit? >>>> [quoted text clipped - 19 lines] > that you should necessarily test it, but it's not pure unit testing > otherwise. Of course QName needs its own tests. My question is whether unit testing one of its clients requires stubbing it out.
Timbo - 14 Dec 2005 16:15 GMT >>>>>but what is a unit? >>>>> [quoted text clipped - 25 lines] > Of course QName needs its own tests. My question is whether unit testing > one of its clients requires stubbing it out. To be a unit test, it does. If you include it, you are not testing the unit in isolation. However, with such a simple class, personally I wouldn't bother stubbing it, because the stub is likely to be just as complex as the the QName class itself. I'm not saying there is anything wrong with this approach (I do it quite often), but I would call that integration testing.
Mike Schilling - 14 Dec 2005 17:13 GMT > To be a unit test, it does. If you include it, you are not testing the > unit in isolation. However, with such a simple class, personally I > wouldn't bother stubbing it, because the stub is likely to be just as > complex as the the QName class itself. Very true :-)
>I'm not saying there is anything wrong with this approach (I do it quite >often), but I would call that integration testing. Thanks for the response. I think it's an odd distinction, myself, to say "this is an integration test, because it depends on a 20-line class I wrote, while this is a pure unit test because it depends only on the JDK classes, the Apache Commons, and Xerces", but we can disagree about that.
Timbo - 16 Dec 2005 09:24 GMT >>I'm not saying there is anything wrong with this approach (I do it quite >>often), but I would call that integration testing. [quoted text clipped - 3 lines] > while this is a pure unit test because it depends only on the JDK classes, > the Apache Commons, and Xerces", but we can disagree about that. True, it is odd, but then where is the distinction? 50 lines? 100 lines? 1000? Maybe a metric related to the data structures used? This way it is clear cut and easy to identify, and it fits with the strict definition of 'unit testing'.
Regarding the 3rd party classes, one doesn't test them as part of their unit/integration/system testing, so they don't come into the picture (i.e. they are assumed correct by the fact that you are not trying to find faults in them).
Mike Schilling - 16 Dec 2005 16:50 GMT >>>I'm not saying there is anything wrong with this approach (I do it quite >>>often), but I would call that integration testing. [quoted text clipped - 7 lines] > clear cut and easy to identify, and it fits with the strict definition of > 'unit testing'. Making that definition useless, IMHO.
> Regarding the 3rd party classes, one doesn't test them as part of their > unit/integration/system testing, so they don't come into the picture (i.e. > they are assumed correct by the fact that you are not trying to find > faults in them). With Xerces, at least, that's a poor assumption.
Timbo - 19 Dec 2005 10:52 GMT >>>>I'm not saying there is anything wrong with this approach (I do it quite >>>>often), but I would call that integration testing. [quoted text clipped - 10 lines] > > Making that definition useless, IMHO. Fair enough, but nobody can ever give me a definition of unit testing other than this, so I'm sticking with it.
>>Regarding the 3rd party classes, one doesn't test them as part of their >>unit/integration/system testing, so they don't come into the picture (i.e. >>they are assumed correct by the fact that you are not trying to find >>faults in them). > > With Xerces, at least, that's a poor assumption. Do you test the Xerces libraries in your testing?
Mike Schilling - 19 Dec 2005 18:53 GMT >>>Regarding the 3rd party classes, one doesn't test them as part of their >>>unit/integration/system testing, so they don't come into the picture [quoted text clipped - 4 lines] >> > Do you test the Xerces libraries in your testing? Implicitly, yes, and I've certainly fixed bugs in them found by my "unit" tests.
Timbo - 20 Dec 2005 09:45 GMT >>>>Regarding the 3rd party classes, one doesn't test them as part of their >>>>unit/integration/system testing, so they don't come into the picture [quoted text clipped - 7 lines] > Implicitly, yes, and I've certainly fixed bugs in them found by my "unit" > tests. Implicitly? From that I gather you mean that when you execute your tests, some of the Xerces code is executed. That's not testing. By testing, I mean select test cases, execute them, and compare behaviour to the expected behaviour.
I think NOT assuming that the 3rd party libraries are correct during testing is crazy. During debugging, by all means, you have to keep an open mind, but not during testing. You'll end up with test case explosion.
Andrew McDonagh - 13 Dec 2005 19:55 GMT >> but what is a unit? >> [quoted text clipped - 10 lines] > > Tim It depends upon how that class came into being, what it does and your mood at the time.
In TDD we write a test, write the code, refactor.
now we normally start out by creating a class and its method we are exercising. But after several test,code, refactor cycles we see that our single class needs further simple refactorings because its really several classes in one (e.g. a dispatcher type class which creates instances of different command classes). but we started out with one class and so far have one test class for it.
At this point we have a choice:
1) Leave the single test class as is - its testing our original class and n other command classes.
2) Change the test class to test the original class, using fake/mock Command objects. Then move the testcase methods from the original testclass into new test classes, one for each Command class. Here we end up with lots of small test classes, each testing an individual class.
Both approaches are fine - both are unit tests - thats how they started out.
For me the point at which a Unit Test stops becoming a unit test, is when its difficult to setup a test. At this point the test code is telling us - 'I'm a functional test'.
YMMV
Andrew
Timbo - 14 Dec 2005 09:44 GMT > It depends upon how that class came into being, what it does and your > mood at the time. [quoted text clipped - 21 lines] > Both approaches are fine - both are unit tests - thats how they started > out. I agree that both approaches are fine, but I disagree that the first choice constitutes unit testing. Firstly, it's not testing in isolation; and secondly, either the command classes are not being specifically tested (and so cannot be said to be unit tested), or they are being tested with the top-level module unit tests, which means the tests are testing outside of the module's boundary, so it's not unit testing.
(The word 'test' came up far too many times in that last sentence!)
Tim
Andrew McDonagh - 14 Dec 2005 19:40 GMT >> It depends upon how that class came into being, what it does and your >> mood at the time. [quoted text clipped - 24 lines] > I agree that both approaches are fine, but I disagree that the first > choice constitutes unit testing. Its ok to disagree.
> Firstly, it's not testing in isolation; Its impractical to test any class in isolation, as we'd have to wrap all Java & 3rd party libraries in order to fake/mock them to do so (never mind about Object.class). If your class uses a String object - you don't stub that do you? There's no difference between those classes and your own.
> and secondly, either the command classes are not being specifically > tested (and so cannot be said to be unit tested), or they are being > tested with the top-level module unit tests, which means the tests are > testing outside of the module's boundary, so it's not unit testing. maybe have missed something I said.... those command classes were *extracted* from the single class. Every line of code within the original single class was covered by a unit test. Every scenario for that single class was captured as a unit test.
Its just that part of TDD is 'refactoring' where we look at the current design and improve things. In this case, we saw that the single class was not conforming to Single Responsibility Principle, so we extracted those hidden classes from within it. The result is several small classes, where every line of code for all of them is still covered by tests for the original class - in fact we don't touch those tests - they create a safety net for our refactorings.
So, the choice we made was to separate the logic into discrete classes, but we could have left them as one class - do you really think this means the previous unit test is now an integration test?
> (The word 'test' came up far too many times in that last sentence!) Always does ;)
> Tim Timbo - 16 Dec 2005 09:30 GMT >> Firstly, it's not testing in isolation; > [quoted text clipped - 3 lines] > don't stub that do you? There's no difference between those classes and > your own. There is a difference. Those classes are assumed to be correct for the purpose of testing (i.e. you aren't trying to find faults in them, so you aren't testing them). Third-party classes are not treated as units in your code, and therefore need not be stubbed. Similarly, if you are relying on a previously written and verified internal library, you don't include that in the testing of a system you are developing.
>> and secondly, either the command classes are not being specifically >> tested (and so cannot be said to be unit tested), or they are being [quoted text clipped - 5 lines] > original single class was covered by a unit test. Every scenario for > that single class was captured as a unit test. Sorry, I didn't miss it, I just wasn't thinking about that when I wrote that paragraph :-) So, as I mentioned above, the 'top-level' tests are testing outside of the unit boundary, so its not really a unit test.
> Its just that part of TDD is 'refactoring' where we look at the current > design and improve things. In this case, we saw that the single class [quoted text clipped - 3 lines] > them is still covered by tests for the original class - in fact we don't > touch those tests - they create a safety net for our refactorings. And doing so is a great way to perform refactoring! Whether or not you refactor your tests after that is a decision that must be made, and if I'm to be honest, I probably wouldn't bother.
> So, the choice we made was to separate the logic into discrete classes, > but we could have left them as one class - do you really think this > means the previous unit test is now an integration test? Strictly, yes. Otherwise it becomes very difficult to make a distinction between a unit test and an integration test.
Tim
iamfractal@hotmail.com - 15 Dec 2005 09:58 GMT A very minor and more-or-less OT-point.
"In TDD we write a test, write the code, refactor. "
I'm a morning person. So I'm most productive in the morning. By the time 4pm swings around, I reach a creative low-ebb, and I just want to do something mechanical and unchallenging.
So I tend to write all my code before mid-afternoon, and only then start writing the test classes for the morning's output.
So I'm not a TDDer by definition, but pragmatism doesn't stop me aiming for its ideals.
As you were ...
.ed
-- www.EdmundKirwan.com - Home of The Fractal Class Composition.
Andrew McDonagh - 15 Dec 2005 11:02 GMT > A very minor and more-or-less OT-point. > [quoted text clipped - 16 lines] > -- > www.EdmundKirwan.com - Home of The Fractal Class Composition.
:) thats most definitely NOT TDD, its more akin to normal unit testing. The times within the TDD cycle are around....
Writing the test - around 2- 3 minutes. Write the code to make the test pass - around 1 - 2 minutes. Refactoring - around 2 -3 minutes.
So in total the cycle take somewhere around 5 - 8 minutes.
These times are examples, but quite normal. If you find you are spending more than 10 minutes within each step of the cycle, then its an indication of trying to test or implement or refactor too big a chunk, or the code base hasn't been refactored enough.
HTH
Andrew
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 ...
|
|
|