Starting Test Driven Development...

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Starting Test Driven Development...

Post by CoderGoblin »

OK You have a new idea for a web site and you decide to take the plunge and throw your normal programming methodologies out to try this newfangled TDD... You look at www.lastcraft.com among other things and think that is useful but, and here come the sticking point, where do you actually start ?

Do you build the tests for the outlined pages first using SimpleTest WebTester ? Or would you start building the testing of classes you assume you will need. What if you do not intend to use classes outside of the "testing" methodology. Classes are (IMO) often overkill for a "simple" website.

Are there any tutorials out there which step you through the development of a "site" integrating WebTesting and UnitTesting ? You see plenty on the nuts and bolts but we are talking about a change in how people (well me in this case) thinks. What I really need is a basic thing along the lines of "I need to build a site where the user logs in or registers and then can surf around spefic pages applicable to his 'access level'. How do I use TDD to do this ?". Has anyone seen any tutorials like this which they could share ?

Looking at the Sitepoint Forums I have noticed that some topics include the comment that different people "design" more in their heads than others. I find it difficult to break away from trying to design the system in my head first. Is developing a very basic "skeleton" of a series of tests acceptable (Register, Login, Browse) or is the development really only one test at a time ? I guess what I am trying to ask is, if you have the "user scenarios" worked out surely you should develop a top level suite of tests to fulfill these requirements (i.e a ToDo list) rather than step through one at a time and "miss" something out ?

Thanks for your time but I am getting confused where to start on this.... (Luckily only playing at the moment not devleloping a system for a client).
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Here is how i would do it:

1-) I would write a couple of WebTests for a simple website. And code the assertions that i expect...

2-) Then i would code untill all those requirements are fullfilled. Well, meaby i wouldn't code _everything_, i would write a MockObject for the database manipulation and concentrate on the other details. So, after this coding i would expect all the test to be successfull (Say hello to the green bar).

3-) Now, you have to repeat this process. The requirements are the remaining stuff (== the Mock Objects).

In each cycle you will either write actual code, defer code by introducting a Mock Object. You repeat the cycles untill there are no Mock Objects anymore.

Notice that you are nowhere forced to use classes whatsoever in your code (Except for the tests that is).. But as with all software design, you will see pretty soon where classes are useful :)
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

Thanks for that timvw. I need to look into Mock objects more as I have only really just looked at them briefly.
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

I find I'm maintaining several ToDo lists.

One is my list of "functionality" I want to add, typically rather fine grained and hopefully simple. This is the one that I look at when picking what to do next most of the time and its where I add all my little ideas that pop up while coding of what else needs to get done.

Another is my list of "Unimplemented Mocks", anytime I mock something and create an empty class/function shell, I add it to this list. While the interpreter will normally find these for me if I try to run without fleshing them out, I like the list. I have a similar list for all "Unimplemented Views" for anytime I name a new template, but haven't written it. I'm not using TDD to drive the layout of the template so this is the compromise I'm using. I also have a list of "Required Queries" since I store my queries in a separate file(s) and typically need to mock their execution.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Re: Starting Test Driven Development...

Post by McGruff »

CoderGoblin wrote:Classes are (IMO) often overkill for a "simple" website.
For a simple shell script, maybe. Definitely, categorically not for a web app. If you stick around I'll show you one of the most important things you can learn as a programmer. It's going to be 100% OOP.
CoderGoblin wrote:where do you actually start ?
Different kinds of tests are used for different purposes. Acceptance tests (using the web tester) are broad-brush, black-box tests which relate to client requirements. For example "only site admins can access the admin area". For that you could set up a web test which asserts failure to open the admin page when not logged in, and which asserts success after submitting a valid name & pass.

You can start with web tests if you're collaboratively designing acceptance tests with the client - tools like Fit are aimed at this. Marcus Baker has started the Arbiter project for php. You'd create the tests and they'd all fail until you've written enough of the app to start passing some tests. The client can monitor progress by running the acceptance tests themselves.

However it's the unit testing - fine-grained tests for individual classes - which actually builds the application. You can jump in and make a start anywhere of interest but since TDD works from the top down, the top is a good place to start.

The method is to write a little test then write a liittle code to pass the test. As soon as the test passes, you're done. You do the simplest thing that gets you through test then move on.

Test-first means that you are always coding to a requirement. This helps enormously to keep you focussed. You don't go off on a mission to investigate the whole "calendar" domain if all you want is a happy birthday message for site members. These classes might well be useful but they can wait until a real need emerges. It's taken for granted that there will be a fair amount of refactoring down the line as new features are requested or you simply learn more about the design. Any dead wood is going to make this harder.

Back in the unit test, if you find a responsibility which doesn't easily fit within the class under test you've just discovered a neighbouring object in the design. This will be mocked and implemented later. Expectations will describe how the primary class interacts with the mock: what methods will be called, what values should be passed and returned. Its this which makes testing a design tool. In the process of writing a unit test for the primary class, you end up designing interfaces for neighbouring objects. When you come to implement a mocked object, you might discover yet more classes, and so on and so on. The design ripples out from the point at which you started.
CoderGoblin wrote:Has anyone seen any tutorials like this which they could share ?
Let's do one here. Pick a class, I'll write a first test, then you can write some code to pass the test.
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

Having trouble thinking of anything useful really but lets start with the problem above. A system where the user wants to register,login and browse. This is, I think a common useful starting point. If you have any better ideas than feel free to use that. Basic testing of units is covered well in lastcraft. It's a tutorial of the overall development cycle which I think is missing.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

I'm glad you've posted this question CoderGoblin :)

I've been meaning to jump into this for a while but all the discussion so far has been more advanced than I need right now. I'll be watching how this moves.

I've gotten to a point where I *just about* use OOP to do most things where I can implement it.

It's something I'll have to learn in my own time unfortunately and if I don't get started this evening (I may have to work late) I'll get cracking tomorrow. It's good to see that it's beginning to catch on here and I'm not the only one who's a bit confused how to get started in TDD :D

(I may be pestering you guys shortly :P)
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

Yeah that goes for me as well. I can see the advantages of OOP development. I don't really understand TDD. How does it work? How does one get started at it?
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

CoderGoblin wrote:It's a tutorial of the overall development cycle which I think is missing.
The overall picture - as I see it - would be to build all the individual classes using test-driven design & mock objects then introduce some integration tests (which substitute real classes for the mocks). You need these to check that everything really is working OK together.

Web tests are really another form of integration test. It depends how you're working whether to write these first or last. By all means set them up first as a means of specifying requirements, if you like. They can wait though - as long as you *do* have a clear set of requirements. If you've agreed that acceptance tests will define the contract with a client you'd obviously want to write them first to get everything crystal clear.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

I'm wondering what to do next. Codergoblin: it's your topic. I'm not sure if you'd like to run through a TDD session to see how that works in practice or if you know how that goes and were instead asking how all the different types of tests acceptance/integration/unit fit together in a project?
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

Its's really
asking how all the different types of tests acceptance/integration/unit fit together in a project?
As previously stated the lastcraft website is, I think, generally good at developing the individual tests and although it would take some reading and "playing", it appears relatively straightforward. Even within this topic the importance of MockObjects is becoming clear and the comment of having two "ToDo" lists is really useful.

As is frequently the case it is all to easy to investigate the nuts and bolts and lose/not find the overall picture. I will be unable to continue now until Monday but will attempt to do some work on it over the weekend.
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

well It looks as though this has now been started in deltawing's topic. Sorry for not pushing forward with this. I just had my 2yr old daughter have to go into hospital on Saturday with an "epileptic" like fit (she's ok now though) so haven't been able to do anything. Will be playing with the ideas in the other topic and would advise others to.
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

I've been wanting to have a go at some TDD sessions in the forums but I can probably only manage one at a time. We can certainly get back to this later though.

Glad to hear your daughter's OK.
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

McGruff wrote:I've been wanting to have a go at some TDD sessions in the forums

Code: Select all

assert("$Me = 'Waiting for this stuff'");
returns TRUE :D
User avatar
sweatje
Forum Contributor
Posts: 277
Joined: Wed Jun 29, 2005 10:04 pm
Location: Iowa, USA

Post by sweatje »

It will always return true, because your asserstion was an assignment not a comparison ;)
Post Reply