Tobiasz Cudnik

Posts Tagged ‘web’

Test cases for websites using phpQuery and SimpleTest

In Ideas, phpQuery on 13.01.2009 at 23:09

Using phpQuery and some UnitTest framework (SimpleTest in this example) you can automatically test web page for presentence of specific part and it’s position. Set of such tests can save a lot of time during website development and after that even more.

Not only you can do simple tests like “are articles visible” but using WebBrowser plugin you can test whole process, let’s say a user registration. Example of such test i would like to present. This test will include following steps:

  1. Enter main page and follow the registration link
  2. Fill registration form and submit it
  3. Check if result is expected

Like i sad before, SimpleTest is framework of choice, but it doesn’t matter so much. What’s important:

  • WebBrowser needs callbacks
  • Callbacks should be declared as functions (for PHP < 5.3)
  • Inside callbacks, $this variable is unavailable
  • First step of the test should check if last step has succeeded

Full code below:

require('simpletest/autorun.php');
require('phpQuery/phpQuery.php');

class CustomerTest extends UnitTestCase {
	public static $_this;
	public static $registration = array(
		'username' => null,
		'success' => false
	);
	function testRegistration() {
		self::$_this = $this;
		phpQuery::browserGet('http://localhost/tested-site/',
			array('CustomerTest', '_testRegistrationLink')
		);
		$this->assertTrue(
			self::$registration['success'], "Registration unsuccessful"
		);
	}
	function _testRegistrationLink($browser) {
		$registrationLink = null;
		$browser->find('a:contains(rejestracja)')
			->WebBrowser(array('CustomerTest', '_testRegistrationForm'))
			->toReference($registrationLink)
				// jump to _testRegistrationForm
				->click();
		self::$_this->assertTrue(
			$registrationLink->length, "Registration link missing"
		);
	}
	function _testRegistrationForm($browser) {
		$registrationForm = null;
		$username = md5(microtime());
		$browser['.customers.form form']
			->toReference($registrationForm)
			->WebBrowser(array('CustomerTest', '_testRegistrationResult'))
			->find('input[name*=login]')->val($username)->end()
			->find('input[name*=email]')->val($username.'@test.com')->end()
			// jump to _testRegistrationResult
			->submit();
		self::$_this->assertTrue(
			$registrationForm->length, "Registration form missing"
		);
		self::$registration['username'] = $username;
	}
	function _testRegistrationResult($browser) {
		$loginForm = $browser->find('h2:text(Logowanie)');
		self::$_this->assertTrue($loginForm->length, "Login form missing");
		if ($loginForm->length)
			self::$registration['success'] = true;
	}
}

WebBrowser doesn’t support AJAX, so not all sites can be tested like this (although you can do it with AHAH after some work), but cookies and HTTP authentication should satisfy most needs.

Of course that’s noting new, projects accomplishing similar goal exist quite time now, eg jWebUnit, but neither of them have jQuery under the hood  ;)