A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.mediawiki.org/wiki/Selenium_Framework below:

Selenium/PHP/Selenium Framework - MediaWiki

SeleniumFramework provides a standardized way of writing Selenium[1] tests for MediaWiki and MediaWiki extensions. The software is based on the PHPUnit unit testing framework and inherits much of PHPUnit's functionality.

Selenium is a tool for looking at an installation and trying to break it and filing bug reports, maybe in a mechanized way -- in other words, integration testing. But automated integration testing, as we've now experienced, frequently breaks; it's brittle, not robust. Selenium is an automated tests framework suited to integration testing: you start Selenium and it fires up a browser, performs scripted actions as a user would, and checks the actual output against the desired output. But that means that we have to define the desired output in a way Selenium can programmatically test, and so the tests break when we change things that actual users wouldn't care about.

For example, a test might define success as "this DIV should have the value 1". If we change the skin to output a SPAN element instead of a DIV element, then the test will fail. And even if a failed test is a legitimate signal of a problem, we have to start from scratch investigating what to fix and how.

We're thus phasing out the use of Selenium for MediaWiki -- see Test framework deployment#Status:_Permanent_hiatus. Sumanah 19:01, 1 July 2011 (UTC)[reply]

Installation

SeleniumFramework has the following major dependencies:

Selenium

SeleniumFramework curently uses Selenium Remote Control (Selenium RC) (and also should use Selenium Grid in the future.)

#  if needed, add the PEAR channels for PHPUnit and its dependencies
pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com

# Install PHPUnit
pear install phpunit/PHPUnit

Testing_Selenium is a PHP client for the Selenium Remote Control test tool.

# you can try "pear install Testing_Selenium", but it may give you an error if you don't specify the stable version
pear install Testing_Selenium-0.4.3

PHPUnit and Testing_Selenium must be accessible within your PHP path. If your PEAR installation is properly configured, then this should already be the case.

Configuration

Create a selenium_settings.ini file

The selenium_settings.ini file configures various settings for SeleniumFramework, such as the browsers that Selenium will attempt to use in testing and the base URL of the wiki to be tested.

selenium_settings.ini must be created in the root or your MediaWiki installation and should use one of the provided template files from tests/selenium. The template to use depends on the Selenium project (and, possibly, version of PHP) that you are running.

Once you have created selenium_settings.ini, you will need to customize the settings it contains. At a minimum, you will need to set the wikiURL configuration value to match the base URL of the MediaWiki instance you are testing.

Update your LocalSettings.php file

Once the preceding steps are complete, you will need to update your LocalSettings.php file to enable SeleniumFramework.

To enable SeleniumFramework, you will need to add the following code to LocalSettings.php :

$wgEnableSelenium = true;
$wgSeleniumConfigFile = $IP . '/selenium_settings.ini';

Loading test configurations and suites

Once SeleniumFramework has been enabled, you'll need to tell it what tests to run.

To do this, you'll need to add a bit more code to LocalSettings.php .

The following examples show how to load various test suites.

# Basic example
require_once( "tests/selenium/suites/SimpleSeleniumConfig.php" );
$wgSeleniumTestConfigs['SimpleSeleniumTestSuite'] = 'SimpleSeleniumConfig::getSettings';

Here's a more complex example that loads the WikiEditor test suite. Note that WikiEditor must be installed for this to work.

require_once("extensions/WikiEditor/tests/selenium/WikiEditorSeleniumConfig.php");
$wgSeleniumTestConfigs['WikiEditorTestSuite'] = 'WikiEditorSeleniumConfig::getSettings';

Multiple MediaWiki instances

The configuration above assumes a single wiki for everything. It is possible to have two separate wikis (one driving the tests, and one being tested). More information can be found in Selenium Configuration.

Writing tests

Adding a test suite

