SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Member
    Join Date
    Mar 2004
    Location
    Indiana
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Test Driven Development Jump Point

    Over the past few months I've been educating myself on unit testing; or more specifically test driven development. I see the benefits, as well as the dedication and self-discipline required, and am ready to commit myself to this way of development. Although I've read several very good tutorials on the topic (the tutorials available at the SimpleTest site are invaluable in my opinion), when it comes time to sit down and start a project of my own and I am readying myself to write that first test I invariably draw a blank.

    Perhaps I'm overthinking to much to early on in the process. While I usually don't pre-plan every inch of a project before starting (I feel overdesign to early on in a project is limiting, and I'm sure there are others that would agree!) I do have a solid idea of where things should be going. Left to my own vices, I end up thinking in terms of "modules" and begin writing projects "module" by "module" on a home-grown framework heavily based on the ideas of open source CMS applications like Postnuke (which incidently was my first introduction to php).

    Is this a normal part of the learning phase? If so, what pointers would those of you with more experience in this area have on changing this train of thought? Any advice that could be offered would be appreciated. I feel that I've reached the proverbial "brick wall" in my skills as a developer and would like to explore the horizons a bit to get over the hump. Thanks to all!

  2. #2
    SitePoint Addict
    Join Date
    Jan 2004
    Location
    New York
    Posts
    254
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just started writing test cases today, and some still feels like it isn't what a test case should be. But it started when I told myself "this class should handle this responsibility" and broke that down. Then I went and made test cases with the idea that the test cases are just observations of the class under a controlled environment.

    An example: I want a cookie management class. The first feature I wanted my class to have is check to make sure that a cookie's value is 'normal' or 'different' and sets to 'normal' by default.

    My test case loads up the cookie management class, executes the setCookie() method with the cookie value to 'blah'. Then I did $this->assertEqual($cookies->getCookie(), 'normal') right after. This makes sure that even though a nonsense value is entered, the default value will be set.

    From there I went into some more detailed test cases. Then I began seeing how test driven development forces you to think deeply about the architecture of your site. Although I am still struggling a bit.

    Hope my story helps.

  3. #3
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    Do you have a specific example? What is the application you are developing?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  4. #4
    SitePoint Member
    Join Date
    Mar 2004
    Location
    Indiana
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Atealtha, thank you for your experience! I am seeing how test driven development is forcing me to change the way I approach problem solving.

    As for a specific example I will use the one that I'm starting on this weekend as a pet project, an automated rollout script. I've read several other posts by you on this forum on how invaluable such a tool can be during the development process and I also think it would be a good learning experience to keep me on my toes.

    Right now I only have a few requirements in mind to get me started:

    - Simple solution for rolling out websites and applications.
    - Support for retrieving application files from a repository (such as CVS or Subversion)
    - Verifies all tests are passing on said website/application before rolling out.

    There are many more ideas and I'm sure I could think of a million more in a brainstorming session, but these are the base requirements and I'm trying to limit the scope for the time being.

    When sitting down to start the project I've chosen to test connecting to a CVS server from the script. I'm doing a bit of research right now on HOW to accomplish that task (not coming up with many resources atm but am playing with the exec command to hopefully accomplish the task). It's in this type of research that I usually end up just writing code instead of more tests as that's how I'm use to doing things by now.

    Thanks again for your time, any help is certainly appreciated!

  5. #5
    Mal Reynolds Mandibal's Avatar
    Join Date
    Aug 2003
    Location
    Columbus
    Posts
    718
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm struggling with the same things as you phpcod3x. For instance, I decided I could really use a DataList class for almost all of the projects I work on. So I sat there thinking and actually ended up writing out the classes skeleton first (with way too many methods and variables that I ended up erasing by the end). I had to force myself to stop and go back and start writing some tests.

    Well after a few minutes of just browsing around and trying to decide what to do I remembered that the thing I'm trying to accomplish with the tests is to test the public interface of the class. So I started with that. I wrote a test that tested that the render() method of my DataList would accept an array of data and convert it into an XML string. Great. (At this point I also realized I would probably need to change the name of the class but havent yet).

    One of the things I wanted the class to do was return the data in a variety of manners. To start I thought I would want a getDataListAsTable() method. So I set up a test to check wether the method would return a string with a table tag in it. Remembering some things from the Becks book on TDD I first set up the method to just return a string like this "<table>". Thats it. The tests passed as they should. Then I rewrote the method to use an XSLT stylesheet to transform the XML string created by the render method into a table with the data in it. Got the test to pass again. Then I decided that instead of hard coding the stylesheet into the method and naming the method so specifically for tables that it would be more usefull to pass the path of the Stylesheet to the method now named getDataList(). Got the tests to pass and now I was realy getting somewhere with the DataList class. I had three public methods that were tested (render(), getXMLString() and getDataList()) and a decent interface going that allowed for flexibility. BTW the test method I named testGetDataListReturnsTable stayed the same throughout the changes to the getDataList method because it was still usefull to describe the behaviour I was looking for.

    That's all the further I've gotten in the class but I feel like I learned a little about how it can benifit my developement by 1) testing first and 2) remembering to test the public interface of the class. When I first was getting started I think I spent too much time trying to decide what to test. But I think it's okay to start big (ie one method that might accomplish too much) and then wittle down. In my example I started with just the render method and got that working then figured out that it was usefull to expand the interface some and so I tested those etc. The class itself probably has 5 methods now but only 3 public ones so far.

    I don't know if this is helpful to others or if I am on the right path now. I'm sure the great Sitepointers will help us out with this. I'm trying though wich is more than I had been doing 3-4 months ago.
    Erh

  6. #6
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mandibal
    But I think it's okay to start big (ie one method that might accomplish too much) and then wittle down.
    Remember that the tests are there to tell you exactly what is going wrong so that you can fix things quickly and easily. Finer-grained tests are best for this ie you might sometimes want to make several test methods for a single class method, each exploring a different constraint. Good naming helps as well.

  7. #7
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by phpcod3x
    As for a specific example I will use the one that I'm starting on this weekend as a pet project, an automated rollout script.
    You really are throwing yourself in at the deep end . Ok, here goes...
    PHP Code:
    class TestOfRollout extends ShellTestCase {
        function 
    setUp() {
            
    $sandbox = new VersionControl('path/to/sample/sandbox');
            
    $sandbox->createProject('Test');
        }

        function 
    tearDown() {
            
    $sandbox = new VersionControl('path/to/sample/sandbox');
            
    $sandbox->removeProject('Test');
        }

        function 
    testCanRollOutOneFile() {
            
    file_put_contents('path/to/sample/sandbox/script''Hello');
            
    $sandbox = new VersionControl('path/to/sample/sandbox');
            
    $sandbox->checkOut('Test');
            
    $sandbox->add('script');

            
    $this->execute("php rollout.php 'path/to/target'");
            
    $this->assertFileExists('path/to/target/script');
            
    $this->assertFilePattern('path/to/target/script''/Hello/');
        }

    That's just a top level acceptance test. You know when you are making progress when this runs. The next step is simplyto have your rollout.php script just write out the file 'Hello'. Work backwards from there.

    I am assuming that as you advance you will have to flesh out the class VersionControl. You will probably need separate tests for this. I often find that the first few acceptance tests force some utilty clases onto me, or utility scripts such as installers.

    Just a suggestion.

    yours, Marcus
    Last edited by lastcraft; Jun 11, 2005 at 15:08.
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •