Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Architecting a testing framework for an API

by mp (Deacon)
on Mar 23, 2006 at 01:24 UTC ( [id://538638]=perlquestion: print w/replies, xml ) Need Help??

mp has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a set of modules that will function as sort of a data access API (mostly reading/writing data in an sql database) that will be used by other (yet-to-be-written) modules that will be developed to add capability to a web application that runs under mod_perl.

I am trying to come up with a way to build a framework that will let developers code and unit test their yet-to-be-written modules to extend the web application without having to use the actual API code (except for integration testing) and without apache/mod_perl.

I've written quite a few perl tests before and am familiar with and have used Test::MockObject, Test::MockModule, Test::More, etc., but thing I'm having a hard time trying to figure out is at a high level, how to structure this test framework in such a way that there's not a bunch of code duplication. I've used Test::Class a little, and maybe it is a good approach and I'm just not "getting it" enough yet.

One approach I've thought of doing is to write mock versions of all the API libraries that provide some means for controlling the return values and that don't do any real database access. Then, the test code would 'use' these rather than the real API modules, but this doesn't really feel like the best approach because there are too many unknowns at this point.

Are there any other good approaches to these sort of test frameworks? Any pointers to reading material or even what to search for on Google would be appreciated. I do have a copy of O'reilly's Perl Testing, which has been helpful.

  • Comment on Architecting a testing framework for an API

Replies are listed 'Best First'.
Re: Architecting a testing framework for an API
by Old_Gray_Bear (Bishop) on Mar 23, 2006 at 02:41 UTC
    mp said:
    >> One approach I've thought of doing is to write mock
    >> versions of all the API libraries that provide some means
    >> for controlling the return values and that don't do any
    >> real database access. Then, the test code would 'use'
    >> these rather than the real API modules, but this doesn't
    >> really feel like the best approach because there are too
    >> many unknowns at this point.
    
    Actually, that's not all that bad an idea. Mocking up the entire API and play-testing it with the User community will help shake out the quirks early on. ("Ninety precent of the time we call api_open() followed by api_read_next(). Can we get things revamped so that the usual behavior of api_open() to return the first record, unless "no-read => '1' " is passed in the call?")

    Developing a useful and friendly API is a real art. The earlier you can involve your User Community, the better your chances of ending up with somthing that they will use. Also, getting something out-there for then to play with begins setting up mind-share. Play-testing breeds a level of comfort -- "this is how it's going to work; it's not all there yet, but here is what I can expect to see when I do this call." And, Folks are much less prone to adding the tag "vapor-ware" to your work-in-progress if you really do have something out there for them to poke at.

    ----
    I Go Back to Sleep, Now.

    OGB

Re: Architecting a testing framework for an API
by chromatic (Archbishop) on Mar 23, 2006 at 06:47 UTC

    I think Test::Class is the way to go, if you expect people to use your code as the base for their code. If you do this, consider distributing your test modules along with the other modules.

    The only other thing I can recommend, without seeing code or design questions, is to consider not hard-coding the names of classes used by other classes. That is, for the purposes of testing, it should be really easy for me to use Test::MockObject::Extends to wrap one of your classes to override the one or two methods that use the database or access the network, or do something else beyond what I want to test.

      Good point on making class names overrideable. I will take a closer look at Test::MockObject::Extends.

      I also worked through the Queue / Test::Class example in your book. That was very instructive.

Re: Architecting a testing framework for an API
by adrianh (Chancellor) on Mar 23, 2006 at 10:19 UTC
    I'm writing a set of modules that will function as sort of a data access API (mostly reading/writing data in an sql database) that will be used by other (yet-to-be-written) modules that will be developed to add capability to a web application that runs under mod_perl.

    As a separate point I generally find it far more effective to develop an API after the modules that need it rather than before. Instead of an educated guess about how it should behave you get concrete examples.

    Have you considered starting with developing the modules and then factoring out the data layer API once you see the duplication that necessitates it?

      Good advice. Thanks.
Re: Architecting a testing framework for an API
by adrianh (Chancellor) on Mar 23, 2006 at 10:09 UTC
    I am trying to come up with a way to build a framework that will let developers code and unit test their yet-to-be-written modules to extend the web application without having to use the actual API code (except for integration testing) and without apache/mod_perl.

    That sounds like you want mocks/fakes/stubs here. Take a look at some of the Test Double patterns.

    I'm having a hard time trying to figure out is at a high level, how to structure this test framework in such a way that there's not a bunch of code duplication.

    Can you give examples of the kind of duplication that you're getting? What's stopping you factoring it out?

      Thank you for the link. The Patterns of xUnit Test Automation site is very helpful in thinking about all of this and is not a site I had seen before.

      I don't have a lot of duplication yet, since this project is still in the early stages of development, but I am expecting there to be quite a bit of "test fixture setup" that is repeated from one test to the next (mainly setup of mock objects or subroutine overrides), possibly with variations in the setup data between tests. I think you're right, though, this will be something that can be factored out.

        I am expecting there to be quite a bit of "test fixture setup" that is repeated from one test to the next (mainly setup of mock objects or subroutine overrides), possibly with variations in the setup data between tests.

        Ah. Then this is stuff that Test::Class can help with. You can stick all your repeated fixture setup in a (wittily named) :setup method. You can specialise fixtures with subclassing. That said - wait until you get the duplication before you factor it out would be my advice.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://538638]
Approved by Moriarty
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2024-04-26 01:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found