📜 ⬆️ ⬇️

UI tests: Cucumber + Selenide

Part 1


Today let's talk about creating a UI smoke test for a site using the frameworks Cucumber and Selenide. The article is designed for junior, which knows absolutely nothing about these frameworks. An experienced junior will find interesting moments in the second part , which I reached for a couple of months.
The article consists of two parts:



Frameworks


Selenide is a framework (or rather a library) wrapping Selenium. How it differs, beautifully described by the author , Andrey Solntsev. The main difference is that Selenide allows you to cut a bunch of lines of code when writing UI tests, which is one of the main tasks when creating tests / writing code, because you need to take care of the tester that comes after you and will have to parse your creation.


Cucumber is a framework that implements the BDD / TDD approach.



I do not pretend to have a deep theoretical knowledge of BDD / TDD , so far for me they are the same thing.


BDD / TDD from a practical point of view:


  1. From business comes those. task, on the basis of which programmers should write down new functionality - create a feature
  2. Before programmers start writing code (as is done in most cases), testers and programmers sit at a round table and discuss how exactly the feature will work. The result of the round table is a paper-recorded feature - a set of actions by the client / user, which leads to some result: a) clicked here; b) entered the numbers there; c) got the result there


    As a result of such a round table, one understanding is created on all this feature, documented on paper.


  3. Further, programmers begin to write code according to the described feature. Testers are also starting to write tests in parallel, because the recorded feature, thanks to Cucumber , is a future test. It is clear that the test can be completed only after the programmers finish coding, but in this way the writing of code and tests goes in parallel, which speeds up the development process

More pluses of Cucumber :



Project on githaba


Video of test performance on youtube




Let's sort the first simple part of simple_selenide_cucumber.


Project structure:




We use Intellij IDEA , Maven and Junit .


Mail.txt contains logins, account passwords for working with the test. ATTENTION: if you start at home, keep in mind that the system will throw out one of the users who will log in with one login / password. Change the mail


In pom.xml we write the following dependency:


<dependencies> <dependency> <groupId>com.codeborne</groupId> <artifactId>selenide</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java8</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> 

Smoketest file # 1.feature is the same feature (feature description) that programmers and testers agreed upon at a round table (in an ideal world :). As you can see, this is a description of user actions on the site, recorded in human-readable form, i.e. it is also your log file, provided that every step (action) does not imply very complex logic:


 Feature: smoke test #1, go through the service to Yandex-pay-page Scenario: go through the service to button "" #actions at first page Given open riskmarket.ru When press button with text "  " And type to input with name "userName" text: "riskmarket.testoviy2016@yandex.ru" And type to input with name "password" text: "l0dcfJMB" And press element with value "" ... Scenario: go through service to yandex pay-page Given press button with text "" #actions at third page When type to input with name "lastName" text: "TESTOVIY" ... 

Creating your UI test begins with this file, the file with the .feature extension. You should put it in the test/java/…/features/ package


The feature should start with the keyword:


  Feature: 

Here it is indicated in general terms what exactly the feature does. In our case, the smoke test is “Pass through the service to the Yandex.payments page”


Next comes the keyword:


  Scenario: 

The script is actually a separate test, i.e. feature can contain as many scripts (tests). All scripts, obviously, should relate to this feature. In our case there will be two scenarios, the first is to go to the Buy button and the second is to go to the payments page . According to the rules of testing, scripts (tests) should be independent, i.e. the success of the passage of one scenario should not depend on the success of the passage of the second scenario. ATTENTION : in our case, this is not the case - the second scenario starts at the point where the first scenario stops, and if the first one falls down, then the second one as well.
The script also has a brief description of what it does.


Next come the steps themselves. Before each step there must be one of the keywords Given, When, Then, And or But .


Given - indicates the initial conditions, "Given: this and that"


When - user actions: click here, wait for something


Then - the result that turns out: most often it is a kind of test, as in our case


 Then element with tag "search-result-item" should exist 

and


 Then verify that page with url "http://money.yandex.ru/cashdesk" is opened 

And , But - is used as a union of "and" , "but" to make it easier to read. With "and" everything is clear. “But” can be used, for example, in steppes describing the thought “... this thing should be visible, BUT this one should be hidden”


Try to observe the separation of steppes into these three parts ( Given, When, Then ), since these are the BDD / TDD rules.


