Software quality assurance days 18 Международная конференция по вопросам качества ПО sqadays.com Москва. 27–28 ноября 2015 Матвеев Сергей ЗАО «КИВИ». Москва, Россия Selenium, а давай подождем?
Selenium, а давай подождем? О себе В тестирование более 3 лет Веду несколько проектов по автоматизации UI Visa QIWI Wallet и ishop.qiwi.com, а так же занимаюсь нагрузочным тестированием Люблю организовывать процессы и вдохновлять людей
Selenium, а давай подождем? Selenium, а давай подождем?
Selenium, а давай подождем? Схема простейшего теста Подождем элемент Взаимодействие с элементом Подождем результат Проверим результат
Selenium, а давай подождем? Простейшее ожидание public void sleep() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public void sleep(long time) { try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } Продвинутые методики:
Selenium, а давай подождем? Почему это плохо? 1. Стабильность тестов понижается 2. Пониженная стабильность ведет к увеличению времени на поддержку 3. Увеличение времени прохождения тестового пака 4. «Временное решение» станет вечным 5. Увеличение кода тестовых методов
Selenium, а давай подождем? «Временное решение» станет вечным form.typeValue(value); page.waitSecond(); Assert.assertTrue(form.dataOnlineIsVisible()); Спустя пару комитов: form.typeValue(value); page.waitSecond(); page.waitSecond(); page.waitSecond(); page.waitSecond(); Assert.assertTrue(form.dataOnlineIsVisible());
Selenium, а давай подождем? Увеличение кода тестовых методов link = “Боевики" leftMenu.choose(link); assertTrue(!content.isEmpty); Так? link = "Фильмы" leftMenu.choose(link); sleep(); assertTrue(!content.isEmpty); … или так? public void choose(String link) { driver.findElement(By.linkText(link)).click(); sleep(); }
Selenium, а давай подождем? Состояния элемента Не найден Есть, видимый, нельзя взаимодействовать Есть, но не видимый Есть, видимый, можно взаимодействовать Был, но удален из DOM
Selenium, а давай подождем? Имплицитные ожидания (неявные) driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); element = driver.findElement(By.id("sub")); Когда они не работают: 1. Надо просто проверить наличие элемента 2. Нужно найти один элемент из двух 3. Подождать пока элемент исчезнет
Selenium, а давай подождем? Эксплицитные ожидания(явные) Супер связка WebDriverWait + ExpectedCondition new WebDriverWait(driver, 30).until(visibilityOfAllElementsLocatedBy(By.id("subb")));
Selenium, а давай подождем? Что можно подождать? Класс ExpectedConditions: Смена заголовка страницы wait.until(titleIs(«Заголовок"); Появление элемента wait.until(presenceOfAllElementsLocatedBy(locator)); Видимость элемента wait.until(visibilityOfElementLocated(locator)); Удаление элемента из DOM wait.until(stalenessOf(element)); Невидимость элемента wait.until(invisibilityOfElementLocated(locator));
Selenium, а давай подождем? Тонкая настройка public class WebDriverWait extends FluentWait<WebDriver> new WebDriverWait() .withMessage(“ Не дождались :-( ”) .pollingEvery( 200 , TimeUnit.MILLISECONDS ) .withTimeout( 10 , TimeUnit.SECONDS ) .ignoring( NoSuchElementException.class ) public class WebElementWait extends FluentWait<WebElement>
Selenium, а давай подождем? Собственные ожидания static ExpectedCondition<Boolean> display( final By by) { return new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver webDriver) { return webDriver.findElement(by).isDisplayed(); } }; } static Predicate<WebElement> isElementDisplay() { return new Predicate<WebElement>() { @Override public boolean apply(WebElement element) { return element.isDisplayed(); } }; } new WebElementWait( element,10 ).until( isElementDisplay ())
Selenium, а давай подождем? Прочие ожидания Frame Window Alert Загрузка страницы
Selenium, а давай подождем? Alert wait().until(ExpectedConditions.alertIsPresent()); Команда driver.swictTo().alert(); в FF будет ждать 2 секунды, если alert нет. Любое действие может закончится с UnhandledAlertException
Selenium, а давай подождем? Окна
Selenium, а давай подождем? Ожидание окна с известным свойством ExpectedCondition<String> windowWithCorrectH1( final String h1) { return new ExpectedCondition<String>() { @Override public String apply(WebDriver driver) { String mainWindow = driver.getWindowHandle(); String foundWindow = null ; Set<String> otherWindows = driver.getWindowHandles(); for (String window : otherWindows) { try { driver.switchTo().window(window); if(driver.findElement(By.tagName("h1")).getText().equals(h1)) { foundWindow = window; break ; } } catch (WebDriverException e) { } } driver.switchTo().window(mainWindow); return foundWindow; } }; }
Selenium, а давай подождем? Ожидание появления любого нового окна ExpectedCondition<String> newWindow( final Set<String> currentWindows) { return new ExpectedCondition<String>() { @Override public String apply(WebDriver driver) { Set<String> newWindows = driver.getWindowHandles(); newWindows.removeAll(currentWindows); if(newWindows.size()> 0 ) { return (String)newWindows.toArray()[ 0 ]; } else { return null ; } } }; } ... Set <String> windows = driver.getWindowHandles(); click(); new WebDriverWait(driver,10).until(newWindow(windows)); ...
Selenium, а давай подождем? Ожидание загрузки страницы ExpectedCondition<Boolean> DOCUMENT_READY = new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver webDriver) { return (Boolean) ((JavascriptExecutor) webDriver).executeScript( "return document.readyState == 'interactive' || document.readyState == 'complete'" ); } } Selenium использует свойство document.readyState для определения момента окончания загрузки страницы. loading interactive complete
Selenium, а давай подождем? Как все это использовать?
Selenium, а давай подождем? Как все это использовать? driver.findElement( search ).sendKeys(" mts "); clickEnter(); Assert.assertTrue ( isProvidersPresent() ); driver.findElement( search ).sendKeys(" банки "); clickEnter(); Assert.assertTrue ( isProvidersPresent() );
Selenium, а давай подождем? Как все это использовать? driver.findElement( search ).sendKeys(" mts "); clickEnter(); Assert.assertTrue ( isProvidersPresent() ); driver.findElement( search ).sendKeys(" банки "); clickEnter(); Assert.assertTrue ( isProvidersPresent() ); if( isProvidersPresent() ) { wait.until(ExpectedConditions.stalenessOf( driver.findElement (By.cssSelector( provider ))); }
Selenium, а давай подождем? Как все это использовать? driver.findElement( search ).sendKeys(" mts "); clickEnter(); Assert.assertTrue ( isProvidersPresent() ); driver.findElement( search ).sendKeys(" банки "); clickEnter(); Assert.assertTrue (isProvidersPresent()); WebElement provider = driver.findElement(By.cssSelector( provider )); wait.until(ExpectedConditions.stalenessOf( provider ));
Selenium, а давай подождем? Как все это использовать? Тест не дождался нового провайдера
Selenium, а давай подождем? Как все это использовать? driver.findElement( search ).sendKeys(" mts "); clickEnter(); Assert.assertTrue ( isProvidersPresent() ); WebElement provider = driver.findElement(By.cssSelector( provider )); driver.findElement( search ).sendKeys(" банки "); clickEnter(); wait.until(ExpectedConditions.stalenessOf( provider )); Assert.assertTrue ( isProvidersPresent() ); wait.until(visibilityOfAllElementsLocatedBy( providerLocator )); wait.until(visibilityOfAllElementsLocatedBy( providerLocator ));
Selenium, а давай подождем? Зачем все это нужно?
Selenium, а давай подождем? Убрал все sleep();