To add a Selenium test, you must first create a test suite class that extends class SeleniumTestSuite. Look at SimpleSeleniumTestSuite.php for an example (which is in the tests/selenium/suites directory of the MediaWiki source.

Add test cases to the suite by implementing the addTests() function. If you have per-suite setup and teardown code, override the setUp() and tearDown() functions.

class MyExtensionTestSuite extends SeleniumTestSuite
{
 # Define only if you have per-suite setup code
 public function setUp(){
 	# Add setUp code here
 	parent::setUp();
 }
 public function addTests() {
 	$testFiles = array(
 		'extensions/MyExtension/tests/selenium/SimpleSeleniumTestCase.php',
 		'extensions/MyExtension/selenium/FooBarTestCase.php'
 	);
 	parent::addTestFiles( $testFiles );
 }
 # Define only if you have per-suite teardown code
 public function teardown(){
 	# Add setUp code here
 	parent::tearDown();
 }
}

Adding individual tests

In each test file listed in addTests(), create a class that extends SeleniumTestCase. Name the class after the file that contains the class, omitting the extension. For example: A file named SimpleSeleniumTestCase.php should contain class SimpleSeleniumTestCase.

For each test that you wish to run, add a public function to the class. Each function name should start with test. For example: testWidget().

Test functions should contain no more than one call to any of the various assert functions (like

assertEmpty()

or

assertEquals()

). The reason for this is that the logger only reports whether or not a test passed, not which assertions in the test passed or failed. If there are multiple assertions in a test function and the test fails, it will be impossible to know which assertion caused the test to fail.

If you have per-test setup and teardown code, override the setUp() and tearDown() functions.

setUp() and tearDown() are run for every test – not just at the beginning and end of all test runs.

class SimpleSeleniumTestCase extends SeleniumTestCase
{
 public function testBasic( ) {
 	$this->open( $this->getUrl() . '/index.php?title=Selenium&action=edit' );
 	$this->type( "wpTextbox1", "This is a basic test" );
 	$this->click( "wpPreview" );
 	$this->waitForPageToLoad( 10000 );
 	// check result
 	$source = $this->getText( "//div[@id='wikiPreview']/p" );
 	$correct = strstr( $source, "This is a basic test" );
 	$this->assertEquals( $correct, true );
 }
 public function testGlobalVariable1( ) {
 	$this->open( $this->getUrl() . '/index.php?&action=purge' );
 	$bodyClass = $this->getAttribute( "//body/@class" );
 	$this-> assertContains('skin-vector', $bodyClass, 'Vector skin not set');
 }
}

Examples

[SeleniumTests]
testSuite[SimpleSeleniumTestSuite] = "tests/selenium/SimpleSeleniumTestSuite.php"

Test Wiki configuration

Multiple test suites that need different wiki configurations are run against a single test wiki.

Recording tests with Selenium IDE

You can record tests with Selenium IDE and still use them with the framework. In order to do so, you have to follow these steps:

Running tests without Selenium Framework

In some cases, Selenium Framework will not be available on the wiki under test. This is especially the case when testing the installer. In this case, you need to tell the test not to use the dynamic reconfiguration and not to try to log into the wiki under test. This is done in the test suite like this:

class MyExtensionTestSuite extends SeleniumTestSuite
{
 public function setUp(){
 	# Add setUp code here
 	parent::setUp();
 	$this->setTriggerClientTestResources( false );
 	$this->setLoginBeforeTests( false );
 }
 ...
}

Running Tests

Requirements

(Do we need more fine grained control, like per test instead of per test suite?)

Missing

Implementation details

Test suite:

Test wiki:
The following happens in WebStart.php only if a global variable $wgEnableSelenium is set.

the test specific include files
the test specific globals (key value pairs)

Test wiki configuration example:
As an example see extensions/WikiEditor/tests/selenium

require_once("extensions/WikiEditor/tests/selenium/WikiEditorSeleniumConfig.php");
$wgSeleniumTestConfigs['WikiEditorTestSuite'] = 'WikiEditorSeleniumConfig::getSettings';

Architecture

These files are part of the framework:

The tests should be located here:

Testing with a clean database and file state

testrunner                     wiki under test
----------                     ---------------
1.1 start selenium which in
turn starts a browser to
talk to the wiki under
test
1.2 send request for new test
with unique test id and tests
that will be fired         
                               2.1 create cookie with test id
                               2.2 create temporal resources 
                               according to tests list
                               2.3 create test tracker with timestamp
                               2.4 return success code
3.1 start testsuites via selenium
3.2 send a lot of individual
requests according to the tests
                               4.1 testrunner is identified by test id
                               4.2 reconfigure database and resources
                               according to test id
                               4.3 ? Do something with memcached ?
                               4.4 execute request
                               4.5 update timestamp in test tracker
5.1 send a teardown request
                               6.1 execute teardown, i.e. delete
                               all resources associated with 
                               test id
                               6.2 delete test tracker
                               6.3 return success code
7.1 stop selenium

Test style guide

This section focuses on general test style issues specific to Selenium Framework. For general issues of Selenium test style, see the test design considerations section of the Selenium documentation.

Leave no trace

Avoid brittle paths

Many developers will use the Selenium IDE to draft tests. This approach allows developers to rapidly rough out tests, but may generate locators that fail when used on other platforms or that are brittle and break when exposed to trivial edge cases.

When possible, avoid absolute paths. Instead, start with an element ID and work relative to the ID.

For example, if the Selenium IDE generated a path like: /html/body/div[2]/p[1] and div[2] has an ID of content, then use path //div[@id="content"]/p[1]

File naming conventions

The names for the test and configuration files should follow these conventions:

Keep log output in mind

Do not expect someone to read your test code. If a test fails, people will most likely read a log file. It is therefore very helpful to pay attention to descriptive log lines.

Do not log with echo

Often, the output of tests is processed further, e.g. by a continuous integration server. In this case, everything that is logged via echo will be lost. More particular, the framework is equipped to produce xml output compatible to phpunit, and echo messages are ignored in this file.

Test cases vs. suites

In order to get a differenciated logging, it is possible to use several test methods per test case, each of which produces an individual line in the log. Unfortunately, the setUp method is called for each of this methods, which makes perfect sense in phpunit but is not a behaviour we want with selenium. So instead, we use a method testSetUp() and testTearDown(), which are called only once per test case. Here is an outline of such an architecture:

class GeneralTestCase extends SeleniumTestCase { ...
   public function testSetUp() {
   ...
   }

   public function testFactboxExists() {
   ...
   }
   
   /**
   *@depends testFactboxExists 
   */
   public function testFactboxContainsRightStrength() {
   ...
   }
}

Here, you can even build in dependencies (see comment in the code above), i.e. if a test fails, succeeding tests will not be executed if they are dependent.

Number of assertions

Ideally, there is one assertion per test. However, this is often not manageable in reality. But it is possible to add a log line to an assertion that will be used in logs and xml output:

$this->assertTrue( $this->isElementPresent("body"), "Element body is  not present" );

Notes and further improvements

Add common test tasks

Add common assertions

Improvements

Further ideas

A test (or a single test suite) should be able to reconfigure the wiki according to its needs. Here, some serious security issues arise. This might be a possible way:

If the hook is not triggered in LocalSettings, no reconfiguration can take place.

Troubleshooting

Error about Testing_Selenium (0.4.3 is installed from pear along with PHPUnit) not being found

General Tips

Backporting

Currently, the framework is only available in svn trunk and will not be available in a packaged version before MW 1.17. In order to make it run with older versions, you need to do this:

 # Include site settings. $IP may be changed (hopefully before the AutoLoader is invoked)
 require_once( MW_CONFIG_FILE );
}

if ( $wgEnableSelenium ) {
 require_once( "$IP/includes/SeleniumWebSettings.php" );
}

wfProfileOut( 'WebStart.php-conf' );

This is known to work at least with MW 1.15.3 onwards.

Experiences: Recent changes in handling of framework

Notes

  1. Selenium is a tool to automate testing of web application interfaces across many platforms.

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4