summaryrefslogtreecommitdiff
path: root/test_tools/simpletest/docs/en/index.html
diff options
context:
space:
mode:
authorwei <>2006-07-05 07:40:57 +0000
committerwei <>2006-07-05 07:40:57 +0000
commitdfa5aa5fbf11f89ce483c58016465ddc3921f082 (patch)
treef01dd1c13d700b266695e503b3ebb6e05e591410 /test_tools/simpletest/docs/en/index.html
parentb6dfb6c447cf502e694d299dbda1b2e092c3312d (diff)
move to tests
Diffstat (limited to 'test_tools/simpletest/docs/en/index.html')
-rwxr-xr-xtest_tools/simpletest/docs/en/index.html467
1 files changed, 0 insertions, 467 deletions
diff --git a/test_tools/simpletest/docs/en/index.html b/test_tools/simpletest/docs/en/index.html
deleted file mode 100755
index 04797272..00000000
--- a/test_tools/simpletest/docs/en/index.html
+++ /dev/null
@@ -1,467 +0,0 @@
-<html>
-<head>
-<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>
- Download the Simple Test testing framework -
- Unit tests and mock objects for PHP
- </title>
-<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
-</head>
-<body>
-<div class="menu_back">
-<div class="menu">
-<h2>
-<span class="chosen">SimpleTest</span>
-</h2>
-<ul>
-<li>
-<a href="overview.html">Overview</a>
-</li>
-<li>
-<a href="unit_test_documentation.html">Unit tester</a>
-</li>
-<li>
-<a href="group_test_documentation.html">Group tests</a>
-</li>
-<li>
-<a href="server_stubs_documentation.html">Server stubs</a>
-</li>
-<li>
-<a href="mock_objects_documentation.html">Mock objects</a>
-</li>
-<li>
-<a href="partial_mocks_documentation.html">Partial mocks</a>
-</li>
-<li>
-<a href="reporter_documentation.html">Reporting</a>
-</li>
-<li>
-<a href="expectation_documentation.html">Expectations</a>
-</li>
-<li>
-<a href="web_tester_documentation.html">Web tester</a>
-</li>
-<li>
-<a href="form_testing_documentation.html">Testing forms</a>
-</li>
-<li>
-<a href="authentication_documentation.html">Authentication</a>
-</li>
-<li>
-<a href="browser_documentation.html">Scriptable browser</a>
-</li>
-</ul>
-</div>
-</div>
-<h1>Simple Test for PHP</h1>
-<div class="content">
-
-
- <p>
- The following assumes that you are familiar with the concept
- of unit testing as well as the PHP web development language.
- It is a guide for the impatient new user of
- <a href="https://sourceforge.net/project/showfiles.php?group_id=76550">SimpleTest</a>.
- For fuller documentation, especially if you are new
- to unit testing see the ongoing
- <a href="unit_test_documentation.html">documentation</a>, and for
- example test cases see the
- <a href="http://www.lastcraft.com/first_test_tutorial.php">unit testing tutorial</a>.
- </p>
-
- <p>
-<a class="target" name="unit">
-<h2>Using the tester quickly</h2>
-</a>
-</p>
- <p>
- Amongst software testing tools, a unit tester is the one
- closest to the developer.
- In the context of agile development the test code sits right
- next to the source code as both are written simultaneously.
- In this context SimpleTest aims to be a complete PHP developer
- test solution and is called "Simple" because it
- should be easy to use and extend.
- It wasn't a good choice of name really.
- It includes all of the typical functions you would expect from
- <a href="http://www.junit.org/">JUnit</a> and the
- <a href="http://sourceforge.net/projects/phpunit/">PHPUnit</a>
- ports, but also adds
- <a href="http://www.mockobjects.com">mock objects</a>.
- It has some <a href="http://sourceforge.net/projects/jwebunit/">JWebUnit</a>
- functionality as well.
- This includes web page navigation, cookie testing and form submission.
- </p>
- <p>
- The quickest way to demonstrate is with an example.
- </p>
- <p>
- Let us suppose we are testing a simple file logging class called
- <span class="new_code">Log</span> in <em>classes/log.php</em>.
- We start by creating a test script which we will call
- <em>tests/log_test.php</em> and populate it as follows...
-<pre>
-<strong>&lt;?php
-require_once('simpletest/unit_tester.php');
-require_once('simpletest/reporter.php');
-require_once('../classes/log.php');
-?&gt;</strong>
-</pre>
- Here the <em>simpletest</em> folder is either local or in the path.
- You would have to edit these locations depending on where you
- placed the toolset.
- Next we create a test case...
-<pre>
-&lt;?php
-require_once('simpletest/unit_tester.php');
-require_once('simpletest/reporter.php');
-require_once('../classes/log.php');
-<strong>
-class TestOfLogging extends UnitTestCase {
-}</strong>
-?&gt;
-</pre>
- Now we have five lines of scaffolding code and still no tests.
- However from this part on we get return on our investment very quickly.
- We'll assume that the <span class="new_code">Log</span> class
- takes the file name to write to in the constructor and we have
- a temporary folder in which to place this file...
-<pre>
-&lt;?php
-require_once('simpletest/unit_tester.php');
-require_once('simpletest/reporter.php');
-require_once('../classes/log.php');
-
-class TestOfLogging extends UnitTestCase {
- <strong>
- function testCreatingNewFile() {
- @unlink('/temp/test.log');
- $log = new Log('/temp/test.log');
- $this-&gt;assertFalse(file_exists('/temp/test.log'));
- $log-&gt;message('Should write this to a file');
- $this-&gt;assertTrue(file_exists('/temp/test.log'));
- }</strong>
-}
-?&gt;
-</pre>
- When a test case runs it will search for any method that
- starts with the string <span class="new_code">test</span>
- and execute that method.
- We would normally have more than one test method of course.
- Assertions within the test methods trigger messages to the
- test framework which displays the result immediately.
- This immediate response is important, not just in the event
- of the code causing a crash, but also so that
- <span class="new_code">print</span> statements can display
- their content right next to the test case concerned.
- </p>
- <p>
- To see these results we have to actually run the tests.
- If this is the only test case we wish to run we can achieve
- it with...
-<pre>
-&lt;?php
-require_once('simpletest/unit_tester.php');
-require_once('simpletest/reporter.php');
-require_once('../classes/log.php');
-
-class TestOfLogging extends UnitTestCase {
-
- function testCreatingNewFile() {
- @unlink('/temp/test.log');
- $log = new Log('/temp/test.log');
- $this-&gt;assertFalse(file_exists('/temp/test.log'));
- $log-&gt;message('Should write this to a file');
- $this-&gt;assertTrue(file_exists('/temp/test.log'));
- }
-}
-<strong>
-$test = &amp;new TestOfLogging();
-$test-&gt;run(new HtmlReporter());</strong>
-?&gt;
-</pre>
- </p>
- <p>
- On failure the display looks like this...
- <div class="demo">
- <h1>testoflogging</h1>
- <span class="fail">Fail</span>: testcreatingnewfile-&gt;True assertion failed.<br>
- <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
- <strong>1</strong> passes and <strong>1</strong> fails.</div>
- </div>
- ...and if it passes like this...
- <div class="demo">
- <h1>testoflogging</h1>
- <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
- <strong>2</strong> passes and <strong>0</strong> fails.</div>
- </div>
- And if you get this...
- <div class="demo">
- <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>
- </div>
- it means you're missing the <em>classes/Log.php</em> file that could look like...
-<pre>
-&lt;?php
-class Log {
-
- function Log($file_path) {
- }
-
- function message() {
- }
-}
-?&gt;;
-</pre>
- </p>
-
- <p>
-<a class="target" name="group">
-<h2>Building group tests</h2>
-</a>
-</p>
- <p>
- It is unlikely in a real application that we will only ever run
- one test case.
- This means that we need a way of grouping cases into a test
- script that can, if need be, run every test in the application.
- </p>
- <p>
- Our first step is to strip the includes and to undo our
- previous hack...
-<pre>
-&lt;?php<strong>
-require_once('../classes/log.php');</strong>
-
-class TestOfLogging extends UnitTestCase {
-
- function testCreatingNewFile() {
- @unlink('/temp/test.log');
- $log = new Log('/temp/test.log');
- $this-&gt;assertFalse(file_exists('/temp/test.log'));
- $log-&gt;message('Should write this to a file');
- $this-&gt;assertTrue(file_exists('/temp/test.log'));<strong>
- }
-}
-?&gt;</strong>
-</pre>
- Next we create a new file called <em>tests/all_tests.php</em>
- and insert the following code...
-<pre>
-<strong>&lt;?php
-require_once('simpletest/unit_tester.php');
-require_once('simpletest/reporter.php');
-
-$test = &amp;new GroupTest('All tests');
-$test-&gt;addTestFile('log_test.php');
-$test-&gt;run(new HtmlReporter());
-?&gt;</strong>
-</pre>
- The method <span class="new_code">GroupTest::addTestFile()</span>
- will include the test case file and read any new classes created
- that are descended from <span class="new_code">SimpleTestCase</span>, of which
- <span class="new_code">UnitTestCase</span> is one example.
- Just the class names are stored for now, so that the test runner
- can instantiate the class when it works its way
- through your test suite.
- </p>
- <p>
- For this to work properly the test case file should not blindly include
- any other test case extensions that do not actually run tests.
- This could result in extra test cases being counted during the test
- run.
- Hardly a major problem, but to avoid this inconvenience simply add
- a <span class="new_code">SimpleTestOptions::ignore()</span> directive
- somewhere in the test case file.
- Also the test case file should not have been included
- elsewhere or no cases will be added to this group test.
- This would be a more serious error as if the test case classes are
- already loaded by PHP the <span class="new_code">GroupTest::addTestFile()</span>
- method will not detect them.
- </p>
- <p>
- To display the results it is necessary only to invoke
- <em>tests/all_tests.php</em> from the web server.
- </p>
-
- <p>
-<a class="target" name="mock">
-<h2>Using mock objects</h2>
-</a>
-</p>
- <p>
- Let's move further into the future.
- </p>
- <p>
- Assume that our logging class is tested and completed.
- Assume also that we are testing another class that is
- required to write log messages, say a
- <span class="new_code">SessionPool</span>.
- We want to test a method that will probably end up looking
- like this...
-<pre>
-<strong>
-class SessionPool {
- ...
- function logIn($username) {
- ...
- $this-&gt;_log-&gt;message("User $username logged in.");
- ...
- }
- ...
-}
-</strong>
-</pre>
- In the spirit of reuse we are using our
- <span class="new_code">Log</span> class.
- A conventional test case might look like this...
-<pre>
-<strong>
-&lt;?php
-require_once('../classes/log.php');
-require_once('../classes/session_pool.php');
-
-class TestOfSessionLogging extends UnitTestCase {
-
- function setUp() {
- @unlink('/temp/test.log');
- }
-
- function tearDown() {
- @unlink('/temp/test.log');
- }
-
- function testLogInIsLogged() {
- $log = new Log('/temp/test.log');
- $session_pool = &amp;new SessionPool($log);
- $session_pool-&gt;logIn('fred');
- $messages = file('/temp/test.log');
- $this-&gt;assertEqual($messages[0], "User fred logged in.\n");
- }
-}
-?&gt;</strong>
-</pre>
- This test case design is not all bad, but it could be improved.
- We are spending time fiddling with log files which are
- not part of our test. Worse, we have created close ties
- with the <span class="new_code">Log</span> class and
- this test.
- What if we don't use files any more, but use ths
- <em>syslog</em> library instead?
- Did you notice the extra carriage return in the message?
- Was that added by the logger?
- What if it also added a time stamp or other data?
- </p>
- <p>
- The only part that we really want to test is that a particular
- message was sent to the logger.
- We reduce coupling if we can pass in a fake logging class
- that simply records the message calls for testing, but
- takes no action.
- It would have to look exactly like our original though.
- </p>
- <p>
- If the fake object doesn't write to a file then we save on deleting
- the file before and after each test. We could save even more
- test code if the fake object would kindly run the assertion for us.
- <p>
- </p>
- Too good to be true?
- Luckily we can create such an object easily...
-<pre>
-&lt;?php
-require_once('../classes/log.php');
-require_once('../classes/session_pool.php');<strong>
-Mock::generate('Log');</strong>
-
-class TestOfSessionLogging extends UnitTestCase {
-
- function testLogInIsLogged() {<strong>
- $log = &amp;new MockLog($this);
- $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>
- $session_pool = &amp;new SessionPool($log);
- $session_pool-&gt;logIn('fred');<strong>
- $log-&gt;tally();</strong>
- }
-}
-?&gt;
-</pre>
- The <span class="new_code">tally()</span> call is needed to
- tell the mock object that time is up for the expected call
- count.
- Without it the mock would wait forever for the method
- call to come in without ever actually notifying the test case.
- The other test will be triggered when the call to
- <span class="new_code">message()</span> is invoked on the
- <span class="new_code">MockLog</span> object.
- The mock call will trigger a parameter comparison and then send the
- resulting pass or fail event to the test display.
- Wildcards can be included here too so as to prevent tests
- becoming too specific.
- </p>
- <p>
- The mock objects in the SimpleTest suite can have arbitrary
- return values set, sequences of returns, return values
- selected according to the incoming arguments, sequences of
- parameter expectations and limits on the number of times
- a method is to be invoked.
- </p>
- <p>
- For this test to run the mock objects library must have been
- included in the test suite, say in <em>all_tests.php</em>.
- </p>
-
- <p>
-<a class="target" name="web">
-<h2>Web page testing</h2>
-</a>
-</p>
- <p>
- One of the requirements of web sites is that they produce web
- pages.
- If you are building a project top-down and you want to fully
- integrate testing along the way then you will want a way of
- automatically navigating a site and examining output for
- correctness.
- This is the job of a web tester.
- </p>
- <p>
- The web testing in SimpleTest is fairly primitive, there is
- no JavaScript for example.
- To give an idea here is a trivial example where a home
- page is fetched, from which we navigate to an "about"
- page and then test some client determined content.
-<pre>
-&lt;?php<strong>
-require_once('simpletest/web_tester.php');</strong>
-require_once('simpletest/reporter.php');
-<strong>
-class TestOfAbout extends WebTestCase {
-
- function setUp() {
- $this-&gt;get('http://test-server/index.php');
- $this-&gt;clickLink('About');
- }
-
- function testSearchEngineOptimisations() {
- $this-&gt;assertTitle('A long title about us for search engines');
- $this-&gt;assertWantedPattern('/a popular keyphrase/i');
- }
-}</strong>
-$test = &amp;new TestOfAbout();
-$test-&gt;run(new HtmlReporter());
-?&gt;
-</pre>
- With this code as an acceptance test you can ensure that
- the content always meets the specifications of both the
- developers and the other project stakeholders.
- </p>
- <p>
- <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>
- </p>
-
- </div>
-<div class="copyright">
- Copyright<br>Marcus Baker, Jason Sweat, Perrick Penet 2004
- </div>
-</body>
-</html>