4

I've read a lot about TDD and I've tried to develop using TDD without success ... I always stop staring at the screen...

I've learned that I should not write tests for methods or class. I should write tests for behaviors. That's because objects interact with each other and this interaction should be tested.

Following the example bellow:

Imagine that, I, as a company owner, would like to save my customers information to consult that later.

That's my business value.

Just to learn, I would not like to use any framework or library, just plain PHP and PHPUnit.

Ok, now, where should I start?

I think that my users must enter an url to go to the form ... So should I test if it's loading the page? Is this a good start? If it's true, how could I test it?

5
  • 11
    With writing tests.
    – cweiske
    Commented Jul 14, 2011 at 14:01
  • But using my user story, where should I start? I really don't know what test before ...
    – thom
    Commented Jul 14, 2011 at 14:14
  • 2
    @thom: If you're doing TDD and there is nothing to test it means you've got your job done! Congratulations!
    – hakre
    Commented Jul 14, 2011 at 14:16
  • @hakre: TDD is tests first, so if there's nothing to test yet... then you're just getting started. Commented Jul 14, 2011 at 21:17
  • @SnOrfus: Or all is already tested ;) I think you got the idea ;)
    – hakre
    Commented Jul 14, 2011 at 21:44

5 Answers 5

5

It sounds like you're mixing up BDD (behaviour driven development) with TDD (which isn't surprising as they're arguably very similar).

BDD is a bigger process than just the tests, but to focus on what's relevant to your question:

  1. pick out an important feature that you want to implement.
  2. pick a specific scenario which you feel is a representative example of the feature (personally I'd go for the simplest happy path rather than diving at exceptions or edge cases).
  3. write a test at the level of abstraction that's closest to the scenario/specification. work your way outside in through each layer of abstraction until the scenario is fully implemented.
  4. if you haven't covered the feature go to 2 and repeat until you have all scenarios relevant to the feature implemented
  5. otherwise go to 1 and repeat until done

I think that this approach is best suited to when you're implementing something very 'businessy', on the rare occasions that I have to do something moderately complex at a low level (e.g. something with a more algorithmic or technical bent) then it becomes less useful doing vertical spikes and it's easier to stay in the same layer of abstraction and work with a more formal approach to edge cases, pre&post conditions, etc.

Edit: oh, and yes if you're doing outside in checking that the form (or more correctly enough of the form to implement your scenario) appears correctly is a good start - don't put too much emphasis on testing the GUI though, you can easily get bogged down in fragile tests.

3
  • 1
    BDD is part of TDD alongside with Unit Testing (which, I suppose, is what you mean by TDD in your answer)
    – Mchl
    Commented Jul 14, 2011 at 20:44
  • 1
    The relationship between TDD and BDD is somewhat controversial to say the least! In any case BDD is usually seen either as a superset/development of TDD (mostly by BDD fans) or simply TDD done correctly/well (by TDD fans).
    – FinnNk
    Commented Jul 14, 2011 at 21:26
  • I don't find it controversial at all. For me TDD encompasses all techniques to test-drive the development: from unit tests at the very bottom, to user acceptance tests on top. ;)
    – Mchl
    Commented Jul 15, 2011 at 7:14
2

I often find it easiest to start with tests for error handling. In your case this could be: if there is no client in database with given ID, raise an Exception.

2
  • It may be easiest, but in bigger applications I'd rather get a feel for where the design is going as soon as possible rather than immediately testing technical details. Sometimes it's useful to bound the problem first by covering edge cases or exceptions, typically where the problem is mathematical or algorithmic, but not for this sort of thing - it's more likely to get in the way IMHO.
    – FinnNk
    Commented Jul 14, 2011 at 20:24
  • @FinnNk: sure thing. I gave this example, because we we have an example of a single user story here. When beginning work on an application, we usually have several user stories at our disposal, from which it might be easier to extract useful test cases.
    – Mchl
    Commented Jul 14, 2011 at 20:43
1

I've learned that I should not write tests for methods or class. I should write tests for behaviors.

This is not true. Your methods should express your behaviors, and you should unit / integration test those methods and classes.

You said you use PHP, well, PHP sites usually don't have complex business logic. (disclaimer: I've said usually) The most complex part is the UI, so what you can do is first switch to doing MVC, and then you will see where your tests fit. When you have explicit methods on your controller, you can easily extract some behavior in a test which has some value.

3
  • I will use MVC but I don't have any structure now... I want to start from scratch. Thank you.
    – thom
    Commented Jul 14, 2011 at 14:48
  • I disagree - in TDD as opposed to more general unit testing you'll be defining your behaviour in the tests and then implementing them using methods (or other constructs).
    – FinnNk
    Commented Jul 14, 2011 at 20:18
  • Well, I admit I was vague in my answer, but I just wanted to say that sometimes you can have a method called Save() for which you should write tests to verify if it does what it should. I completely agree with your comment Commented Jul 14, 2011 at 20:32
1

save my customers information to consult that later.

Then I think a good test would be to see if you have a file on your harddrive, or an entry into a database, that contains all the "customers information". Or you simulate a user coming to your site, doing whatever, and seeing if the information was saved successfully.

What information? Yeah... that's a good question.

1
  • Mocked information of course ;)
    – Mchl
    Commented Jul 14, 2011 at 19:42
0

Your example is little broad. Target a small section of the problem to start with.

There are any number of places to start. You can start with the page load for the form. (Selenium is a nice tool that integrates with PHPUnit http://seleniumhq.org/projects/ide/) Or the processing of the information on the backend. You are going to have some sort of function/method that is going to process the data. What is this method going to do? Write the information to a database? Return it formatted in a specific manner? What about invalid data?

You should have a story or process in mind. For example, John Smith fills out a form with his name and address. So you can start with a test ensuring that a page comes up with a name and address field. Proceed to the next step, John Smith submits the form and the data stored in a database. So you write a test that makes sure submitted data is entered into your database. Repeat.

TDD helps serve two purposes in my mind, the first being confirmation that the code that I am writing behaves as I want it to and can be modified without causing new bugs. And second as a guide for what the code needs to do. If you provide me with your tests, I should be able to come up with a similar solution to the problem as you (the only difference being our individual coding styles).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.