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-&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>&lt;?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 = &amp;new SessionPool($log);        $session_pool-&gt;logIn('fred');</strong>        $messages = file('/temp/test.log');        $this-&gt;assertEqual($messages[0], "User fred logged in.<strong>\n</strong>");    }}?&gt;</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>&lt;?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 = &amp;new MockLog();        $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>        $session_pool = &amp;new SessionPool(<strong>$log</strong>);        $session_pool-&gt;logIn('fred');    }}?&gt;</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>&lt;?phprequire_once('simpletest/autorun.php');<strong>require_once('simpletest/web_tester.php');</strong>class TestOfAbout extends <strong>WebTestCase</strong> {    function testOurAboutPageGivesFreeReignToOurEgo() {        <strong>$this-&gt;get('http://test-server/index.php');        $this-&gt;click('About');        $this-&gt;assertTitle('About why we are so great');        $this-&gt;assertText('We are really great');</strong>    }}?&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>                You can navigate forms too...<pre>&lt;?phprequire_once('simpletest/autorun.php');require_once('simpletest/web_tester.php');class TestOfRankings extends WebTestCase {    function testWeAreTopOfGoogle() {        $this-&gt;get('http://google.com/');        $this-&gt;setField('q', 'simpletest');        $this-&gt;click("I'm Feeling Lucky");        $this-&gt;assertTitle('SimpleTest - Unit Testing for PHP');    }}?&gt;</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&amp;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&amp;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 + -
显示快捷键?