📜 ⬆️ ⬇️

DevPoint: Selenium in web application testing

What to do when:

To score and justify that such a code should not live?

I often encountered such situations and it did not suit me. While searching for a suitable testing method / tool, I came across Selenium. And apply it for more than 3 years.

DevPoint conference dedicated to web development took place on April 9 in Kiev. The organizer of this event was Uniweb . As part of it, I decided to share an impression about Selenium.
')
Selenium consists of many subprojects, but wanted to highlight only three:

Selenium Core - JavaScript framework for writing and executing tests. Used in Selenium IDE and Remote Control *.

Selenium IDE - plugin for Firefox, which allows you to record and play tests. It can also generate test code for use in Selenium Remote Control.

Selenium Remote Control is a client-server system that allows you to control web browsers locally or on other computers using virtually any programming language.

As part of this report about Selenium Core there was no time to focus attention, although this project is most interesting for writing tests with nontrivial logic.

Selenium IDE



Advantages of Selenium IDE:

A spoon of tar:

We use Selenium IDE in practice


For example, I took a lively old project, which is still the task to cover up with tests. This is a regular online store, which is used for in-house bulk purchases in one company, we don’t give names ...
The first test that we write will simply log in to the system:



Recommendations for those who start using Selenium:

The system is very important functionality associated with the exchange rate, as it must be set manually for each day. Let's write a test covering this logic:



And the last two tests that cover the logic of creating and editing an order:





And to check our tests, the intention was to spoil the preservation of the order:



Advantages of testing in IDE:

Minuses:

Selenium Remote Control


Selenium Remote Control is an http daemon that accepts commands via GET and executes them. API for communication with Selenium RC is almost for all programming languages. This report is only about the API for PHP, which is provided with PHPUnit



As mentioned earlier in the Selenium IDE there is a nice option for generating code for * Unit:



Thus, you can simply copy the code and execute it in your PHPUnit suite.



Also in PHPUnit - Selenium it is possible to run tests written in Selenium IDE:
class SeleneseTests extends PHPUnit_Extensions_SeleniumTestCase
{
public static $ seleneseDirectory = '/ devpoint / ide' ;

protected function setUp ( )
{
$ this -> setBrowser ( "* firefox" ) ;
$ this -> setBrowserUrl ( " test.devpoint.com.ua/" ) ;
}
}

Without a file can not do ...


  1. PHPUnit_Extensions_SeleniumTestCase cannot interpret suite files with the Selenium IDE;
  2. to run the test, PHPUnit always launches a new browser;
  3. PHPUnit 3.4.x does not properly handle the logic of the wait commands.

The execution of tests in the Selenium IDE and in PHPUnit differ in their approach. Selenium IDE assumes that tests performed in a suite may be dependent on each other, while in PHPUnit each test is independent of the previous *. And for each test PHPUnit sends commands to re-initialize the browser and, accordingly, our tests are performed with an error, since they depend on the first test. To solve this problem, the logic was written to execute the suite file created in Selenium IDE.

To solve the problem with the execution of the wait * commands, you need to consider how they are executed in PHPUnit:
for ( $ second = 0 ;; $ second ++ ) {
if ( $ second > = 60 ) $ this -> fail ( "timeout" ) ;
try {
if ( "Orders" == $ this -> getText ( "// html / body / table / tbody / tr / td [2] / form / table / tbody / tr / td" ) ) break ;
} catch ( Exception $ e ) { }
sleep ( 1 ) ;
}

In fact, we loop the execution of the command for a certain interval and wait until our condition becomes true. Implementing PHPUnit - Selenium sending the Selenium RC command expects only two answers from it, that everything is good or that everything is bad. If the ERROR answer came, then it immediately closes the browser, writes that an error occurred and, accordingly, our cycle will send commands to an already closed Selenium RC session.

I put the code with the solution of these problems on github and I will not dwell on it.

Another of the nice things about Selenium RC is that he can take screenshots when an error is detected:
class ScreenshotTest extends PHPUnit_Extensions_SeleniumTestCase
{
protected $ captureScreenshotOnFailure = true ;
protected $ screenshotPath = '/ home / ... / screenshots' ;
protected $ screenshotUrl = 'http: // localhost / screenshots' ;
}

The downside is that the screenshots do not highlight the location of the error, but the text in PHPUnit is usually easy to understand what is wrong.

We pull the strings not FireFox



According to the developers, Selenium RC supports the following browsers:

In fact, to achieve correct execution in these browsers is not always possible the first time, but this is not in the framework of this report. The only thing I’ll note in Firefox, IE and Chrome under Windows is almost never a problem in Safari under MacOS.

To run our tests in different browsers, it is enough to describe an array in the static $ browsers variable with the settings for accessing Selenium RC:
class SeleneseTests extends PHPUnit_Extensions_SeleniumTestCase
{
public static $ browsers = array (
array (
'name' => 'Firefox on Windows' ,
'browser' => '* firefox' ,
'host' => 'localhost' ,
'port' => 4444 ,
'timeout' => 30000 ,
) ,
array (
'name' => 'IE on Windows' ,
'browser' => '* iexplore' ,
'host' => 'localhost' ,
'port' => 4444 ,
'timeout' => 30000 ,
) ,
array (
'name' => 'Google Chrome on Windows' ,
'browser' => '* googlechrome' ,
'host' => 'localhost' ,
'port' => 4444 ,
'timeout' => 30000 ,
) ,
) ;

protected function setUp ( )
{
$ this -> setBrowserUrl ( " test.devpoint.com.ua/" ) ;
}

public function testSigninCase ( )
{
$ this -> open ( "/ login /" ) ;
$ this -> waitForPageToLoad ( "" ) ;
$ this -> type ( "login" , "admin" ) ;
$ this -> type ( "password" , "admin" ) ;
$ this -> click ( "// input [@ value = 'Login']" ) ;
$ this -> waitForPageToLoad ( "30000" ) ;
$ this -> assertEquals ( "Home" , $ this -> getText ( "// html / body / table / tbody / tr / td / a" ) ) ;
}

}



How can Selenium not help you?




Report


Source: https://habr.com/ru/post/117648/


All Articles