"Fossies" - the Fresh Open Source Software Archive

Member "phpbibliography-1.1.1/vendors/simpletest/docs/en/index.html" (22 Dec 2009, 23768 Bytes) of archive /linux/www/phpbibliography-1.1.1.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) HTML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 <html>
    2 <head>
    3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    4 <title>
    5         Download the Simple Test testing framework -
    6         Unit tests and mock objects for PHP
    7     </title>
    8 <link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
    9 </head>
   10 <body>
   11 <div class="menu_back"><div class="menu">
   12 <span class="chosen">SimpleTest</span>
   13                 |
   14                 <a href="overview.html">Overview</a>
   15                 |
   16                 <a href="unit_test_documentation.html">Unit tester</a>
   17                 |
   18                 <a href="group_test_documentation.html">Group tests</a>
   19                 |
   20                 <a href="mock_objects_documentation.html">Mock objects</a>
   21                 |
   22                 <a href="partial_mocks_documentation.html">Partial mocks</a>
   23                 |
   24                 <a href="reporter_documentation.html">Reporting</a>
   25                 |
   26                 <a href="expectation_documentation.html">Expectations</a>
   27                 |
   28                 <a href="web_tester_documentation.html">Web tester</a>
   29                 |
   30                 <a href="form_testing_documentation.html">Testing forms</a>
   31                 |
   32                 <a href="authentication_documentation.html">Authentication</a>
   33                 |
   34                 <a href="browser_documentation.html">Scriptable browser</a>
   35 </div></div>
   36 <h1>Simple Test for PHP</h1>
   37         This page...
   38         <ul>
   39 <li>
   40             <a href="#unit">Using unit tester</a>
   41             with an example.
   42         </li>
   43 <li>
   44             <a href="#group">Grouping tests</a>
   45             for testing with one click.
   46         </li>
   47 <li>
   48             <a href="#mock">Using mock objects</a>
   49             to ease testing and gain tighter control.
   50         </li>
   51 <li>
   52             <a href="#web">Testing web pages</a>
   53             at the browser level.
   54         </li>
   55 </ul>
   56 <div class="content">
   57         
   58         
   59             <p>
   60                 The following assumes that you are familiar with the concept
   61                 of unit testing as well as the PHP web development language.
   62                 It is a guide for the impatient new user of
   63                 <a href="https://sourceforge.net/project/showfiles.php?group_id=76550">SimpleTest</a>.
   64                 For fuller documentation, especially if you are new
   65                 to unit testing see the ongoing
   66                 <a href="unit_test_documentation.html">documentation</a>, and for
   67                 example test cases see the
   68                 <a href="http://www.lastcraft.com/first_test_tutorial.php">unit testing tutorial</a>.
   69             </p>
   70         
   71         <p><a class="target" name="unit"><h2>Using the tester quickly</h2></a></p>
   72             <p>
   73                 Amongst software testing tools, a unit tester is the one
   74                 closest to the developer.
   75                 In the context of agile development the test code sits right
   76                 next to the source code as both are written simultaneously.
   77                 In this context SimpleTest aims to be a complete PHP developer
   78                 test solution and is called "Simple" because it
   79                 should be easy to use and extend.
   80                 It wasn't a good choice of name really.
   81                 It includes all of the typical functions you would expect from
   82                 <a href="http://www.junit.org/">JUnit</a> and the
   83                 <a href="http://sourceforge.net/projects/phpunit/">PHPUnit</a>
   84                 ports, and includes
   85                 <a href="http://www.mockobjects.com">mock objects</a>.
   86             </p>
   87             <p>
   88                 What makes this tool immediately useful to the PHP developer is the internal
   89                 web browser.
   90                 This allows tests that navigate web sites, fill in forms and test pages.
   91                 Being able to write these test in PHP means that it is easy to write
   92                 integrated tests.
   93                 An example might be confirming that a user was written to a database
   94                 after a signing up through the web site.
   95             </p>
   96             <p>
   97                 The quickest way to demonstrate SimpleTest is with an example.
   98             </p>
   99             <p>
  100                 Let us suppose we are testing a simple file logging class called
  101                 <span class="new_code">Log</span> in <em>classes/log.php</em>.
  102                 We start by creating a test script which we will call
  103                 <em>tests/log_test.php</em> and populate it as follows...
  104 <pre>
  105 &lt;?php
  106 <strong>require_once('simpletest/autorun.php');</strong>
  107 require_once('../classes/log.php');
  108 
  109 class TestOfLogging extends <strong>UnitTestCase</strong> {
  110 }
  111 ?&gt;
  112 </pre>
  113                 Here the <em>simpletest</em> folder is either local or in the path.
  114                 You would have to edit these locations depending on where you
  115                 unpacked the toolset.
  116                 The "autorun.php" file does more than just include the
  117                 SimpleTest files, it also runs our test for us.
  118             </p>
  119             <p>
  120                 The <span class="new_code">TestOfLogging</span> is our first test case and it's
  121                 currently empty.
  122                 Each test case is a class that extends one of the SimpleTet base classes
  123                 and we can have as many of these in the file as we want.
  124             </p>
  125             <p>
  126                 With three lines of scaffolding, and our <span class="new_code">Log</span> class
  127                 include, we have a test suite.
  128                 No tests though.
  129             </p>
  130             <p>
  131                 For our first test, we'll assume that the <span class="new_code">Log</span> class
  132                 takes the file name to write to in the constructor, and we have
  133                 a temporary folder in which to place this file...
  134 <pre>
  135 &lt;?php
  136 require_once('simpletest/autorun.php');
  137 require_once('../classes/log.php');
  138 
  139 class TestOfLogging extends UnitTestCase {
  140     function <strong>testLogCreatesNewFileOnFirstMessage()</strong> {
  141         @unlink('/temp/test.log');
  142         $log = new Log('/temp/test.log');
  143         <strong>$this-&gt;assertFalse(file_exists('/temp/test.log'));</strong>
  144         $log-&gt;message('Should write this to a file');
  145         <strong>$this-&gt;assertTrue(file_exists('/temp/test.log'));</strong>
  146     }
  147 }
  148 ?&gt;
  149 </pre>
  150                 When a test case runs, it will search for any method that
  151                 starts with the string "test"
  152                 and execute that method.
  153                 If the method starts "test", it's a test.
  154                 Note the very long name <span class="new_code">testLogCreatesNewFileOnFirstMessage()</span>.
  155                 This is considered good style and makes the test output more readable.
  156             </p>
  157             <p>
  158                 We would normally have more than one test method in a test case,
  159                 but that's for later.
  160             </p>
  161             <p>
  162                 Assertions within the test methods trigger messages to the
  163                 test framework which displays the result immediately.
  164                 This immediate response is important, not just in the event
  165                 of the code causing a crash, but also so that
  166                 <span class="new_code">print</span> statements can display
  167                 their debugging content right next to the assertion concerned.
  168             </p>
  169             <p>
  170                 To see these results we have to actually run the tests.
  171                 No other code is necessary - we can just open the page
  172                 with our browser.
  173             </p>
  174             <p>
  175                 On failure the display looks like this...
  176                 <div class="demo">
  177                     <h1>TestOfLogging</h1>
  178                     <span class="fail">Fail</span>: testLogCreatesNewFileOnFirstMessage-&gt;True assertion failed.<br>
  179                     <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
  180                     <strong>1</strong> passes and <strong>1</strong> fails.</div>
  181                 </div>
  182                 ...and if it passes like this...
  183                 <div class="demo">
  184                     <h1>TestOfLogging</h1>
  185                     <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
  186                     <strong>2</strong> passes and <strong>0</strong> fails.</div>
  187                 </div>
  188                 And if you get this...
  189                 <div class="demo">
  190                     <b>Fatal error</b>:  Failed opening required '../classes/log.php' (include_path='') in <b>/home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php</b> on line <b>7</b>
  191                 </div>
  192                 it means you're missing the <em>classes/Log.php</em> file that could look like...
  193 <pre>
  194 &lt;?php<strong>
  195 class Log {
  196     function Log($file_path) {
  197     }
  198 
  199     function message() {
  200     }
  201 }</strong>
  202 ?&gt;
  203 </pre>
  204                 It's fun to write the code after the test.
  205                 More than fun even -
  206                 this system is called "Test Driven Development".
  207             </p>
  208             <p>
  209                 For more information about <span class="new_code">UnitTestCase</span>, see
  210                 the <a href="unit_test_documentation.html">unit test documentation</a>.
  211             </p>
  212         
  213         <p><a class="target" name="group"><h2>Building test suites</h2></a></p>
  214             <p>
  215                 It is unlikely in a real application that we will only ever run
  216                 one test case.
  217                 This means that we need a way of grouping cases into a test
  218                 script that can, if need be, run every test for the application.
  219             </p>
  220             <p>
  221                 Our first step is to create a new file called <em>tests/all_tests.php</em>
  222                 and insert the following code...
  223 <pre>
  224 &lt;?php
  225 <strong>require_once('simpletest/autorun.php');</strong>
  226 
  227 class AllTests extends <strong>TestSuite</strong> {
  228     function AllTests() {
  229         $this-&gt;TestSuite(<strong>'All tests'</strong>);
  230         <strong>$this-&gt;addFile('log_test.php');</strong>
  231     }
  232 }
  233 ?&gt;
  234 </pre>
  235                 The "autorun" include allows our upcoming test suite
  236                 to be run just by invoking this script.
  237             </p>
  238             <p>
  239                 The <span class="new_code">TestSuite</span> subclass must chain it's constructor.
  240                 This limitation will be removed in future versions.
  241             </p>
  242             <p>
  243                 The method <span class="new_code">TestSuite::addFile()</span>
  244                 will include the test case file and read any new classes
  245                 that are descended from <span class="new_code">SimpleTestCase</span>.
  246                 <span class="new_code">UnitTestCase</span> is just one example of a class derived from
  247                 <span class="new_code">SimpleTestCase</span>, and you can create your own.
  248                 <span class="new_code">TestSuite::addFile()</span> can include other test suites.
  249             </p>
  250             <p>
  251                 The class will not be instantiated yet.
  252                 When the test suite runs it will construct each instance once
  253                 it reaches that test, then destroy it straight after.
  254                 This means that the constructor is run just before each run
  255                 of that test case, and the destructor is run before the next test case starts.
  256             </p>
  257             <p>
  258                 It is common to group test case code into superclasses which are not
  259                 supposed to run, but become the base classes of other tests.
  260                 For "autorun" to work properly the test case file should not blindly run
  261                 any other test case extensions that do not actually run tests.
  262                 This could result in extra test cases being counted during the test
  263                 run.
  264                 Hardly a major problem, but to avoid this inconvenience simply mark your
  265                 base class as <span class="new_code">abstract</span>.
  266                 SimpleTest won't run abstract classes.
  267                 If you are still using PHP4, then
  268                 a <span class="new_code">SimpleTestOptions::ignore()</span> directive
  269                 somewhere in the test case file will have the same effect.
  270             </p>
  271             <p>
  272                 Also, the test case file should not have been included
  273                 elsewhere or no cases will be added to this group test.
  274                 This would be a more serious error as if the test case classes are
  275                 already loaded by PHP the <span class="new_code">TestSuite::addFile()</span>
  276                 method will not detect them.
  277             </p>
  278             <p>
  279                 To display the results it is necessary only to invoke
  280                 <em>tests/all_tests.php</em> from the web server or the command line.
  281             </p>
  282             <p>
  283                 For more information about building test suites,
  284                 see the <a href="group_test_documentation.html">test suite documentation</a>.
  285             </p>
  286         
  287         <p><a class="target" name="mock"><h2>Using mock objects</h2></a></p>
  288             <p>
  289                 Let's move further into the future and do something really complicated.
  290             </p>
  291             <p>
  292                 Assume that our logging class is tested and completed.
  293                 Assume also that we are testing another class that is
  294                 required to write log messages, say a
  295                 <span class="new_code">SessionPool</span>.
  296                 We want to test a method that will probably end up looking
  297                 like this...
  298 <pre><strong>
  299 class SessionPool {
  300     ...
  301     function logIn($username) {
  302         ...
  303         $this-&gt;_log-&gt;message("User $username logged in.");
  304         ...
  305     }
  306     ...
  307 }
  308 </strong>
  309 </pre>
  310                 In the spirit of reuse, we are using our
  311                 <span class="new_code">Log</span> class.
  312                 A conventional test case might look like this...
  313 <pre>
  314 &lt;?php
  315 require_once('simpletest/autorun.php');
  316 require_once('../classes/log.php');
  317 <strong>require_once('../classes/session_pool.php');</strong>
  318 
  319 class <strong>TestOfSessionLogging</strong> extends UnitTestCase {
  320     
  321     function setUp() {
  322         <strong>@unlink('/temp/test.log');</strong>
  323     }
  324     
  325     function tearDown() {
  326         <strong>@unlink('/temp/test.log');</strong>
  327     }
  328     
  329     function testLoggingInIsLogged() {
  330         <strong>$log = new Log('/temp/test.log');
  331         $session_pool = &amp;new SessionPool($log);
  332         $session_pool-&gt;logIn('fred');</strong>
  333         $messages = file('/temp/test.log');
  334         $this-&gt;assertEqual($messages[0], "User fred logged in.<strong>\n</strong>");
  335     }
  336 }
  337 ?&gt;
  338 </pre>
  339                 We'll explain the <span class="new_code">setUp()</span> and <span class="new_code">tearDown()</span>
  340                 methods later.
  341             </p>
  342             <p>
  343                 This test case design is not all bad, but it could be improved.
  344                 We are spending time fiddling with log files which are
  345                 not part of our test.
  346                 We have created close ties with the <span class="new_code">Log</span> class and
  347                 this test.
  348                 What if we don't use files any more, but use ths
  349                 <em>syslog</em> library instead?
  350                 It means that our <span class="new_code">TestOfSessionLogging</span> test will
  351                 fail, even thouh it's not testing Logging.
  352             </p>
  353             <p>
  354                 It's fragile in smaller ways too.
  355                 Did you notice the extra carriage return in the message?
  356                 Was that added by the logger?
  357                 What if it also added a time stamp or other data?
  358             </p>
  359             <p>
  360                 The only part that we really want to test is that a particular
  361                 message was sent to the logger.
  362                 We can reduce coupling if we pass in a fake logging class
  363                 that simply records the message calls for testing, but
  364                 takes no action.
  365                 It would have to look exactly like our original though.
  366             </p>
  367             <p>
  368                 If the fake object doesn't write to a file then we save on deleting
  369                 the file before and after each test. We could save even more
  370                 test code if the fake object would kindly run the assertion for us.
  371             <p>
  372             </p>
  373                 Too good to be true?
  374                 We can create such an object easily...
  375 <pre>
  376 &lt;?php
  377 require_once('simpletest/autorun.php');
  378 require_once('../classes/log.php');
  379 require_once('../classes/session_pool.php');
  380 
  381 <strong>Mock::generate('Log');</strong>
  382 
  383 class TestOfSessionLogging extends UnitTestCase {
  384     
  385     function testLoggingInIsLogged() {<strong>
  386         $log = &amp;new MockLog();
  387         $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>
  388         $session_pool = &amp;new SessionPool(<strong>$log</strong>);
  389         $session_pool-&gt;logIn('fred');
  390     }
  391 }
  392 ?&gt;
  393 </pre>
  394                 The <span class="new_code">Mock::generate()</span> call code generated a new class
  395                 called <span class="new_code">MockLog</span>.
  396                 This looks like an identical clone, except that we can wire test code
  397                 to it.
  398                 That's what <span class="new_code">expectOnce()</span> does.
  399                 It says that if <span class="new_code">message()</span> is ever called on me, it had
  400                 better be with the parameter "User fred logged in.".
  401             </p>
  402             <p>
  403                 The test will be triggered when the call to
  404                 <span class="new_code">message()</span> is invoked on the
  405                 <span class="new_code">MockLog</span> object by <span class="new_code">SessionPool::logIn()</span> code.
  406                 The mock call will trigger a parameter comparison and then send the
  407                 resulting pass or fail event to the test display.
  408                 Wildcards can be included here too, so you don't have to test every parameter of
  409                 a call when you only want to test one.
  410             </p>
  411             <p>
  412                 If the mock reaches the end of the test case without the
  413                 method being called, the <span class="new_code">expectOnce()</span>
  414                 expectation will trigger a test failure.
  415                 In other words the mocks can detect the absence of
  416                 behaviour as well as the presence.
  417             </p>
  418             <p>
  419                 The mock objects in the SimpleTest suite can have arbitrary
  420                 return values set, sequences of returns, return values
  421                 selected according to the incoming arguments, sequences of
  422                 parameter expectations and limits on the number of times
  423                 a method is to be invoked.
  424             </p>
  425             <p>
  426                 For more information about mocking and stubbing, see the
  427                 <a href="mock_objects_documentation.html">mock objects documentation</a>.
  428             </p>
  429         
  430         <p><a class="target" name="web"><h2>Web page testing</h2></a></p>
  431             <p>
  432                 One of the requirements of web sites is that they produce web
  433                 pages.
  434                 If you are building a project top-down and you want to fully
  435                 integrate testing along the way then you will want a way of
  436                 automatically navigating a site and examining output for
  437                 correctness.
  438                 This is the job of a web tester.
  439             </p>
  440             <p>
  441                 The web testing in SimpleTest is fairly primitive, as there is
  442                 no JavaScript.
  443                 Most other browser operations are simulated.
  444             </p>
  445             <p>
  446                 To give an idea here is a trivial example where a home
  447                 page is fetched, from which we navigate to an "about"
  448                 page and then test some client determined content.
  449 <pre>
  450 &lt;?php
  451 require_once('simpletest/autorun.php');
  452 <strong>require_once('simpletest/web_tester.php');</strong>
  453 
  454 class TestOfAbout extends <strong>WebTestCase</strong> {
  455     function testOurAboutPageGivesFreeReignToOurEgo() {
  456         <strong>$this-&gt;get('http://test-server/index.php');
  457         $this-&gt;click('About');
  458         $this-&gt;assertTitle('About why we are so great');
  459         $this-&gt;assertText('We are really great');</strong>
  460     }
  461 }
  462 ?&gt;
  463 </pre>
  464                 With this code as an acceptance test, you can ensure that
  465                 the content always meets the specifications of both the
  466                 developers, and the other project stakeholders.
  467             </p>
  468             <p>
  469                 You can navigate forms too...
  470 <pre>
  471 &lt;?php
  472 require_once('simpletest/autorun.php');
  473 require_once('simpletest/web_tester.php');
  474 
  475 class TestOfRankings extends WebTestCase {
  476     function testWeAreTopOfGoogle() {
  477         $this-&gt;get('http://google.com/');
  478         $this-&gt;setField('q', 'simpletest');
  479         $this-&gt;click("I'm Feeling Lucky");
  480         $this-&gt;assertTitle('SimpleTest - Unit Testing for PHP');
  481     }
  482 }
  483 ?&gt;
  484 </pre>
  485                 ...although this could violate Google's(tm) terms and conditions.
  486             </p>
  487             <p>
  488                 For more information about web testing, see the
  489                 <a href="browser_documentation.html">scriptable
  490                 browser documentation</a> and the
  491                 <a href="web_tester_documentation.html">WebTestCase</a>.
  492             </p>
  493             <p>
  494                 <a href="http://sourceforge.net/projects/simpletest/"><img src="http://sourceforge.net/sflogo.php?group_id=76550&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></a>
  495             </p>
  496         
  497     </div>
  498         References and related information...
  499         <ul>
  500 <li>
  501             <a href="https://sourceforge.net/project/showfiles.php?group_id=76550&amp;release_id=153280">Download PHP Simple Test</a>
  502             from <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
  503         </li>
  504 <li>
  505             The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
  506             gives full detail on the classes and assertions available.
  507         </li>
  508 </ul>
  509 <div class="menu_back"><div class="menu">
  510 <span class="chosen">SimpleTest</span>
  511                 |
  512                 <a href="overview.html">Overview</a>
  513                 |
  514                 <a href="unit_test_documentation.html">Unit tester</a>
  515                 |
  516                 <a href="group_test_documentation.html">Group tests</a>
  517                 |
  518                 <a href="mock_objects_documentation.html">Mock objects</a>
  519                 |
  520                 <a href="partial_mocks_documentation.html">Partial mocks</a>
  521                 |
  522                 <a href="reporter_documentation.html">Reporting</a>
  523                 |
  524                 <a href="expectation_documentation.html">Expectations</a>
  525                 |
  526                 <a href="web_tester_documentation.html">Web tester</a>
  527                 |
  528                 <a href="form_testing_documentation.html">Testing forms</a>
  529                 |
  530                 <a href="authentication_documentation.html">Authentication</a>
  531                 |
  532                 <a href="browser_documentation.html">Scriptable browser</a>
  533 </div></div>
  534 <div class="copyright">
  535             Copyright<br>Marcus Baker 2006
  536         </div>
  537 </body>
  538 </html>