index.html.svn-base
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· SVN-BASE 代码 · 共 539 行 · 第 1/2 页
SVN-BASE
539 行
<p> 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">TestSuite::addFile()</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 or the command line. </p> <p> For more information about building test suites, see the <a href="group_test_documentation.html">test suite documentation</a>. </p> <p><a class="target" name="mock"><h2>Using mock objects</h2></a></p> <p> Let's move further into the future and do something really complicated. </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->_log->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><?phprequire_once('simpletest/autorun.php');require_once('../classes/log.php');<strong>require_once('../classes/session_pool.php');</strong>class <strong>TestOfSessionLogging</strong> extends UnitTestCase { function setUp() { <strong>@unlink('/temp/test.log');</strong> } function tearDown() { <strong>@unlink('/temp/test.log');</strong> } function testLoggingInIsLogged() { <strong>$log = new Log('/temp/test.log'); $session_pool = &new SessionPool($log); $session_pool->logIn('fred');</strong> $messages = file('/temp/test.log'); $this->assertEqual($messages[0], "User fred logged in.<strong>\n</strong>"); }}?></pre> We'll explain the <span class="new_code">setUp()</span> and <span class="new_code">tearDown()</span> methods later. </p> <p> 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. 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? It means that our <span class="new_code">TestOfSessionLogging</span> test will fail, even thouh it's not testing Logging. </p> <p> It's fragile in smaller ways too. 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 can reduce coupling if we 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? We can create such an object easily...<pre><?phprequire_once('simpletest/autorun.php');require_once('../classes/log.php');require_once('../classes/session_pool.php');<strong>Mock::generate('Log');</strong>class TestOfSessionLogging extends UnitTestCase { function testLoggingInIsLogged() {<strong> $log = &new MockLog(); $log->expectOnce('message', array('User fred logged in.'));</strong> $session_pool = &new SessionPool(<strong>$log</strong>); $session_pool->logIn('fred'); }}?></pre> The <span class="new_code">Mock::generate()</span> call code generated a new class called <span class="new_code">MockLog</span>. This looks like an identical clone, except that we can wire test code to it. That's what <span class="new_code">expectOnce()</span> does. It says that if <span class="new_code">message()</span> is ever called on me, it had better be with the parameter "User fred logged in.". </p> <p> The 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 by <span class="new_code">SessionPool::logIn()</span> code. 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 you don't have to test every parameter of a call when you only want to test one. </p> <p> If the mock reaches the end of the test case without the method being called, the <span class="new_code">expectOnce()</span> expectation will trigger a test failure. In other words the mocks can detect the absence of behaviour as well as the presence. </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 more information about mocking and stubbing, see the <a href="mock_objects_documentation.html">mock objects documentation</a>. </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, as there is no JavaScript. Most other browser operations are simulated. </p> <p> 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><?phprequire_once('simpletest/autorun.php');<strong>require_once('simpletest/web_tester.php');</strong>class TestOfAbout extends <strong>WebTestCase</strong> { function testOurAboutPageGivesFreeReignToOurEgo() { <strong>$this->get('http://test-server/index.php'); $this->click('About'); $this->assertTitle('About why we are so great'); $this->assertText('We are really great');</strong> }}?></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> You can navigate forms too...<pre><?phprequire_once('simpletest/autorun.php');require_once('simpletest/web_tester.php');class TestOfRankings extends WebTestCase { function testWeAreTopOfGoogle() { $this->get('http://google.com/'); $this->setField('q', 'simpletest'); $this->click("I'm Feeling Lucky"); $this->assertTitle('SimpleTest - Unit Testing for PHP'); }}?></pre> ...although this could violate Google's(tm) terms and conditions. </p> <p> For more information about web testing, see the <a href="browser_documentation.html">scriptable browser documentation</a> and the <a href="web_tester_documentation.html">WebTestCase</a>. </p> <p> <a href="http://sourceforge.net/projects/simpletest/"><img src="http://sourceforge.net/sflogo.php?group_id=76550&type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></a> </p> </div> References and related information... <ul><li> <a href="https://sourceforge.net/project/showfiles.php?group_id=76550&release_id=153280">Download PHP Simple Test</a> from <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>. </li><li> The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a> gives full detail on the classes and assertions available. </li></ul><div class="menu_back"><div class="menu"><span class="chosen">SimpleTest</span> | <a href="overview.html">Overview</a> | <a href="unit_test_documentation.html">Unit tester</a> | <a href="group_test_documentation.html">Group tests</a> | <a href="mock_objects_documentation.html">Mock objects</a> | <a href="partial_mocks_documentation.html">Partial mocks</a> | <a href="reporter_documentation.html">Reporting</a> | <a href="expectation_documentation.html">Expectations</a> | <a href="web_tester_documentation.html">Web tester</a> | <a href="form_testing_documentation.html">Testing forms</a> | <a href="authentication_documentation.html">Authentication</a> | <a href="browser_documentation.html">Scriptable browser</a></div></div><div class="copyright"> Copyright<br>Marcus Baker 2006 </div></body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?