📜 ⬆️ ⬇️

Integration testing of a web application with Selenium WebDriver

Integration testing (as opposed to Unit or unit testing) is not testing of individual atomic components of the system (classes) but the result of their interaction with each other in any environment.

By the will of fate, I am developing a kind of interface framework sharpened for specific corporate needs. The framework for executing the framework is a browser, and according to this language is JavaScript.

I wrote earlier about how Unit can test JavaScript. Now I’ll tell you about the integration testing process used in the team.

Selenium


For a long time, a tool for testing web applications / pages in the browser is known - Selenium . In terms of its application, there are two main ways, namely:
  1. writing TestSuite to SeleniumIDE and running them through SeleniumTestRunner, or
  2. using webdriver

WebDriver is a new "chip" Selenium, which appeared in the second branch of the product. Its main essence is that you can run the tests described in the code (C #, Java, Python, Ruby), in different browsers and / or in a virtual execution environment.
')

Webdriver


Selenium WebDriver is a set of "bindings" to different languages ​​(C #, Java), which allows you to give various commands to the "slave" browser.

Each browser has its own WebDriver implementation (FireFoxDriver, InternetExplorerDriver, ChromeDriver - now included, OperaSoftware developed OperaDriver ). There is also a “virtual” HtmlUnitDriver. Unlike browser implementations, it does not require an installed browser and due to this it is faster and platform-independent, but there are also disadvantages - HtmlUnitDriver has its own JavaScript implementation and therefore the behavior of rich web applications may differ. For our tasks, we use “browser” implementations; this allows us to test the application in the environment in which it will be executed later.

Briefly, the general essence of working with WebDriver can be described as follows:

What can WebDriver


Below is a “browser” implementation, the essence of the RemoteWebDriver class extension (implements the WebDriver interface).

C "found" elements (WebElement interface)

Test execution environment


Java was chosen as the language for writing tests. Environment for execution - JUnit4 .

DISCLAIMER : I do not pretend to be a cool Javista, so if my older colleagues find flaws and all sorts of other “antipatterns”, I’ll be happy to hear in the comments.

The base abstract class of web tests.
@Ignore abstract public class AbstractWebTest { protected static RemoteWebDriver _driver; //    private String testPageLocation = String.format( "http://%s:%s/test.html", System.getProperty("test.httproot"), // Web- ... System.getProperty("test.httpport", "80") //   ); //   WebDriver private static String driverName = System.getProperty( "test.driver", "org.openqa.selenium.firefox.FirefoxDriver"); /** *     -   . *     */ @BeforeClass public static void setUpDriver() throws ClassNotFoundException, IllegalAccessException, InstantiationException { _driver = (RemoteWebDriver) Class.forName(driverName).newInstance(); } /** *    -    */ @Before public void setUp() { _driver.get(testPageLocation); } /** *     -    ( ) */ @AfterClass public static void tearDown() { _driver.close(); } } 

A specific class with a set of tests (for simplicity, some checks have been removed, for example, that the CSS selector element is actually found and accessible on the page)
 public class TestMoneyField extends AbstractWebTest { /** *         0.00 */ @Test public void testRendering() { WebElement content = _driver.findElementByCssSelector("#FieldMoney .input-text-field"); Assert.assertEquals("0.00", content.getValue()); } /** *   "" */ @Test public void testInputWithoutDot() { WebElement content = _driver.findElementByCssSelector("#FieldMoney .input-text-field"); content.sendKeys("999999"); Assert.assertEquals("999 999.00", content.getValue()); } } 

All tests are run using a separate task of the Ant build:
 <target name="integrationtest" depends="init, buildtests, deploytests"> <junit haltonfailure="false"> <sysproperty key="test.driver" value="org.openqa.selenium.firefox.FirefoxDriver" /> <classpath> <pathelement location="${path.to.tests.jar}"/> </classpath> <batchtest> <fileset dir="${path.to.compiled.test.classes}"> <include name="**/tests/Test*.class" /> </fileset> </batchtest> </junit> <junit haltonfailure="false"> <sysproperty key="test.driver" value="org.openqa.selenium.ie.InternetExplorerDriver" /> <classpath> <pathelement location="${path.to.tests.jar}"/> </classpath> <batchtest> <fileset dir="${path.to.compiled.test.classes}"> <include name="**/tests/Test*.class" /> </fileset> </batchtest> </junit> </target> 

This task will run all known tests from classes whose names begin with Test under the Firefox and InternetExplorer browsers. In dependencies task with basic initialization, compilation and unloading of compiled tests on the test site.

Chips, buns


Some “browser” implementations (Firefox, Opera, Chrome) support screenshots. This can be useful in order to fix the visual state in which the test page was in at the moment when the test failed. To do this, the JUnit4 functionality - TestWatchman .
 @Ignore abstract public class AbstractWebTest { //    private String screenshotDir = System.getProperty("test.screenshotDir", ""); @Rule public MethodRule watchman = new TestWatchman() { /** *     ""  * @param e    * @param method - */ @Override public void failed(Throwable e, FrameworkMethod method) { if(_driver instanceof TakesScreenshot && !screenshotDir.equals("")) { String browserName = _driver.getClass().getName(); String testSuiteName = method.getMethod().getDeclaringClass().getName(); browserName = browserName.substring(browserName.lastIndexOf('.') + 1); testSuiteName = testSuiteName.substring(testSuiteName.lastIndexOf('.') + 1); byte[] screenshot = ((TakesScreenshot)_driver).getScreenshotAs(OutputType.BYTES); try { FileOutputStream stream = new FileOutputStream( new File( String.format("%s/screenshot_%s_%s_%s.png", screenshotDir, browserName, testSuiteName, method.getName()))); stream.write(screenshot); stream.close(); } catch (IOException e1) { e1.printStackTrace(System.out); } } } }; //  ... } 

Add a variable with the path to the screenshots folder in the Ant build
  <junit haltonfailure="false"> <sysproperty key="test.driver" value="org.openqa.selenium.firefox.FirefoxDriver" /> <sysproperty key="test.screenshotDir" value="${screenshotsDir}" /> <classpath> <pathelement location="${path.to.tests.jar}"/> </classpath> <batchtest> <fileset dir="${path.to.compiled.test.classes}"> <include name="**/tests/Test*.class" /> </fileset> </batchtest> </junit> 

Integration


In the current implementation, the Ant Build chases through Jetbrains TeamCity . The launch of the build is configured to reset the code in SVN. Integration tests are part of the overall testing procedure. If any of the integration tests fail, a screenshot is taken and published as an “artifact” of the build - you can see not only which tests “drove off” after dumping any functionality into the trunk, but also to see “how” they “drove off”.

Currently testing under IE and Firefox is used, Chrome is not connected due to some difficulties with integration (apparently, ChromeDriver contains some errors that do not allow to search for elements on the page in some cases - as of 2.0b1, 2.0b2 is now available but have not tried to work with it)

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


All Articles