Test Driven Development Examples? 74
esnyder queries: "I find the pragmatic/agile/XP hype about test driven development compelling, but find it hard to see how to test first (or even unit test at all) in some situations. I would like to explore some extended examples of it in a moderate to large scale real world codebase to improve my test design skills. Can anyone recommend some F/OSS software projects that consistently use test driven development processes that I could check out? Preferable over 50K lines of code, but I'd welcome pointers to anything that people think would be helpful."
eating your own dogfood (Score:3, Insightful)
Nothing reality tests the usability of a proposed API then writing unit tests against it.
For those who develop in Java, may I propose JUnit [junit.org]? If you want to test the GUI of a web server, then try HTTPUnit [sourceforge.net] although the value of writing unit tests to this is less since GUI is usually subject to a lot of changes over time.
Zope3 (Score:3, Informative)
http://cvs.zope.org/Zope3/ [zope.org]
Re:Zope3 (Score:4, Interesting)
Start Small And Move Up (Score:5, Interesting)
So, most of the library functions that I wrote (stuff like except an integer, return a text string from a list) have been unit tested by myself, and every time I change a function or a class, I try and write a unit test for it.
Seriously, you just need to dive right in and think about how you make your code easy to test. I use the SimpleTest testing framework (it's PHP), and I always feel good when my array of tests all run correctly when I make a major change to the code that impacts a huge portion of the site.
If test-driven development has done one thing, it's forced me to carefully examine my code to create a way to make sure it is actually working according to the business logic we've been asked to implement.
Darn good question. (Score:4, Insightful)
I find that odd really, considering that the point behind "write tests first" is to create an executable specification for functionality. If a new piece is desired, surely it would be easier for someone else to pick up the module with the tests and write code to pass the tests than it is to try to pick up the flow of a project from out of date documents, etc, and just contribute. I look forward to those who know of such projects, because I plan to examine them for help on how to implement these techniques myself. (My current project uses regression tests driven by an external test application... I have had this same question for some time, especially in regards to web applications).
Re:Darn good question. (Score:2)
Python (Score:5, Informative)
Tcl and Tk (Score:2)
Twisted (Score:1)
http://www.twistedmatrix.com [twistedmatrix.com]
Java example (Score:5, Informative)
If you're using Java for web development, I'd suggest reviewing the Struts Applications Project on SourceForge [sf.net].
It's a collection of documentation and applications using Struts that are really "done right" -- with documentation, sensible and scalable design, fully implemented testing (unit level AND on the HTTP level). I'm currently roaming through the AppFuse source in there -- it's basically designed to give you a complete setup to start building your app on, with common functions already built-in.
From the site:
AppFuse
An application for starting your Struts-based applications. Checkout from CVS and execute "ant -Dapp.name=yourApp -Ddb.name=database" to instantly be up and running with a Tomcat/MySQL app. Uses Ant, XDoclet, Hibernate, JUnit, Cactus, StrutsTestCase, Canoo's WebTest, Struts Menu, Display Tag Library, JSTL and Struts (including Validator and Tiles). Features include CMA, Remember Me, Self Registration, Password Hint. The fuse to start your apps.
Re:Java example (Score:1)
Re:Java example (Score:1)
Re:Good idea, but a time-sucker (Score:3, Insightful)
A more positive veiw (Score:5, Insightful)
Second. The tests themselves act as documentation. I am anoyed that I pick up generic routines like a CSV file reader and there is subroutines but no way to figure out how to use them. A test suite acts as sample code as well.
This process is balance, you don't test every detail but you do codify some tests. When you find a bug you codify a test and then you NEVER reintroduce the same bug. I find that in general I reintroduce bugs about once for every month of coding. Since this application only gets worked on in random blocks of a week here and there I am not focussed on the whole application and I simple forget. Use the computer to validate that you have not made a mistake.
These sort of tests saves my reputation, does not frustrate my users.
Re:Good idea, but a time-sucker (Score:5, Insightful)
Sorry to let you know but, you didn't write good unit tests and probably did waste your time. I've found very close to 100% of the bugs in Vstr a network IO string library [and.org] using unit tests. That includes a couple of ones that would have been damn hard to track down otherwise.
However it's been over a year since 1.0.0 which had a unit test for every function and every function option, to the last release which had over 99% code coverage [and.org]found a couple of weird corner case issues (not just bugs, but optimizations that could never be reached for some reason). And going from 98% coverage to 99% coverage took a significant time investment, and required significant thinking about how the test should be written.
As with much software development, it's easy to write simple tests that don't show much and aren't very useful. It's much harder to write tests that find bugs (and you have to appraoch writing the tests with a very different mindset to how you approach writting the code you are testing. This is not even close to being "Like picking lint from your belly-button."
Re:Good idea, but a time-sucker (Score:1)
Re:Good idea, but a time-sucker (Score:5, Insightful)
My question to you is, if you have no unit tests, how can you be sure that the code works at all? Manual testing? Do you cover all the code paths with manual testing? It must take forever, or your application is rather trivial.
Re:Good idea, but a time-sucker (Score:1, Insightful)
Have you never developed anything of significance without unit testing? I ask because it seems like you can't understand how it could be done. It not only CAN be done, it IS done, and some very solid, worthwhile code has been developed with absolutely no unit testing framework whatsoever.
But in answer to your question, (please understand that whatever I say cannot be constr
Re:Good idea, but a time-sucker (Score:3, Interesting)
Re:Good idea, but a time-sucker (Score:3, Insightful)
You also touched on another problem I have with unit testing: it influences the design pattern too much. I don't believe that the design which best fits with the unit testing framework is the best design pattern for the project. If your only goal is to make lots
Re:Good idea, but a time-sucker (Score:5, Insightful)
This is a common miconception about test-driven development. Sure, when you look at the speed at which new features go in, "development" seems to be slowing to a crawl.
But this is a very short-sighted and limited view of the whole project lifecycle. I've found that having great unit tests for my code actually help in the long run for adding new features. And that's not just adding the features to the code base, that's all the way to the end -- making sure they work properly.
Nevermind the benefit they give while refactoring in an agile development process: the unit tests become a sort contract you can guarantee will work for objects that use your code, no matter the internals of a function. For refactoring this is invaluable.
In short, you're not alone. Very few developers think long term like this and it's a shame. But once you drink the unit testing/test driven design (TDD) kool-aid I guarantee you'll never go back. I wouldn't think of writing code without unit tests any more and quite often it's TDD.
Re:Good idea, but a time-sucker (Score:3, Interesting)
I had three primary problems with it.
#1: My biggest problems always revolve around the user interface. Users encounter FAR more bugs than my internals do, and I never found a good way to unit test GUIs.
#2: I spent many hours developing tests for things that ended up rarely/never choking my tests, meaning they rarely/never caught any bugs. Yet, I still had bugs to work out. I found
Re:Good idea, but a time-sucker (Score:4, Informative)
But what would you rather debug: 1) A problem in the user interface you know has to be in the user interface because you have confidence that it's not below it or 2) the whole thing all the way down all of the method calls? If you have unit tests in the rest of the code, debugging the UI is much easier.
#2: I spent many hours developing tests for things that ended up rarely/never choking my tests....
Making tests for situations that work is still valuable. If you make such a test and it fails later on, you'll know you had a regression in the code somewhere. This is very handy to have when refactoring as well.
#3: Whenever I re-factor, unless I'm Mr. Perfect and all my interfaces are perfect from the get-go...
Interfaces can be refactored too, and of course you'll break tests and have to rewrite things because now you're expecting a new set of behaviour.
I've found that this has the side benefit of forcing people to really think about changes they make to their code and not just hack away at it. If people know they have to write tests too they seem to put more thought into it ahead of time.
Anyway, that's just my personal experience with unit testing.
Re:Good idea, but a time-sucker (Score:3, Interesting)
#2: But you know, if you have time, there are LOTS of things you can do that might help, or might not. I stopped writing unit tests thinking that they one day *might* catch a bug. If I don't have an immediate or at least imminent benefit from it, I don't do it. It's simply a waste of time.
#3: I don't hack away at code, so I don't think unit tests will save me fro
Re:Good idea, but a time-sucker (Score:2)
Then the unit tests could/should have been better. Sorry, it really is that simple.
True, and if you can get a large amount of free debugging (like a prominent OSS project) then an
Re:Good idea, but a time-sucker (Score:2)
I have been working on a very large web based product. I use a test product that exercises the UI, but I find it difficult to test two components:
1) ASP pages (or for that matter PHP or any other dynamic scripting code) that generate HTML. The test product can either check for exact matches (which means updates to XSTs break things) or it can look for things with names and IDs (which most elements do
Re:Good idea, but a time-sucker (Score:3, Informative)
First, IMO, html is the UI ... and the best way to test that isn't with a unit test (that I've seen). You want all your UI functions to just glue sql/data commands to the UI. Then yo
Re: Good idea, but a time-sucker (Score:1)
The other time I've had a really hard time figuring out the right way to do my testing was working on an aggressively multithreaded and distributed server application.
Re:Good idea, but a time-sucker (Score:1)
My feeling is, when you are a neophyte, unit testing helps you get your code up to speed while you are learning about the pitfalls of programming. However, once you pass a certain point, unit testing is simply a wasteful phase.
The bad code you see comes from neophytes. Unit testing won't help them much because by the time they become disciplined enough to actually use them regu
Re:Good idea, but a time-sucker (Score:1, Insightful)
Then you're not writing the tests correctly. In my experience the quality of code that has been developed in conjunction with (or better, after the tests are written) is consistently better than code that is written and never tested except as part of the greater context.
The real win for unit tests is when you modify the code later on. If the unit tests pass, then you can be pretty darn sure that any code that depends on the modified code will continue to work. This has saved me hundreds of times.
Read Te
Re:Good idea, but a time-sucker (Score:2)
Despite the solid try, however, they never, or rarely, found any bugs.
Pair programming, refactoring, code review, etc...all excellent ways to increase the quality of your code: provided you have the time and budget. I'm sure with enough time spent on th
Re:Good idea, but a time-sucker (Score:2)
On our project (~200kLOC), the unit tests have helped find lots of stupid things during initial development, but have really made their money during the huge refactorings needed to follow program management's wildly changing product vision.
We knew that the previous PM's were worthless, so we built a fairly broad solution against the requirements they gave us. The company eventually agreed with us, and hired a new marketing team after
Re:Good idea, but a time-sucker (Score:1)
Re:Good idea, but a time-sucker (Score:1)
Re:Good idea, but a time-sucker (Score:1)
From my personal experience (I use JUnit and PyUnit on a daily basis):
Unit tests save a *lot* of time compared to manual testing (that is not to say that they are a complete replacement)
Unit tests are a must for daily automatic build process
Unit tests are indespensible for code refactoring, as there is no way to know if you broke anything in the process without them
Unit tests help to design API (that is if you start with tests)
Re:Good idea, but a time-sucker - maybe.. (Score:1)
#1. Don't test the obvious - enthusiastic new developers (or naive old developers) tend to write miniscule tests (like testing the accessor methods of a class), which are equivalent to testing the compiler. Avoid them at all costs!
#2. Test for the obvious - if you wrote a metho
Re:Good idea, but a time-sucker (Score:2, Insightful)
Others have already commented on their varying mileage with this topic, I too believe that TDD (done correct) will rather save time than cost more time. At least in the long run. (I'll leave the "done correct" part to somebody else, books and articles have been recommended in other comments).
There's one misconception that I always see with TDD and Unittesting: Both are not the same.
In my eyes, TDD is rather a design strategy than a testing strategy. It certainly gives a test suite as a very nice "bypr
Here's a good example (Score:2, Funny)
TDD vs. unit tests (Score:4, Informative)
I'm far from convinced that TDD is actually a good approach. Although it's pretty obvious that without testing the code is often trivially buggy, and unit testing is the cheapest way to perform testing. For instance this kind of thing [msdn.com] is all too easy to do with TDD.
For unit tests you want to write your code, and then look at the best set of unit tests to do complete code coverage. For an OSS e3xample of that you can look at Vstr string library [and.org] and the code coverage [and.org] for that project.
Re:TDD vs. unit tests (Score:1)
Multiple return points usually occur because the algorithm computes the return value 'early' (often via some special condition) or because an error condition is encountered and the return mechanism is used to propagate errors up the call hierarchy.
If you write your function to have only a single return point at the end of the function, you ca
Re:TDD vs. unit tests (Score:2)
That's a simplification, a significant portion of it now seems to be gcc coverage bugs (Ie. lines marked not covered I can step through in a debugger), but yes a lot of the difficult areas are to do branches.
Re:TDD vs. unit tests (Score:2)
If one was aiming for readability, one obviously wouldn't write the gibberish in your example :-)
We didn't hit 100%, because there was code that would only be run if hardware-centric exceptional cases were encountered. In such a case, exception code was executed, which we could test via a test harness, but the
code did not get covered. I think we managed above 95%, which were we were pretty happy with. I don't recall the ratio of lines of code to lines of tests.
some projects are hard (Score:2)
We write or bring in small programs which test how we handle applications or events. But it is still really hard to test the whole thing.
Re:some projects are hard (Score:3, Informative)
Creating mock objects [sourceforge.net] is much simpler than creating a "text X server", although admitedly a wm is slightly harder than normal as you can't take the easy route of running a seperate version on your main display.
Howewver taking a quick look at blackbox, textPropertyToString() is the only thing in Util.cc that couldn't trivially be unit test
Re:some projects are hard (Score:2)
This kinds of pushes me to try testing more of the lib though
Re:some projects are hard (Score:1)
But you're in the arena of gui testing, which is hard. Everyone admits that it's hard. But for many applications, you can separate the gui from the parts that do the real work, and then test those parts. In some cases this can even give you a huge benefit in terms of prog
Re:ncurses, termcap, etc. (Score:1)
I keep junit around (Score:5, Insightful)
Do write a test case if:
+ a failure could introduce data propagation issues
+ it performs some intricate mathematical or logical function whose result must be precise
+ you're writing test cases to hunt down bugs that you know are in you're code; keep those test cases
+ you're uncomfortable about the quality of your code
+ an error might kill someone, or otherwise be Really Bad
Don't bother writing a test case if:
- you can use a guard clause or assertion instead
- a failure in the code will otherwise be immediately obvious
- the code generates massive amounts of data which need not be mathematically precise (i.e. graphical output)
- you don't feel it
I should probably write more test cases, according to my own guidelines.
The Bowling Game (Score:4, Interesting)
The unique thing about the article was that it was presented as a discussion between two developers pair programming doing agile test driven development of the game. It was like watching over their shoulders.
If you want to get an idea of what extreme programming is like, I suggest reading this article AND writing the code and tests along with it, either in Java (and JUnit) or C#/VB.NET (and NUnit) or another language with a xUnit unit testing framework [junit.org]. Most object oriented languages have them now so you don't have to roll your own framework.
Try the Portland Pattern Repository (Score:2)
SCons (Score:3, Informative)
SCons is a next-generation build tool, or make tool, written in Python with strong cross-platform support, integrated autoconf-like functionality, a lot of stable features, and a growing user community. We're currently at 14K+ lines of non-comment, non-blank source code, and 32K+ lines of non-comment, non-blank test code.
We use a combination of two different testing methodologies: 1) Individual modules all have PyUnit unit tests (similar to JUnit, but in Python, of course). 2) The SCons application itself is tested using a custom testing module that manages creation of temporary directories and files, execution of the application, and checking against expected results. This custom module is actually a wrapper around a generic "test any script/command" infrastructure module that could be easily used to test other scripts and/or commands. (The command under test could be implemented in any language, not just in Python.)
I use the Aegis [sourceforge.net] change management system to manage the SCons development and testing cycle. Aegis' primary value add (for me) is its management of the test cases and the testing methodology it enforces. By default, all Aegis changes must have one or more modified or new tests. The new/modified tests must not only pass when run against the new code, but must (by default) fail when run against the old code. This helps guarantee that your tests are good, and that your code isn't passing because you made a mistake in your test and forgot to call the new feature.
By testing in this fashion from day one, we've built up a very strong regression test base--284 test scripts at last count, each script containing multiple individual tests. This test base has become crucial to our ability to refactor (and refactor and refactor...) the internals as we add more features. Sometimes it takes longer, of course, to make a rewrite satisfy all of the regression tests, but when you're done, you can be pretty sure you haven't broken anything. And if you did break something, then you have to add or modify a test when you fix it, and that becomes another part of the regression test base.
The key to getting going with this kind of test-driven development (in my opinion) is making writing and executing the tests as simple as possible (but no simpler!). If writing a test is too difficult, then a lot of developers will simply avoid it. But if you can get them over the initial hump by making it easy to write tests, it gets downright addictive because you get all of this positive feedback when your tests show you that your new code works.
We'd be glad to have you check out the testing infrastructure we've developed for SCons, either for code you can actually use, or simply as a source of ideas. Feel free to contact the SCons development team if you have any questions.
Re:SCons (Score:1)
It's been interesting how most of the examples people have come up with are Java and Python; seems to be a language culture kind of thing.
Thanks again.
Re:SCons (Score:2)
Have you ever consider Subversion instead of Aegis for change management in Scons? If so, does it has same level of support for testing? If so, can you recommend a combination of Subversion+Scons for the process automation in mid-size teams?
Boost (Score:3, Informative)
And check out the Boost unit test libraries. http://boost.org/libs/test/doc/index.html
Looking for an example of Test-Driven Development? (Score:3, Informative)
It's a neat little book. The first third demonstrates writing a Money class in Java using test-driven development. It's kinda like you're sitting next to him and he is demonstrating. In that example he shows a lot of what comes up in an average TDD session. If you're new to it, you might not realize how fluid it is, and how tiny the steps can be. Even if you *think* you know what TDD is about from reading a description, this will really show you how it works.
Then the next chapter is really cool.. here he writes a unit test framework in Python
Final third of the book is patterns, example, theory, philosphy, somewhat interesting.
This is a book you'll only read once or twice, honestly, but you will benefit greatly from it. In my opinion.
Re:Looking for an example of Test-Driven Developme (Score:1)
Re:Looking for an example of Test-Driven Developme (Score:3, Informative)
I am left still wanting a nice non-trivial working example to look at.
The Craftsman (Score:3, Informative)
Software Development Magazine [sdmagazine.com] has been running a series for about the past year called The Craftsman written by Robert C. Martin. It focuses on a young apprentice writing a java app with his mentors. Nothing is done that doesn't involve a test first.
While the series itself is kind of slow, it is a good introduction to TDD, and I really enjoy Robert's writing style. Might be able to lead you to some more examples.
Most OSS projects don't use XP (Score:1)
Therefore most test first projects are probably closed source. I can't show you our whole code base but we are a TestFirst XP place with 1654 unit tests currently in place.
For large scale testing mock objects are invaluable. See www.mockobjects.com and www.mockmaker.org
Here is an example of what a test looks like using Junit and MockObject testing. It might give you a feel for how easy the tests are to write.
Re:Most OSS projects don't use XP (Score:1)
gcc (Score:3, Informative)
http://gcc.gnu.org/install/test.html
TDD with web development (Score:1)
Thanks in advance for your replies.
Re:TDD with web development (Score:1)
Search for "php unit testing"
If you're too lazy, here are some links:
Unit Testing in PHP [phppatterns.com]
PHPUnit [sebastian-bergmann.de]
Happy unit testing!
Take a look at Eclipse (Score:1)
Junit has its own unit tests (Score:2)
Fwiw - I'd suggest that a large project is _not_ the best way to get to understand how unit testing works - there is likely to be way more detail than you need or want. Matt Raible [raibledesigns.com] shares some code (esp. AppFuse) which includes unit tests, and describes them in his wiki on Appfuse tutorials [raibledesigns.com].
His "Struts Resume" demo application contains some pretty interesting unit tests of a real-world application.
Now, here's