Почти каждая Test Automation команда прикладывает много усилий и времени, чтобы построить и отполировать свой Framework. Никто не нуждается в Framework в первую очередь. Вместо этого нужны быстрые, надежные и простые тесты, которые работают и обеспечивают качество для текущего процесса разработки. На это митапе @Nikita Simonovets расскажет, как можно построить хорошую автоматизацию и на какие готовые решения и подходы стоит обратить внимание.
Agenda:
• Whois Test Automation Engineer?
• What is really WebDriver?
• What is really Test Automation Framework?
• Bad examples of Test Automation Solution
• How to write more stable tests
• Stairway to heaven: Selenide vs JDI
4. DSL
A domain-specific language (DSL) is a computer
language specialized to a particular application domain.
@Test
public void bookShouldBeSearchedByName() {
loginToBookStoreAs(regularUser);
openBookStorePage();
enterSearchCriteria("99 Francs");
searchBooks();
assertFalse(isEmptySearchResult());
}
5. Benefits of DSL Approach
● High-level - tests are in the language of product
management, at the user level
● Readable - product management can understand them
● Writable - easy for developer or QA to write new test
● Extensible - tests base is able to grow with DSL
6. Tips and Tricks of DSL Approach
● Use test class hierarchy or test helpers
● Use builders, visitors and other design patterns
● Reuse domain model from application
● Some common methods move to base test class
● Minimize usage of driver instance in tests
7. What is really Test Automation Framework?
Test Automation Framework (TAF) — the environment required for test
automation including test harnesses and artifacts such as test libraries.
Test Automation Solution (TAS) — the realization / implementation of a TAA
including test harnesses and artifacts such as test libraries.
Test Automation Architecture (TAA) — an instantiation of gTAA to define the
architecture of a TAS.
Generic Test Automation Architecture (gTAA) — providing a blueprint for test
automation solutions.
9. What is Test Automation Engineer?
Test Automation Engineer (TAE) — the person who is
responsible for the design of a Test Automation Architecture
(TAA), including the implementation of the resulting Test
Automation Solution (TAS), its maintenance and technical
evolution.
TAE == Software Developer in Test
10. What is really WebDriver?
Selenium is
a suite of tools to automate web browsers
across many platforms.
11. What is really WebDriver?
Selenium automates browsers. That's it!
12. UI Test Automation Framework
Selenium inside
http://selenide.org
https://github.com/codeborne/selenide
13. Selenide > Main Goals
KISS principle in action
No unnecessary code → No unnecessary maintenance
Less to learn → Easier to use
15. Selenide > Keynote
Shutdown a browser
Selenium WebDriver:
if (driver != null) {
driver.close();
}
Selenide:
// Do not care! Selenide closes the browser automatically
With Selenide You don't need to operate with Selenium WebDriver directly.
WebDriver will be automatically created/deleted during test start/finished.
16. Selenide > Keynote
Find element by id
Selenium WebDriver:
WebElement customer = driver.findElement(By.id("customerContainer"));
Selenide:
WebElement customer = $("#customerContainer");
or a longer conservative option:
WebElement customer = $(By.id("customerContainer"));
17. Selenide > Keynote
Assert that element has a correct text
Selenium WebDriver:
assertEquals("Customer profile",
driver.findElement(By.id("customerContainer")).getText());
Selenide:
$("#customerContainer").shouldHave(text("Customer profile"));
18. Selenide > Keynote
Ajax support (waiting for some event to happen)
Selenium WebDriver:
FluentWait<By> fluentWait = new FluentWait<By>(By.tagName("TEXTAREA"));
fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS);
fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS);
fluentWait.until(new Predicate<By>() {
public boolean apply(By by) {
try {
return browser.findElement(by).isDisplayed();
} catch (NoSuchElementException ex) {
return false;
}
}
});
assertEquals("John", browser.findElement(By.tagName("TEXTAREA")).getAttribute("value"));
Selenide:
$("TEXTAREA").shouldHave(value("John"));
This command automatically waits until element gets visible AND gets expected value.
Default timeout is 4 seconds and it's configurable.
19. Selenide > Keynote
Assert that element does not exist
Selenium WebDriver:
try {
WebElement element = driver.findElement(By.id("customerContainer"));
fail("Element should not exist: " + element);
}
catch (WebDriverException itsOk) {}
Selenide:
$("#customerContainer").shouldNot(exist);
20. Selenide > Keynote
Looking for element inside parent element
Selenium WebDriver:
WebElement parent = driver.findElement(By.id("customerContainer"));
WebElement element = parent.findElement(By.className("user_name"));
Selenide:
$("#customerContainer").find(".user_name");
21. Selenide > Keynote
Looking for Nth element
Selenium WebDriver:
driver.findElements(By.tagName("li")).get(5);
Selenide:
$("li", 5);
22. Selenide > Keynote
Select a radio button
Selenium WebDriver:
for (WebElement radio : driver.findElements(By.name("sex"))) {
if ("woman".equals(radio.getAttribute("value"))) {
radio.click();
}
}
throw new NoSuchElementException("'sex' radio field has no value 'woman'");
Selenide:
selectRadio(By.name("sex"), "woman");
23. Selenide > Keynote
Take a screenshot
Selenium WebDriver:
if (driver instanceof TakesScreenshot) {
File scrFile = ((TakesScreenshot) webdriver)
.getScreenshotAs(OutputType.FILE);
File targetFile = new File("c:temp" + fileName + ".png");
FileUtils.copyFile(scrFile, targetFile);
}
Selenide:
takeScreenShot("my-test-case");
24. Selenide > Three simple things
1. Open the page
2. $(element).doAction()
3. $(element).check(condition)
open("/login");
$("#submit").click();
$(".message").shouldHave(text("Hello"));
25. Selenide > Use the power of IDE
Selenide API consists of few classes. Open your IDE and start typing.
Just type: $(selector). - and IDE will suggest you all available options.
Use the power of todays development environments instead of bothering with
documentation!
26. Selenide > Selenide API
open(String URL) opens the browser (if yet not opened) and loads the
URL
$(String cssSelector) – returns object of the SelenideElement class that
represents first element found by CSS selector on the page.
$(By) – returns "first SelenideElement" by the locator of the By class.
$$(String cssSelector) – returns object of type ElementsCollection that
represents collection of all elements found by a CSS selector.
$$(By) – returns "collection of elements" by the locator of By type.
import static com.codeborne.selenide.Selenide.* for readability
27. Selenide > Selenide API > Selectors
com.codeborne.selenide.Selectors
$(byText("Login")).shouldBe(visible));
$(byXpath("//div[text()='Login']")).shouldBe(visible);
$(By.xpath("//div[text()='Login']")).shouldBe(visible);
Selector
byText - search element by exact text
withText - search element by contained text (substring)
by(attributeName, attributeValue) - search by attribute’s name and value
byTitle - search by attribute “title”
byValue - search by attribute “value”
Xpath
etc.
28. Selenide > Selenide API
Perform some action on it:
$(byText("Sign in")).click();
Or even several actions at once:
$(byName("password")).setValue("qwerty").pressEnter();
Check some condition:
$(".welcome-message").shouldHave(text("Welcome, user!"));
When you needed an element in Element Collection of a same type:
$$("#search-results a").findBy(text("selenide.org")).click();
29. Selenide > Selenide API > Selenide Elements
Selenide Elements
SelenideElement
ElementsCollection
$ $$
30. Selenide > Selenide API > Selenide Element
com.codeborne.selenide.SelenideElement
Actions methods
Search methods
Element statuses methods
Check methods (Assertions)
Conditions methods
Selenide Explicit Waits methods
Other useful methods
38. Selenide > Selenide API > Elements Collection
Selector methods
filterBy(Condition) – returns
collection with only those
original collection elements
that satisfies the condition,
excludeWith(Condition)
get(int)
findBy(Condition)
Element statuses methods
size()
isEmpty()
getTexts()
39. Selenide > Selenide API > Elements Collection
Check methods (Assertions)
shouldBe(CollectionCondition)
shouldHave(CollectionCondition)
Assertions also play role of explicit waits.
They wait for condition
(e.g. size(2), empty, texts("a", "b", "c")) to be
satisfied until timeout reached (the value
of Configuration.collectionsTimeout
that is set to 6000 ms by default).
Conditions methods
empty
size(int)
sizeGreaterThan(int)
sizeGreaterThanOrEqual(int)
sizeLessThan(int)
sizeLessThanOrEqual(int)
sizeNotEqual(int)
texts(String... substrings)
exactTexts(String... wholeTexts)
40. Selenide > Selenide API > WebDriver Runner
com.codeborne.selenide.WebDriverRunner
This class defines some browser management methods:
isChrome()
isFirefox()
isHeadless()
url()
source()
getWebDriver() - returns the WebDriver instance (created by Selenide
automatically or set up by the user), thus giving to the user the raw API
to Selenium if needed
setWebDriver(WebDriver) - tells Selenide to use driver created by the
user. From this moment the user himself is responsible for closing the
driver.
41. Selenide > Selenide API > Configuration
com.codeborne.selenide.Configuration
Сonfiguration options to configure execution of Selenide-based tests, e.g.:
timeout: waiting timeout in milliseconds, that is used in explicit
(should/shouldNot/waitUntil/waitWhile) and implicit waiting for
SelenideElement; set to 4000 ms by default; can be changed for
specific tests, e.g. Configuration.timeout = 6000;
collectionsTimeout - waiting timeout in milliseconds, that is used in
explicit (should/shouldNot/waitUntil/waitWhile) and implicit waiting for
ElementsCollection; set to 6000 ms by default; can be changed for
specific tests, e.g. Configuration.collectionsTimeout = 8000;
browser (e.g. "chrome", "ie", "firefox")
baseUrl
...
42. UI Test Automation Framework
Selenium inside
http://jdi.epam.com
https://github.com/epam/JDI
https://github.com/epam/JDI-Examples
43. JDI > Main Goals
Already implemented actions for most used elements
Detailed UI actions log
Flexible for any UI on any Framework or Platform
Short and obvious UI Objects (Page Objects)
56. JDI > JDI API > Typified elements
Code readability
Clear behavior
Union of all element’s locators
Union of element and its actions
Detailed logging