8

I am developing my first project using test driven development. I am using Zend Framework and PHPUnit.

Currently my project is at 100% code coverage but I am not sure I understand in what order I am supposed to write my code.

Am I supposed to write my test FIRST with what my objects are expected to do, or write my objects and then test them?

I've been working on completing a controller/model and then writing a test for it but I am not sure if this is what TDD is about.

Any advice?

For example, I wrote my Auth plugin and my Auth controller and tested that they work properly in my browser; then I sat down to write the tests for them which proved that there were some logical errors in the code that did work in the browser.

Mike Partridge
  • 6,587
  • 1
  • 25
  • 39

1 Answers1

20

Test first. TDD is also IOW called "test-first development".

What you have been working at is not TDD.

TDD is 1-2-3:

  1. Write a failing test.
  2. Make it pass (committing any sins and shortcuts during the way).
  3. Remove duplicities (logical, not just physical).

In shorter words this is also advertised as "make it fail / make it work / make it right".

More in Kent Beck's awesome book Test-Driven Development By Example.

gnat
  • 21,442
  • 29
  • 112
  • 288
herby
  • 2,734
  • 1
  • 18
  • 25
  • 11
    +1 These three steps are also known as "Red-Green-Refactor". – Fenton Sep 19 '12 at 08:53
  • 2
    Make it pass means: Write only so much code that It pass, not more! That's quite important. – ollins Sep 19 '12 at 09:30
  • @ollins: Yes. Or, from the bigger PoV, "Never write a line of code without a failing test.", that is, _never_ write any piece of production code which is not necessitated by existence of failing test and which makes this failing test pass. Kent Beck calls this approach "test-infected". – herby Sep 19 '12 at 09:36
  • Does "write a failing test" mean, for example, that you validate the input and if it's not within the allowed range, it returns an error? Eg. if($x < 1 || $x > 5) { return 1; } else { return 0; } – Juha Untinen Sep 19 '12 at 10:06
  • 2
    It *used* to be called Test-First Development, but that is misleading: it's not about writing your tests first, it's about letting your tests drive the design and development. Writing your tests first is simply a prerequisite for that – how can your tests drive you if they don't exist yet? But you can write your tests first and still not let them drive you, and then you are not doing TDD. – Jörg W Mittag Sep 19 '12 at 10:08
  • Also: Compiling is failing. My first test for a new class is ALWAYS: obj = new (); That will fail, as you of course have not made the class yet, and by writing class {} you have suddenly made your test pass, hurray! – martiert Sep 19 '12 at 10:51
  • @martiert: It is a wrong test. You do not test anything in that test (existence of class is implementation detail). – herby Sep 19 '12 at 11:42
  • I know I don't really test anything in that test, and yes, I could omit it without problems. It's also deleted in the refactor step after the second test passes. The only thing this actually achieves is that I don't write more code than is sufficient to pass a failing test. – martiert Sep 19 '12 at 12:47
  • 100% code coverage != TDD. Remember to disassociate TDD from Unit Tests. Unit Tests generally can't be written until after there's code to test. TDD tests are usually integration tests. – deltree Sep 19 '12 at 13:16
  • 3
    @deltree erm... I disagree with every statement you made! – Froome Sep 19 '12 at 13:43
  • 2
    except "code coverage != TDD" :p – Froome Sep 19 '12 at 14:04
  • @Froome Ok, my statement is based on a lot of testing experience. I write my TDD tests based on User Story acceptance criteria, then code, then write Unit Tests to increase code coverage so that future programmers know when they've changed the code in a way that breaks expected functional logic – deltree Sep 19 '12 at 14:05
  • @Froome http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx a link to explain – deltree Sep 19 '12 at 14:11
  • @Froome also http://programmers.stackexchange.com/questions/59928/difference-between-unit-testing-and-test-driven-development a link from this site. Unit Testing is a method of testing. TDD is a timeframe of testing. TDD ultimately is a method of building an application, while Unit Testing is a method of testing that application, and people tend to mix the two terms so I was trying to clarify – deltree Sep 19 '12 at 14:18