After writing the features, you can run the test (right-click on the features file -> Run). The result will be many Undefined step: < > . The system hints that it does not know how to perform each step. It is necessary to slip the logic of the performance of tap dance. If you write in IDEA, then you have every indefinite step highlighted. Press Alt + Enter and go through all dialog boxes without changing values. The MyStepdefs class will be created (for convenience, I put it in the steps package). You will see something like:


 @Given("^open riskmarket\\.ru$") public void openRiskmarketRu() throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); } 

By default, methods that define steppes throw PendingException() . This is necessary so that there are no indefinite steps, and at the same time you can continue to write tests. Those. while the feature is being written by programmers, some steps can already be defined, and some must wait for the programmers to write the code. Each time you run a test, the system will remind you which steps have not yet been determined.


You can also use lambda expressions to describe steps. But I will not disassemble it here, because This is a separate issue. We will do the old fashioned.


Let us analyze the step definition in more detail:


 @Given("^open riskmarket\\.ru$") public void openRiskmarketRu() 

The first line is the abstract, with the help of which Cucumber understands to which step this definition applies. In place of @Given , as mentioned earlier, can be @And/@Then/@But/@When . Next, the annotation argument uses a regular expression ( regex ).


Regex is the topic of a separate article, read somewhere, the material is full.


Here are the key regex symbols used that are needed to start:



The next line public void openRiskmarketRu() is the name of the method. The method that determines the step must always be public void . If you use Alt + Enter, then IDEA itself synthesizes the name of the method, most often this is enough.


Let us examine some steps.


In the description of step logic, Selenide is used.


  1. View in feature: Given open riskmarket.ru


    MyStepdefs view:


     @Given("^open riskmarket\\.ru$") public void openRiskmarketRu() { open("http://riskmarket.ru"); } 

    Thanks to the open(…) method from Selenide , the instance WebDriver (by default, Firefox) is created in one line and goes to the specified url . Close / kill instance is not necessary, it will make Selenide


  2. View in feature:


     When press button with text "  "` And press button with text " " Given press button with text "" And press button with text "" 

    MyStepdefs view:


     @When("^press button with text \"([^\"]*)\"$") public void press(String button) { $(byText(button)).waitUntil(Condition.visible, 15000).click(); } 

    Here is an example of reuse step. Try to reuse steps as often as possible, do not procreate the code. In our example, in the annotation argument we indicate that "the button can contain any text of any kind, but in quotes" . What fun, you can use any language.


    Generally speaking, any language can also be used to describe steps - you can write like this:


      And     "" 

    Once the name of the button is an argument, then we indicate it in the method signature:


      public void press(String button) 

    $() Is the Selenide method for finding an item on a page. He has many different, convenient options. In this case, we are looking for an element that contains our text. I am writing an article from a place with not very fast internet, so you need to add an increased wait until the element appears, because built-in timeout for 4s is not enough. $(byText(button) gives us an object of type SelenideElement , which, among other methods, has such a wait - waitUntil(Condition, timeout) . Condition - the condition we are waiting for.


    Condition is a Selenide class in which many different conditions are described, look, it will come in handy.


    And at the end, when we waited for the element to appear, click on it.
    By the way, what is described in one line here, in pure Selenium, you would have taken several lines of code, with the creation of WebDriverWait.


  3. View in feature:


     And type to input with name "userName" text: "riskmarket.testoviy2016@yandex.ru" And type to input with name "password" text: "l0dcfJMB” When type to input with name "lastName" text: "TESTOVIY" And type to input with name "firstName" text: "TEST" 

    MyStepdefs view:


     @And("^type to input with name \"([^\"]*)\" text: \"([^\"]*)\"$") public void typeToInputWithNameText(String input, String text) { sleep(1000); $(byName(input)).sendKeys(text); } 

    This step is used one of the times after the frame appears, so you need to pause for input to appear - done using Selenide sleep(timeout with ms) .


    sendKeys(String) - sends text to element.


  4. View in feature:


     And select countries: , ,  

    MyStepdefs view:


     @And("^select countries: (.*)$") public void selectCountries(List<String> countries) { for (String str : countries) { $("#countryInput").sendKeys(str); $("#countryInput").pressEnter(); } } 

    When describing steppes as a parameter, you can take lists - the elements are listed separated by commas.
    The remaining steps are similar to those described above.
    Junit was added to this project in pom.xml only because of the last step, where checking that the desired url was opened is done using assertThat () .



The first part ends here. Read in the second part about automatic screenshots, custom Condition , PageObject , annotation of elements and the creation of beautiful reports.


')

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


All Articles