SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 56
  1. #26
    SitePoint Zealot Kayarc's Avatar
    Join Date
    Sep 2009
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Amenthes View Post
    It is always valuable, but especially when you have to maintain a project.
    Small or large, does not matter that much. But if you're called six months after
    you finished a project to modify some functionality, you'd want to have tests.
    You want to be sure you're not introducing bugs in the old code with the new
    features.

    Anyway, the above is just one side of unit tests, the side that helps you check
    functionality. Unit tests are also helpful in designing your application, but only
    when you're doing TDD. TDD helps you keep components decoupled, which in
    turn will help teams in sharing components.
    I guess, then, Unit Testing will be the inevitable next step for me to become better at my craft.
    Phoenix Arizona Web Design | info *at* kayarc.com | 602.633.2676

  2. #27
    SitePoint Guru
    Join Date
    Jan 2005
    Location
    heaven
    Posts
    953
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayarc View Post
    I guess, then, Unit Testing will be the inevitable next step for me to become better at my craft.
    I've yet to write one Unit Test in over 8 years of programming in PHP. I seem to get along fine with out it. One of my co-workers actually sent me a link to this article which reminded me of this thread.
    Creativity knows no other restraint than the
    confines of a small mind.
    - Me
    Geekly Humor
    Oh baby! Check out the design patterns on that framework!

  3. #28
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by imaginethis View Post
    I've yet to write one Unit Test in over 8 years of programming in PHP. I seem to get along fine with out it. One of my co-workers actually sent me a link to this article which reminded me of this thread.
    Indeed, I've seen programmers that are OK without unit tests, and I actually
    envy them. For me though, having to write code, which is supposed to be
    tested by clicking I don't know how many times, is not ideal. I have a feeling of
    total discomfort when there's nothing that "watches" what I'm actually coding
    right there. I feel like in a big dark room, where I can touch something that
    could fell off and break. The level of stress shortly before and after deployment
    is high as well.

    @imaginethis, how do you actually test your code to know it's working
    properly? You must be testing you're code, even if it's not done in an automatic
    manner.

    Before unit tests I was usually clicking away on the front end of my app to see
    whether it's working fine. In fact I'm still doing this as I maintain old code
    without tests. But I'm lazy, and I really like the joy of dots in PHPUnit, or the
    green of other testing frameworks.

    For me, writing unit tests actually speeds up the development, so I don't
    actually agree with that guy from Netscape. But then again, I'm not a rockstar
    programmer or a real hacker. I do a lot of mistakes, so I need a cure.
    I'm under construction | http://igstan.ro/

  4. #29
    SitePoint Guru
    Join Date
    Jan 2005
    Location
    heaven
    Posts
    953
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Amenthes View Post
    Indeed, I've seen programmers that are OK without unit tests, and I actually
    envy them. For me though, having to write code, which is supposed to be
    tested by clicking I don't know how many times, is not ideal. I have a feeling of
    total discomfort when there's nothing that "watches" what I'm actually coding
    right there. I feel like in a big dark room, where I can touch something that
    could fell off and break. The level of stress shortly before and after deployment
    is high as well.

    @imaginethis, how do you actually test your code to know it's working
    properly? You must be testing you're code, even if it's not done in an automatic
    manner.

    Before unit tests I was usually clicking away on the front end of my app to see
    whether it's working fine. In fact I'm still doing this as I maintain old code
    without tests. But I'm lazy, and I really like the joy of dots in PHPUnit, or the
    green of other testing frameworks.

    For me, writing unit tests actually speeds up the development, so I don't
    actually agree with that guy from Netscape. But then again, I'm not a rockstar
    programmer or a real hacker. I do a lot of mistakes, so I need a cure.
    Generally the only errors I make when programming are simple parse errors. Every once in a while I make a stupid mistake, for instance this one, after being up for a day or 2. Generally I write my code and it works, if it doesn't its a parse error and I fix it then it works.

    Its not that I'm infallible, far from it. It's just that all the hard work has already been done for me. For instance heres a simple function from one of my models.

    PHP Code:
    /*************************
     * @param integer $id
     * @return Zend_DB_Table_Row
     */
    public function find($id)
    {
        
    $helper $this->getHelper('dbtable');
        
    $table  $helper->getTable('clients''default');
        if( 
    $result $table->find($id) ){
            return 
    $result->current();
        }

    There's not alot of room for error. Most of the functions in my models tend to be this small, roughly 1-15 lines of code. My controllers are pretty much the same, very light. The only thing I do that requires any thought is the user interface design... All that to say unit tests don't really fit within my day to day activities. By the time I'm done story boarding an application and planning my models, within an hour I have 75% of my work done.
    Creativity knows no other restraint than the
    confines of a small mind.
    - Me
    Geekly Humor
    Oh baby! Check out the design patterns on that framework!

  5. #30
    From space with love silver trophy
    SpacePhoenix's Avatar
    Join Date
    May 2007
    Location
    Poole, UK
    Posts
    5,068
    Mentioned
    103 Post(s)
    Tagged
    0 Thread(s)
    I normally test bits of code as I go, 9 out of 10 times the errors are parse errors where I've forgot a ; or a } Any errors I get with a query, i echo it out and then run the query against the db in phpmyadmin. Most of the errors that I make are in my controller classes.
    Community Team Advisor
    Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
    Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator

  6. #31
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    I too have a few issues with unit testing, and after reading this thread, I still do.

    My issues mainly center around testing interfaces using mock objects. I just don't see the point. If something goes wrong, the only thing it tells me is that there is something wrong with the test code itself. It tells me nothing about the app.

    Testing against real objects, using dependancy injection to affect which database, or set of data, the object will be using, makes perfect sense, however.

    To be honest, if your design on paper is sound, and your interfaces reflect that, then you shouldn't have many actual errors to begin with. Finding a scenario where you need to refactor based on new information is another thing altogether, but can be found early with testing against real objects.

    Can somebody please explain a real tangible benefit of testing against mocks?

  7. #32
    SitePoint Guru
    Join Date
    Jan 2005
    Location
    heaven
    Posts
    953
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Serenarules View Post
    I too have a few issues with unit testing, and after reading this thread, I still do.

    My issues mainly center around testing interfaces using mock objects. I just don't see the point. If something goes wrong, the only thing it tells me is that there is something wrong with the test code itself. It tells me nothing about the app.

    Testing against real objects, using dependancy injection to affect which database, or set of data, the object will be using, makes perfect sense, however.

    To be honest, if your design on paper is sound, and your interfaces reflect that, then you shouldn't have many actual errors to begin with. Finding a scenario where you need to refactor based on new information is another thing altogether, but can be found early with testing against real objects.

    Can somebody please explain a real tangible benefit of testing against mocks?
    One scenario where mock testing would be viable is with payment gateways. Rather than sending test data to payment gateway server, you create a mock object that with sample codes the payment gateway uses. That way you would actually be able to test a class without actually having to connect to the payment gateway to test your code.
    Creativity knows no other restraint than the
    confines of a small mind.
    - Me
    Geekly Humor
    Oh baby! Check out the design patterns on that framework!

  8. #33
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm sorry if I'm posting too much on this thread. Maybe others will want some
    other people to answer too. But here's my explanation and reason for using
    mocks in my tests.

    Recently I had to write a client to talk to a certain web service through the
    SOAP protocol. Although the job was pretty trivial, as I used NuSOAP to deal
    with the peculiarities of SOAP, I still had to build the request expected by
    NuSOAP, as well as transform the response from it. I basically decorated
    NuSOAP in order to provide a better API for my library.

    In order to test my library I had two options.

    1. Write code, upload to server via FTP (the web service imposed IP restrictions),
    then hit F5 in browser. Rinse. Repeat.
    2. Write unit/integration tests and mock the NuSOAP client so that I don't have
    to rely on a real server.

    By using the second option I didn't need an Internet connection in order to
    work, I had greater control over the response "received" by the mock soap
    client and I could actually "save" these responses in my code, so later on I
    don't have regression bugs.

    In the end, the code looked like this:

    PHP Code:
    class SpecificWebService
    {
        private 
    $soapClient;

        public function 
    __construct($soapClient)
        {
            
    $this->soapClient $soapClient;
        }

        public function 
    getProductDetails($productId)
        {
            
    // pre-processing
            
    $args $this->buildArgumentsExpectedBySoapClient($productId);

            
    // send request, get response
            
    $resp $this->soapClient->call('GetProductDetails'$args);

            
    // post-processing
            
    return $this->transformResponseReceivedFromSoapClient($resp);
        }

    PHP Code:
    class SpecificWebServiceTest extends PHPUnit_Framework_TestCase
    {
        public function 
    testGetProductDetails()
        {
            
    // $expectedArguments are the arguments the mock will expectd when
            // its call() method will be... called inside getProductDetails. More
            // exactly, we may test that the first argument is the string
            // 'GetProductDetails' and that the second argument contains a
            // product ID equal with 13. See below.
            //
            // $expectedResponse is the return value of the call() method. This
            // would be the "raw" response from the remote server, before doing
            // any processing on it.
            
    $this->mockSoapClient($expectedArguments$expectedResponse);

            
    // This is the response we expect from getProductDetails() after
            // processing the "raw" response returned by the SOAP client.
            
    $expect = array(
                
    'name'    => 'Wonder Cleaner',
                
    'company' => 'Acme',
            );

            
    $this->assertEquals($expect$wsClient->getProductDetails(13));
        }

    This is not to say that my SpecificWebService class didn't do anything. It does.
    It decorates NuSOAP. And I wanted to check that it decorated it the right way,
    i.e. the way NuSOAP expects it.

    Using mocks I can control all of the components under test save for one, the
    object that I really want to test. That's my reason for mocking. Isolate the
    library code just to the class/function that I want to test. The rest is known
    to me from my mocks, so I can start make assumptions if something goes
    wrong.

    In the example above, if the mock would receive an argument that does not
    conform to the interface I have declared for it, would yell at me and I'd know
    that my class is doing something wrong.

    You may actually want to mock for other reasons as well, say because the
    component you rely on is not ready yet. All you know is its interface.

    Hopefully I made myself clear, otherwise I'd be really grateful to hear any
    questions or comments on my pseudo-code above.
    I'm under construction | http://igstan.ro/

  9. #34
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    "...because the component you rely on is not ready yet."

    This I can understand. In my case however, I only write simple db apps with no real need for a true business object persisted in $_SESSION. Each operation is simple and a one-shot deal. I simply code unit tests against my finished repostories (using a test db connection passed in via D.I.). As long as it uses my predefined interface, I've effectively tested both at the same time. For my simple little apps, having less than 10 simple respositories with little more than CRUD ops, I'm not sure the "not ready yet" argument is really all that relavent.

  10. #35
    SitePoint Member
    Join Date
    Sep 2009
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I can see benefits of unit testing in some areas of programming, but its usefulness for web development seem largely exaggerated.

    In an average web app, like a blog or a forum, most of the effort goes to write templates, user-side logic (page flow, form fields, etc.) and DB API. That's true even if you don't use MVC, and that's even more true if you do. How do you unit test that? To make a unit test, you need to isolate a unit first. Moreover, its methods must produce either an easily detectable state change or output a data structure that is computer-readable.

    I don't see any way to make unit tests for templates. Templates produce output for browsers and users, not for other APIs.

    Models may seem unit testable, but in PHP apps most of their logic usually interacts with the database. They aren't real units, because the important data they produce are SQL queries. The only reliable way to test SQL is with more SQL. You could write a test that performs some operations on a model, and then runs a query that checks that the changes to the database were what they needed to be. But that's not longer a real unit test.

    Controllers? Even worse. The end result of their work is a bunch of API calls, which eventually get data written to DB, templates rendered for the user, and so on.

    Stuff like Watir seems way more practical in such context. An interesting approach might be a comprehensive functionality-based test. You script all the actions the user might take, but check the intermediate results too. E.g. you script article creation, then check that the article is really in the database, then script viewing the article and check for some serious bugs, etc. But that's not unit testing, and I don't know a package that actually aims doing something like that.

  11. #36
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    I tend to agree with the above poster. I'd much rather forget the TDD practice, and use traditional post-development QA test cases to see if things works right. If the app is an OOP app, then refactoring should still be just as easy should a problem occur.

  12. #37
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Gambler Z View Post
    How do you unit test that? To make a unit test, you need to isolate a unit first. Moreover, its methods must produce either an easily detectable state change or output a data structure that is computer-readable.
    That's one of the central points of unit testing. Having to determine a unit of
    test brings up a better design. But I reckon that it's very hard to unit test
    applications developed based on existing frameworks.

    Quote Originally Posted by Gambler Z View Post
    I don't see any way to make unit tests for templates. Templates produce output for browsers and users, not for other APIs.
    Of course, templates by themselves don't have behavior. You could test the
    template renderer component to see that its output corresponds to what you
    intended to output. Feed it some context data and a template string and
    check the output conforms to what you expect.

    Quote Originally Posted by Gambler Z View Post
    You could write a test that performs some operations on a model, and then runs a query that checks that the changes to the database were what they needed to be. But that's not longer a real unit test.
    True. No longer a unit test, but it's still better than having to click around
    on the web site, write something in text fields, click submit, then check for
    data correctness and consistency. Also, this is better than using Watir
    because it's reducing the system under test to a couple of components.
    It's true that it's not a real unit test, but I treat the database as the fixture.
    I have total control of what data the database holds and I can easily add
    new entries on a per bug basis. I've done that using PHPUnit and it's actually
    not that bad (if someone is interested I could post some of my code).

    The thing is that I have some automated tester that check my work "at the
    click of a button".

    Quote Originally Posted by Gambler Z View Post
    Controllers? Even worse. The end result of their work is a bunch of API calls, which eventually get data written to DB, templates rendered for the user, and so on.
    True, a good controller should do little, and if it's extensible enough you can
    mock out the models and see that the integration between the controller
    and view works OK (integration tests are useful too). You may test proper
    HTTP headers are sent, test that certain GET, POST params are rejected, etc.
    But the controller must be open for extension, which is a nice side-effect of
    testing first.

    Quote Originally Posted by Gambler Z View Post
    Stuff like Watir seems way more practical in such context. An interesting approach might be a comprehensive functionality-based test. You script all the actions the user might take, but check the intermediate results too. E.g. you script article creation, then check that the article is really in the database, then script viewing the article and check for some serious bugs, etc. But that's not unit testing, and I don't know a package that actually aims doing something like that.
    I've done that too using WatiN. The application (written by me by the way),
    was pretty untestable as units, so I took WatiN and did exactly what you said.
    I opened a form page, input some text, save, then enter the page displaying
    the entry and check that it was what I actually entered. The setUp() method
    called a MySQL procedure which was inserting fixture data in a test database.
    The tearDown() method called another MySQL procedure which truncated all
    tables in the test database. This worked great too, but I still prefer finer
    grained tests, be them unit tests or not. Opening Firefox for every test is not
    that nice. It actually crashes pretty often and you get failing tests.

    Quote Originally Posted by Serenarules View Post
    I tend to agree with the above poster. I'd much rather forget the TDD practice, and use traditional post-development QA test cases to see if things works right.
    I understand that TDD may not be the way to go. But, as I said, I much rather
    have some kind of automated tests at a finer grained level, even if they talk to
    the database.

    Quote Originally Posted by Serenarules View Post
    If the app is an OOP app, then refactoring should still be just as easy should a problem occur.
    I find that I come up with better designs when doing TDD. So don't look at
    testing just for its merit in checking for correct functionality, look at it for its
    merits as a design tool too.
    I'm under construction | http://igstan.ro/

  13. #38
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    I find that I come up with better designs when doing TDD. So don't look at
    testing just for its merit in checking for correct functionality, look at it for its
    merits as a design tool too.
    I guess this is the part I really don't understand. Maybe I'm limited in my ability to forsee problems ahead, based on a test result. Maybe it's something else. Take the scenrio below:

    $fooRepository = new FooRepository(new FooConnection($hostname, $username, $password, $database));

    $expected = "42";
    $actual = $fooRepository->GetIDFromName("Adams");

    if ($expected !== $actual) { // fail test } else { // pass test }

    Ok, let's say the db has this record where id = 42 and name = "Adams". If the test fails, what does this tell me? That the code in GetIDFromName is bad? Or that the code in the db access layer is bad?

    What if it passed? Does it really mean things are working as intended? Or does it simply mean that I haven't yet found a reason to refactor it based on additional needs revealed later?

    It would seem to me that testing should be done nearer the end of the development cycle as things should be more concrete by then, and our data needs more solid. Of course, if the design (on paper) phase is done right, you should know before you ever code how things fit together.

    Can anybody possibly elaborate on my sample above and tell me what more the results should be telling me than what they are?

  14. #39
    SitePoint Member
    Join Date
    Dec 2008
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Amenthes
    I've done that too using WatiN.[...]This worked great too, but I still prefer finer grained tests, be them unit tests or not.
    Design by Contract would be a great way to achieve fine grained results from high level tests. Unfortunately, that's one of those paradigms that are difficult to implement without language level support. I wish PHP developers considered adding it to the language.

    I'm thinking about a way to replace real classes with wrappers that perform precondition, postcondition and invariant checks, but can't immediately see any way to achieve that that short of using tokenizer in __autoload.
    Caffeine Web Framework - reinventing the wheel since 2004.
    MicroWSS - simple SOAP web services server in Java.

  15. #40
    SitePoint Addict fattyjules's Avatar
    Join Date
    Dec 2005
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Serenarules View Post
    (snip) Take the scenrio below:

    $fooRepository = new FooRepository(new FooConnection($hostname, $username, $password, $database));

    $expected = "42";
    $actual = $fooRepository->GetIDFromName("Adams");

    if ($expected !== $actual) { // fail test } else { // pass test }

    Ok, let's say the db has this record where id = 42 and name = "Adams". If the test fails, what does this tell me? That the code in GetIDFromName is bad? Or that the code in the db access layer is bad?
    (snip)
    Are you running the test against mock data that you have created yourself? The unit test's job isn't to check data - it's to check the code. So I'd write some tests that do the following;

    - call GetIDFromName() with a name that DOES NOT exist in the mock database
    - call GetIDFromName() with an invalid value, like an INT or NULL
    - call GetIDFromName() with a name that exists MORE THAN ONCE in the mock data
    - call GetIDFromName('adams') when you know 'Adams' exists in the mock data (how does it handle case sensitivity)
    - call GetIDFromName('van der Plonk'), make sure it handles spaces ok

    Having said all that, don't waste buckets of time writing tests for very simple methods. You'll end up devoting more time to tests than the actual product.

  16. #41
    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 Gambler Z View Post
    I can see benefits of unit testing in some areas of programming, but its usefulness for web development seem largely exaggerated.
    What if the site accepts cc payments? If you have the smallest error - anywhere, not just in the checkout process - how will that affect potential customers' willingness to trust you with their credit card details?

    If the error is in the checkout, how will that affect your client's willingness to keep you in your job?

    Even simple sites rely on some kind of logic and all logic needs to be tested. You will make mistakes, I think - but if you can say that you've never had to debug a single line of code, ever, in all your programming career, then OK: don't test.

    Either you can test your website formally, by capturing all client requirements as acceptance tests, and then writing unit tests to verify the component parts, or you can leave it up to your site visitors to test and (maybe) email you if something isn't working. Which is the more professional way to work?

    Joel from joel on software may be great at many things. He is dead wrong on testing. In fact, I detect a note of rabble-rousing, anti-intellectual bigotry which could be hugely damaging to anyone trying to learn about a very important technique.

    Quote Originally Posted by Gambler Z View Post
    I don't see any way to make unit tests for templates. Templates produce output for browsers and users, not for other APIs.
    You can test browser output with SimpleTest's web tester. Not unit testing, OK, but that's where it would be verified along with everything else which creates the page.

    Quote Originally Posted by Gambler Z View Post
    Models may seem unit testable, but in PHP apps most of their logic usually interacts with the database. They aren't real units, because the important data they produce are SQL queries. The only reliable way to test SQL is with more SQL. You could write a test that performs some operations on a model, and then runs a query that checks that the changes to the database were what they needed to be. But that's not longer a real unit test.
    Actually I would view these as unit tests *and* as integration tests. They do test units of behaviour, it's just that they need to interaact with an external resource to do it.

    Doesn't matter what they're called though, so long as they are being done. I always, always (unit?) test data access classes because they can be a rich source of bugs. Maybe you're better at sql than me but it usually takes me a couple of tries just to write an executable query. I also find that db schemas tend to change quite a lot early on in the development process while you're figuring out what you need to store. Unit tests are a godsend to tell you if you broke something.

    Storing/retrieving data is such a fundamental element of an app I couldn't imagine not testing it. Losing data could have catastrophic consequences, depending on what it is.

    Quote Originally Posted by Gambler Z View Post
    Controllers? Even worse. The end result of their work is a bunch of API calls, which eventually get data written to DB, templates rendered for the user, and so on.
    Aah not so. Controllers - which tend not to do anything themselves merely issue instructions to other objects which do - are perfect candidates for tests using mocks. Mock all the collaborators, and set your expectations.

    This is the essence of TDD. Testing isn't primarily about testing at all (although that too) but rather about design. You can start at the top, in the controller class test case, and work with objects which don't even exist yet (you just need a bare interface to mock). The controller test will describe a series of behaviours which should be implemented by the mocked classes when you come to write them.

    These in turn will throw up new objects to be mocked, and etc. Eventually, there's nothing left to mock. The app has just written itself while you were testing.

  17. #42
    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 Serenarules View Post
    Can somebody please explain a real tangible benefit of testing against mocks?
    You're checking that the tested class issues all the method calls which it should. The ways in which objects communicate is a vital element in the application logic.

    What if a record is saved to a db but an email which should be sent is not? An interaction test (mocks) will show that the call to $mailer is not being made.

    This is also used as a design tool. Suppose you haven't written the $mailer class yet. What should it be? Just imagine the simplest interface you can think of which gets the job done and describe that in the current test case (using mock expectations). Later, when you come to implement the class you mocked, you've got a clear description of what methods to write and how they should behave.

    It's a really nice way to work, top-down in lots of little steps. Little steps are much easier to work through than a giant design-everything-in-advance leap. At each step, you've got high confidence that each component does do what it's supposed to do. As Marcus said, it's almost like cheating.

    It's particularly good for a new domain where you don't quite know how to get from A to B. Just dive in and write the map as you go, pausing regularly to refactor.

  18. #43
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Serenarules View Post
    Ok, let's say the db has this record where id = 42 and name = "Adams". If the test fails, what does this tell me? That the code in GetIDFromName is bad? Or that the code in the db access layer is bad?
    In my opinion, it tells you that you're testing too many things at once. Normally,
    you'd separate some logic and mock it when testing, so that only a small part
    it's actually tested. The example you presented is however special in that is
    accessing a database. I don't mock databases because it's hard to set SQL
    expectations. You could use an ORM and mock that, but that's not really solving
    the problem.

    I would just use a test database with fixture data for testing a repository.
    Also, I'd separate "the code in GetIDFromName" in a separate method and write
    a unit test for that. Basically, the new method would receive as arguments the
    DB result. GetIDFromName would just query the database and pass the args
    along.

    Now, you can actually know what happend in your tests. If the newly extracted
    method does not do its job properly it will fail in both its unit test as well as the
    integration test with the DB. If the DB access layer isn't working properly, only
    its test will fail.

    This is known as test dependencies and the recently released PHPUnit 3.4 brought
    support for it.

    Quote Originally Posted by Serenarules View Post
    Or does it simply mean that I haven't yet found a reason to refactor it based on additional needs revealed later?
    Yes. You Aren't Gonna Need It.

    Quote Originally Posted by Serenarules View Post
    It would seem to me that testing should be done nearer the end of the development cycle as things should be more concrete by then, and our data needs more solid. Of course, if the design (on paper) phase is done right, you should know before you ever code how things fit together.
    How about combining design phase with coding phase and testing phase? But
    mixing them in little chunks and doing it in tiny increments. Maybe you would
    like Extreme Programming.

    I want to add a note about mocks. They should not be abused. If mocks try to
    verify too much, they'll be to tied to the actual implementation of the system
    under test and refactoring will become harder. I don't know where the balance
    lies though, but one must be careful about that.
    I'm under construction | http://igstan.ro/

  19. #44
    SitePoint Guru
    Join Date
    Sep 2004
    Location
    NY, USA
    Posts
    712
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by webaddictz View Post
    When you're accustomed to unit testing, in a fashion that you write the tests before you start writing your code, which is also known as Test Driven Design, you'll notice that that actually happens. The tests will start driving your design. Because you're using the interface before it's even written, you'll only ever write the code that you actually need, instead of writing code that you think it could be necessary to write. Besides, it'll make for a more pragmatic API. Start using it, and you'll start loving it. Promise.
    Quote Originally Posted by lastcraft View Post
    Really though, you have to try it. It makes coding so easy, it feels like cheating.

    yours, Marcus
    I read comments like this from people who obviously know their stuff... and I want to get into TDD... but every time I've tried to dabble in... I quickly start feeling like it's a whole LOT of extra work and just not worth my time. I just can't get over the hump of it all mentally. I wish I could --- IF it would indeed make my life easier. But I've never done any unit testing to this day. (I work in .NET and PHP mainly, nearly 10 years in the field).

    It seems to me if you are diligent in your design about exception/error handling, type checking, logical result validation etc. etc. - then your code is basically testing itself all the time, no? Sure you'll have bugs, but they'll be easier to pinpoint. I am definitely no genius - just an average guy - but I've never stayed up till 4AM trying to find a bug either. Detailed error messages get me close enough. (And yes I've worked on some humungous applications with monster object models).

    My remarks might sound ignorant or un-enlightened to you established TDD folks... but I have just never been able to see the measurable value of it all. (and I LOVE stuff that makes my job faster and easier - that's why I have tried to get into TDD a few times - to no avail.)

  20. #45
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cringer View Post
    ... but I have just never been able to see the measurable value of it all.
    I think this poster hit on something I've been trying to put into words for some time. And I think it's something that's been skirted around in this thread as well, though nobody's actually stated it. Well, here it is:

    Unit Testing and Test Driven Design are two completely diferent things!

    While it's true the latter uses the former, using the former doesn't imply the latter. Personally, like the above poster, I get more "measurable" benefit from testing a unit after I've done my object design and stubbing things out than I do when all I have is an interface, or even just an idea.

    It might be different if there were a tool (that I felt comfortable using) that would actually move test code from "fakes" into a real concrete class for me once a unit passes it's tests. That would be a real measurable gain. As it stands, there isn't.

  21. #46
    SitePoint Member
    Join Date
    Apr 2005
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Definitely worth the effort, its an investment which starts paying in long-term. However, implementation varies from person to person. For eg: We're a custom web development company, who does like 1-2 project every month. Our reusable libraries are all test-covered but we dont do app-specific tests because that is not worth the effort.

    So if there's a code you're using again and again from ages, its good to create tests for them.

  22. #47
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Serenarules View Post
    It might be different if there were a tool (that I felt comfortable using) that would actually move test code from "fakes" into a real concrete class for me once a unit passes it's tests. That would be a real measurable gain. As it stands, there isn't.
    Then maybe you haven't looked in the right places.


    Quote Originally Posted by gigapromoters View Post
    So if there's a code you're using again and again from ages, its good to create tests for them.
    It's not so much about using the code again and again, as it is about testing the code again and again. From my point of view, you will test the code everytime you use it if you don't unit test. I can understand the notion of Unit testing being more beneficiary on code that's being reused than code that is used once, but I'd say writing a Unit Test once and running it a lot of times is faster than your assumed usual testing (alt-tab, F5, see if it works?).

    I'd say there is measurable gain, it's just that no-one has actually measured it.
    Yes, I blog, too.

  23. #48
    SitePoint Guru
    Join Date
    Sep 2004
    Location
    NY, USA
    Posts
    712
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by webaddictz View Post
    I'd say there is measurable gain, it's just that no-one has actually measured it.
    I have to wonder why not.

  24. #49
    SitePoint Enthusiast
    Join Date
    Sep 2009
    Posts
    45
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cringer View Post
    I have to wonder why not.
    Because the only way to measure the true cost of a project is from the inception to the death. Even getting to the first release milestone is a pretty useless metric as it does not take into account the Technical Debt accrued( http://martinfowler.com/bliki/TechnicalDebt.html ) that impacts all other changes, often after the original developers have gone skipping over the hill into the sunset. The Design Stamina Hypothesis http://martinfowler.com/bliki/Design...ypothesis.html is interesting reading if you work on projects that have had a lifecycle of years or are working on a project that will be around for years/maybe decades. Useful projects don't usually die even if we eventually wish it.

    I personally come from the school of thought that you always leave any bit of code better than it was. If I come across a piece of code that causes confusion ( eg. badly named variables/ methods, high cyclomatic complexity eg. arrow anti pattern http://www.codinghorror.com/blog/archives/000486.html etc.) then it gets surgically renamed or refactored to Composed Method ( http://codebetter.com/blogs/jeremy.m...d-Pattern.aspx - the top example is minor arrow head ) etc. I do pair programming so it is always a joint decision so I cannot refactor on a whim. Sometimes though my pair would have to fight to stop me, or it would be over by the time they finished trying. Working in a team you must be willing to research/read heavily and know how to fight from a calculated viewpoint, thankfully if those senior than you are on the same page it is not that hard as it is just rectifying misunderstanding/over zealous adherance to things they have said. As I am in an XP environment I just arm myself with Martin Fowler/Robert C. Martin as reference which with Kent Beck are our 'poster boys'. There is always room for improvement of future code and also improvement of old code as better techniques are found. That is where the courage thing in XP comes in http://www.umsl.edu/~sauterv/analysis/xp/tsld029.htm.

    Even before I went into an agile/XP environment I believed no code was holy, bad code deserves to die however 'important' it might be. Bad code often becomes important due to the complexity caused by bad design/uncontrolled change that makes people fear changing it. Stuff gets added, eventually it is one freaky big ball of mud. The holy ball of mud that sacrifices of developers eyes must always be made to it as management have decreed that no large scale changes can be made.

    I have met quite a few developers who have no inclination to refactor, or just don't see the visibile need as they wrote it and understanding your own code is always easier. It is hard enough to get developers who have good enough people skills to drill down to what is needed and not wanted. They are two different things and a misunderstanding of those things leads to projects that tick the boxes but leave clients unhappy/are effectively useless.

    The ability to refactor( and spotting the need ) is as much as an art as testing and coding. A lot of people would break stuff doing it as it requires clinical precision. Far more precision than writing most new code.

    Unit testing allows change to happen in a safety harness. The harness is never perfect, but when a hole is found by a bug the bug can be strangled in a test then fixed. The chance of the bug reappearing is reduced to nearly nil and the current development stream can be focussed on. The whole time thing has to take into account interruptions caused by bug fixing that ruin project estimations and personal workflow. The older/bigger the project the more likely the bugs are deep and hidden with code built on top of them ready to cascade in error if it is ever fixed. You would be surprised by how much code is written on assumption, bad assumption at that.

    A lot of errors come from not understanding the problem and the flaws in human to developer conversion. If conversing with yourself it is very easy to only get syntax errors. If you are conversing with 1 customer, 1 customer representive, 1 project manager, 1 Tester and 1 business analyst then getting them all to agree and understand what will be built is harder( the project manager should do it but sometimes they need to be managed ). If something is built, however code perfect, and it does not perform the function that they all believe is needed then it is an error. The tests also act as documentation of what was asked for in developer speak in case they try and bait and switch and place blame on the developers. The tests are the comments that should loudly when the function changes, killing comment drift.

    The code may take a day to write but getting them to agree may take 3-4 days of downed tools on that functionality. Regulators get rather touchy if you allow wrong sign off on 250,000 of expenses due to the possible allowance of fraud so best do nothing, do nothing do no harm. In that case the code which was flawed by design of the business rules passed human testing and it took the tests to prove it was flawed. I know as I wrote the business rules by best guess( the whole customer representive thing required in XP was elusive ).

    QA testing as it involves human clicking relies on the humans clicking to be perfect. An automated test is always 100% reproducible. If anything the testers complain they are bored as it usually works and nothing interesting is ever found. What was working stays working. Case studies are handled with a selenium service driving firefox in addition to the unit tests so human testers only have to test the new piece of functionality.

    Whether unit testing is useful to you as an individual by yourself or in a very small regimented team( every one group thinks at a very capable level, everyone makes an effort to improve etc. ) is harder to answer. Some things become clear that automated tests are needed due to the amount of jumps needed to replicate things manually. 10 minutes of clicking for every methodical change in the code to fix a problem becomes very boring and can eat half a day. Pressing a button and waiting 40 seconds or so is much more manageable.

    Implementing unit testing is as much a management decision as a developer one, they have to get on board and be willing to defend it. They have to realise that one day no developer may be willing to work on thats code base except the truly job desperate heeding to the fastening doom of that project.

    PHP is entering a new age where it is getting respect as a language from those who have a more formalised background( plus the Java people are too busy fighting the Ruby people ). PHP used to be very heavily lambasted as the language of the script kiddy. I personally like it
    because the community is not arrogant( a bit terse sometimes but no-one replies noob read the javadoc ) and with a bit of care elegance can be created.
    The fact that questions such as unit testing/ what is good design come up shows a healthy growing maturity.

    With this respect though comes greater responsibility as larger projects are entrusted with it. By larger I don't just mean lines of code( a pretty worthless measurement ) but ones that help generate large revenue and are business critical. They may be the new cobal systems that they will have to hire PHP developers for 20+ years for. I have no crystal ball. With good tests working on that system will be as easy as it is today, the tests hold the knowledge. At this point it is useful to look outside of the PHP world and look at the problems that have been faced by developers for decades and not repeat their mistakes. Learn from what they have learned, use good common approaches that have been created and are applicable, time is short. I would go as far to say it is disrespectful not to. Disrespectful to our coding elders and to those who will work on that code in the future. Writing software is never about how you get on with your stuff, but how others get on with yours and how you get on with theirs. It is a community effort.

    Good software can be written without tests. But we just see the outside most of the time so we can not really measure the quality. There are a lot of horror stories out there so I assume quality is not that easy to get and hold onto. The more people working on a project the harder.

    What is a well written test is a whole other ball game.

    Robert C Martin's follow up to joel is here
    http://blog.objectmentor.com/article...ape-programmer

    I might seem a bit of an agile/TDD fan boy but a lot of dire code cannot be tested due to it's complexity so forcing TDD thus killing the inception of that code in my book is a good thing. To those who do not test and do consistent quality over many years on a project, I believe you can do it. I'd think you were possibly naive to believe any more than 10% of developers can do it. I actually believe the honing required comes at a detriment to other parts of the personality( I personally edge case everything making me a bit crazy sometimes stuck between two points ) and not everyone is willing to pay that psychological price. They are too sensible.

    Anyway this is the third time I have tried not to write a novella and could keep going on and on and on . 4 damn hours.

  25. #50
    Resident OCD goofball! bronze trophy Serenarules's Avatar
    Join Date
    Dec 2002
    Posts
    1,911
    Mentioned
    26 Post(s)
    Tagged
    0 Thread(s)
    webaddictz, I no longer use php. I moved to .NET in Jan 2009.

    To continue this discussion though, what nobody has proven to me at any point, is exactly what unit testing proves, what the evidence is, and how to apply it to fixing a problem.

    It may simply be that my understanding of a unit test, and how they should be used is faulty. In my reading, it would seem that the proper way is to write the tests first, then add code a bit at a time, so that the tests pass one by one.

    The thing is, when you're done, you aren't really done! Now you have to actually copy your mocks to a real class file and alter the code so that it uses live data. Ok, so now we have a different code base. One whose stability and accuracy isn't reflected in the prior tests.

    So I haven't really done anything except waste a bunch of time. If the spec calls for a class called Foo that exposes a method called Bar that takes one arg of type string named input, then write the interface, implement it, THEN test it against a test database.

    That makes more sense to me, but apparently I'm wrong accoring to the community. Please help me understand the difference and why one method is better than the other.


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
  •