TDD: were to start

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

Post Reply
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

TDD: were to start

Post by matthijs »

After having started a bit with writing my first tests for a model class in an MVC app I started to think a bit further and have some questions about the next step.

We know that in a TDD approach you start with the simplest thing. You write a test testFetchUserId() or something and then write the minimal code needed to do that. Ok, that's clear. In this case, i started working on one of the "deeper" classes of the system in the data layer.

But we all know that a medium sized project is more then just a few classes which pass a test. At the front end we need pages which show some kind of combination of data, coming from different db tables and thus using different model classes. Somewhere between that single front page view and all those backend (data) classes a lot is happening. User authentication, validation, session handling, data mapping, etc etc

So how do I get to that?

To give an example. You have a CRUD like app with categories and articles (which can be in different categories) and users (who write articles in different categories), etc. With my approach you would start to test/write a few model classes for categories, articles and users. Fine. You have some model classes for adding, deleting and editing cats, articles, and users. That will probably look like a couple of active record classes.

Ok. Then what? Should you then just start testing the front-end views? Like, test a class with methods like showAllArticlesBy AuthorId(), showCategories(), showArticlesInLastMonth() etc? If I would do that it would be difficult to use the model classes as I designed earlier, because I need to combine the data from several tables somehow.

Or should I have started with the front end anyway?

Well, I hope my issue is clear and some people could enlighten me on this.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

To a certain extent, TDD can test overarching segments of functionality, using mocks if necessary to reduce the amount of lower level components each unit test depends on (and testing more specifically that component and how it integrates several classes together).

TDD doesn't catch everything though, so you'll want to set up a bunch of smoketests, where a live human steps through various procedures in the application and makes sure everything is working properly. Tools like Selenium can automate this process.
phait
Forum Commoner
Posts: 46
Joined: Wed Apr 07, 2004 4:41 am
Location: watford / leicester, UK

Post by phait »

hi,
In addition to what the commander mentioned above, if you use Simpletest, you can also produce the user acceptance tests / smoke tests / (insert other name here). So you can have your unit tests and then test them in situ on a test server prior to making them live, or perhaps just on your local dev box.

http://www.lastcraft.com/web_tester_documentation.php

I think ST V.2 might also have some changes with this aswell, Marcus has certainly suggested that on posts elsewhere. I think there is also a plugin available that generates Selenium scripts for integration with ST 1.

Google is your friend.

Cheers,
phait
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Thanks for the replies and suggestions.

I'll look into the user acceptance tests. I did read the web tester docs. (still getting many errors using it, but that's another question). I'll also look at Selenium as Ambush suggested.

I would like to go a bit further into the general approach of using TDD though. The thing what bothers me, at the moment, is that there's such a wide gap between the idea of TDD as I understand it now and the reality of how mid- or larger sized applications might look like. What I mean is as follows. In the TDD/agile way you start writing one test on one class. On success, do the second. Etc. Once the classes get bigger you will see that you start repeating certain parts of code, or you spot certain areas with code smells. So you refactor the code. However, at this point you will still have a fairly "flat" layer of classes. At most a few helper classes which you got with refactoring. For example, a db class.

However, if you look at an average MVC -diagram, there are many layers. In Sweatje's book you have Controller, ActionFactory, ShowViewAcction, ViewFactory, View, Model, TemplateEngine. I do understand the purpose of all those layers. What I find hard to see is how you get from that first "flat" layer of classes after writing those first tests to such a deeper layered application.

Do you get there only with refactoring? Do you do that each time you write a new application, rewriting the code again and again until you end up with all those layers?

Or do you start with a general idea of how the design might look like (in this case MVC) and write your tests/classes accordingly?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

However, if you look at an average MVC -diagram, there are many layers. In Sweatje's book you have Controller, ActionFactory, ShowViewAcction, ViewFactory, View, Model, TemplateEngine. I do understand the purpose of all those layers. What I find hard to see is how you get from that first "flat" layer of classes after writing those first tests to such a deeper layered application.

Do you get there only with refactoring? Do you do that each time you write a new application, rewriting the code again and again until you end up with all those layers?
There are only three layers - Model, View, Controller. You can add Database as a fourth, but often it's not a Unit Testing concern. Within those three layers are various competing Patterns you can implement, mix and match. For example, you could have single Controller classes OR multiple Action classes OR ...

TDD and Unit Testing will push you towards what you call "flat" class families. This is considered a major benefit for many people (assuming I'm interpreting you right). Something that's flat has little depth, it's easier to pull out and reuse elsewhere without having to cart half the whole library with you because there a dozen dependencies are all deeply buried and hard to extract. I think most of your issues lies within the Controller layer. If you have unit tested Models, and a set of unit tested component classes (authentication for example) then you are well on your way.

It all starts boiling towards the Controller - since the Controller manages workflow a great deal and determines a lot of how you use the classes you have assembled. As in all things like this, an example would be easier to dissect and discuss...
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Thanks for your explanation Maugrim.
TDD and Unit Testing will push you towards what you call "flat" class families. This is considered a major benefit for many people (assuming I'm interpreting you right). Something that's flat has little depth, it's easier to pull out and reuse elsewhere without having to cart half the whole library with you because there a dozen dependencies are all deeply buried and hard to extract.
This makes sense. And gives me some hope :)
It all starts boiling towards the Controller - since the Controller manages workflow a great deal and determines a lot of how you use the classes you have assembled. As in all things like this, an example would be easier to dissect and discuss...
You're right. Once I rethought this a bit and when I have my first classes figured out I'll post a concrete example.
Post Reply