Before reading this section, it is recommended that you read the Selenium documentation and the PHPUnit documentation first. We summarize in the following the basic principles of writing a functional test in Yii:
Like unit test, a functional test is written in terms of a class XyzTest
which extends from [CWebTestCase], where Xyz
stands for the class being tested. Because PHPUnit_Extensions_SeleniumTestCase
is the ancestor class for [CWebTestCase], we can use all methods inherited from this class.
The functional test class is saved in a PHP file named as XyzTest.php
. By convention, the functional test file may be stored under the directory protected/tests/functional
.
The test class mainly contains a set of test methods named as testAbc
, where Abc
is often the name of a feature to be tested. For example, to test the user login feature, we can have a test method named as testLogin
.
A test method usually contains a sequence of statements that would issue commands to Selenium RC to interact with the Web application being tested. It also contains assertion statements to verify that the Web application responds as expected.
Before we describe how to write a functional test, let's take a look at the WebTestCase.php
file generated by the yiic webapp
command. This file defines WebTestCase
that may serve as the base class for all functional test classes.
[php] define('TEST_BASE_URL','http://localhost/yii/demos/blog/index-test.php/'); class WebTestCase extends CWebTestCase { /** * Sets up before each test method runs. * This mainly sets the base URL for the test application. */ protected function setUp() { parent::setUp(); $this->setBrowserUrl(TEST_BASE_URL); } ...... }
The class WebTestCase
mainly sets the base URL of the
pages to be tested. Later in test methods, we can use relative URLs to
specify which pages to be tested.
We should also pay attention that in the base test URL, we use index-test.php
as the entry script instead of index.php
. The only difference between index-test.php
and index.php
is that the former uses test.php
as the application configuration file while the latter main.php
.
We now describe how to test the feature about showing a post in the blog demo. We first write the test class as follows, noting that the test class extends from the base class we just described:
[php] class PostTest extends WebTestCase { public $fixtures=array( 'posts'=>'Post', ); public function testShow() { $this->open('post/1'); // verify the sample post title exists $this->assertTextPresent($this->posts['sample1']['title']); // verify comment form exists $this->assertTextPresent('Leave a Comment'); } ...... }
Like writing a unit test class, we declare the fixtures to be used by this test. Here we indicate that the Post
fixture should be used. In the testShow
test method, we first instruct Selenium RC to open the URL post/1
.
Note that this is a relative URL, and the complete URL is formed by
appending it to the base URL we set in the base class (i.e. http://localhost/yii/demos/blog/index-test.php/post/1
). We then verify that we can find the title of the sample1
post can be found in the current Web page. And we also verify that the page contains the text Leave a Comment
.
Tip: Before running functional tests, the Selenium-RC server must be started. This can be done by executing the command
java -jar selenium-server.jar
under your Selenium server installation directory.