Category: Тестирование

27
Июн
2022

Тестируем на Python: unittest и pytest. Инструкция для начинающих 

Python-разработчик Андрей Смирнов рассказал, как написать первые тесты и какие фреймворки выбрать: unittest или pytest.
— Читать дальше «Тестируем на Python: unittest и pytest. Инструкция для начинающих »

29
Май
2022

Ожидаемое условие не выполнено: ожидание видимости всех элементов, расположенных с помощью By.xpath

Падает тест, ошибка: org.openqa.selenium.TimeoutException: ожидаемое условие не выполнено: ожидание видимости всех элементов, расположенных с помощью By.xpath: //h5[text()=’Elements’] (попытка длилась 30 секунд с интервалом 500 миллисекун…

14
Апр
2022

Какой фремворк для интеграционного тестирования использует текстовое описание теста [закрыт]

Проблема:

Существуют ли юнитестфреймовки тесты в котором описываються текстовыми критериями а не кодом? Если да то что это за фреймворки

Пример: (как я его вижу)

Тестировщику поставлена задача написать автотест для проверки создания сущ…

10
Апр
2022

Как после выполнения теста selenium запустить скрипт на питоне?

Есть тест на selenium, сгенерированный selenium ide. Он скачивает с сайта файл .xls, есть скрипт на питоне, который проверяет этот файл на корректность. Как после выполнения теста автоматически запускать этот скрипт?

10
Апр
2022

Как после выполнения теста selenium запустить скрипт на питоне?

Есть тест на selenium, сгенерированный selenium ide. Он скачивает с сайта файл .xls, есть скрипт на питоне, который проверяет этот файл на корректность. Как после выполнения теста автоматически запускать этот скрипт?

19
Мар
2022

Не может найти xpath при автотесте входа mail ru

Я только начинаю изучать тестирование в Selenide JAVA. Я попытался создать простенький автотест со входом в свою учетную запись. Копирую Xpath ПКМ через настройки, до этого в других сайтах работала, но тут я вижу что при клике на TextBox h…

20
Фев
2022

Модульное тестирование REST сервиса

Пишу REST сервис на CDI. Используется библиотека helidon. При запуске этот сервис получает часть конфигурации с другого сервиса. Это сделано при помощи специального config-интерфейса org.eclipse.microprofile.config.spi.ConfigSource. Класс,…

09
Фев
2022

Хрупкие тесты при использовании моков репозиториев

Задача: нужно протестировать метод, который под капотом обращается к репозиторию:
public Result businecLoigc(int x, int y) {
int z = …; //шаг 1 – но основе x и y формируем z

T t = myRepository.get(z); //шаг 2

//… оставшая…

07
Фев
2022

Копирование mock сервиса из SoapUI в питоновский скрипт

Всем привет, есть мок сервис и запрос в soap проекте от разраба, можно ли заюзать мок сервис питоном? Отдельно запрос я могу отправить питоновским скриптом, взяв url и xml запроса из проекта, а что делать с мок сервисом? Только запускать в…

07
Фев
2022

Копирование mock сервиса из SoapUI в питоновский скрипт

Всем привет, есть мок сервис и запрос в soap проекте от разраба, можно ли заюзать мок сервис питоном? Отдельно запрос я могу отправить питоновским скриптом, взяв url и xml запроса из проекта, а что делать с мок сервисом? Только запускать в…

16
Янв
2022

🧪 4 простых шага по найму и развитию тестировщика

Рассказываем, как команде разработчиков подготовиться к собеседованию с тестировщиком (QA) и быстро ввести его в курс дела.

Хорошо, когда путь специалиста по тестированию начинается в команде, где уже есть QA-специалист или даже собрана целая команда – в таком случае его развитие идет плавно и продуманно. Но что делать, если процессы тестирования на проекте еще не построены, а сам тестировщик только начинает первые шаги на этом пути? Предлагаем вам инструкцию по найму и развитию QA-специалиста.

Шаг 1. На что обратить внимание во время собеседования


Продукт должен уже выйти в продакшен, сроки горят, а количество багов все не уменьшается, и стабильность оставляет желать лучшего. Обычно в такой момент задумываются над тем, что неплохо было бы взять в команду специалиста по тестированию, который поможет искать баги и контролировать процесс вывода продукта в продакшен. Однако, нанимать специалистов с опытом построения тестовых процессов дорого и долго, поэтому проще найти новичка: он и дешевле и на рынке труда сейчас их много, а там уже как-нибудь он сам разберется и научится.

И вот решение принято, вакансия опубликована и на почту упало несколько десятков резюме. Осталось найти нужного кандидата.

Первое: подготовьте вопросы до собеседования. Не нужно спрашивать про белый и черный ящики, или как протестировать карандаш (только ленивый не загуглит ответы на эти вопросы), вы не только потратите впустую время, но и оттолкнете кандидата. Лучше придумайте кейс, который реально случился у вас на проекте, например, форма поиска или может форма обратной связи. Подготовьте несколько несложных задач на знание SQL. Если проект является веб-сервисом, то можно поговорить про REST-запросы и коды ответов. Задайте вопросы про Linux, потому что знание хотя бы основ окажется большим плюсом в снятии логов и дальнейшей работе.

Второе: смотрите, как кандидат думает, а не на его знания – основные знания можно просто зазубрить. Тот же ISQB можно сдать, просто выучив теорию. А вот думать как тестировщик сможет не каждый. Поэтому лучше посмотрите на примере, как человек будет тестировать простую форму, заодно узнаете, как он выбирает приоритеты багов.

Третье: не давите на кандидата своим авторитетом.

Шаг 2. С чего начать знакомство с тестировщиком, а тестировщика с системой


Самый достойный кандидат найден, со дня на день примет оффер и придет работать к вам в команду. Отлично! Часть работы сделана, вот только это малая часть. Любому, а тем более начинающему специалисту, нужны подсказки и заметки, которые помогут начать работу и быстро влиться в проект.

Начать следует с создания рабочей среды: какие доступы понадобятся тестировщику для начала? Доступ к самому тестируемому продукту, к системе управления проектом (например, Jira), к базе знаний, к Git? Будет ли тестировщик собирать проект локально на своем компьютере или сборка ведется на виртуальных машинах с помощью Jenkins? В таком случае туда тоже нужен будет доступ. Подготовив такой список, вы удивитесь, насколько легче принимать в команду новичков, а не только тестировщика с опытом.

Если на проекте нет тестовой документации, то сейчас есть шанс с самого начала сделать ее понятной и полезной. Подумайте, какими вы хотели бы видеть баг-отчеты, может, вам хватит стандартного шаблона, а может, проект имеет свою специфику и без какого-то определенного поля (например, логина/пароля пользователя) будет сложно воспроизводить баг. Нужна ли вам mind-map карта проекта (ее создание как раз поможет тестировщику полностью познакомиться с проектом)? Какие тесты вы хотите видеть на проекте? Будет ли время на их написание? Можно ли потом их будет переписать в документацию проекта, например в ПМИ? Решив все эти вопросы, вы значительно упростите жизнь тестировщика.

Приведенные выше советы – формальности. Следовать им или нет – ваше право. Главное – не бросайте человека одного. Пусть у него будет наставник из разработчиков или аналитиков, кто лучше знает проект. Помогите ему сгенерировать ssh ключ и подложить на сервер для снятия логов. Да, вопросов будет очень много, но, отвечая на них, вы точно не потратите время впустую.

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека тестировщика»

Шаг 3. Когда начинать автоматизировать


Вот прошло несколько недель или месяцев с прихода тестировщика. Он прижился на проекте, тестовая документация в норме, баги быстро находятся и правятся. Не пора ли начать автоматизировать тесты? Ответ, скорее всего, нет.

Любая автоматизация тестирования в первое время требует больших затрат времени и сил. Чаще всего на активно развивающемся проекте их нет. Тем более, если тестировщик один. Поэтому, если вы уверены, что автоматизировать непременно нужно, то сразу же решите, какой процент времени и сил можно выделить под эту задачу в день, неделю или месяц. Если этого не сделать, то всегда будут находиться более приоритетные задачи и баги, и, в конце концов, ни одного теста вы не получите.

Если время было успешно выделено, то можно перейти к следующему этапу: выбору типа тестов, языка и архитектуры. Если опираться на пирамиду тестирования, то разумнее выбрать unit или rest-тесты.

Пирамида тестирования
Пирамида тестирования

Чаще всего unit-тесты пишут сами разработчики, но при желании этим может заниматься и опытный тестировщик. Однако если вы хотите впечатлить заказчика, то можно написать и UI-тесты, правда на их поддержку и выполнение уйдет гораздо больше времени, чем на остальные типы тестов.

Не стоит забывать про CI для тестов, потому что без окружения тесты будут лежать мертвым грузом. Так что, принимая решение об автоматизации тестирования на проекте, сразу же добавьте несколько часов работы DevOps-a.

Шаг 4. Курсы и конференции


Хотелось бы обсудить последний вопрос: это развитие тестировщика как специалиста. Развитие тестировщика важно для качества продукта. Чем больше специальных знаний имеет тестировщик, тем больше сценариев проверки он сможет придумать, больше ошибок предвидит и лучше проверит новые фичи.

В интернете есть множество инструкций по развитию QA-инженера. При желании такую инструкцию можно составить лично для человека, опираясь на его предпочтения. Способов развития есть множество. Лучшие, на наш взгляд – новые задачи, курсы и конференции.

Если с задачами все понятно, то в чем преимущество конференций и курсов? Курсы хороши тем, что сейчас туда добавляют много практики, а также создаются чаты, где можно найти собеседников своего уровня, которые чаще всего сталкиваются с такими же проблемами, что и проходящий курс тестировщик. Нужно следить, чтобы человек не начинал хаотично учиться всем направлениям одновременно, потому что в таком случае знания не успевают применяться на практике и остаются мертвым грузом.

Конференции же больше полезны для поиска новых идей. Полностью применить то, что услышала на конференциях, еще ни разу не получилось на практике, но новые идеи обязательно появлялись. Так что посмотрите, какие конференции идут в ближайшее время и отправьте на них тестировщика, он вернется с новыми идеями и готовым усовершенствовать процесс.

***

Пройдя все шаги, выстроив свою систему тестирования и выучив новое, станет ли человек готовым специалистом? Скорее да, чем нет. Правда стоит помнить, что путь этот не заканчивается никогда и всегда есть куда расти.

Успехов!

Материалы по теме

02
Янв
2022

🎨 Как нарисовать смайлик и квадрат в онлайн-редакторе графики Paint с помощью Selenium

В этой статье напишем два скрипта, рисующих смайлик и квадрат в онлайн-версии Paint с помощью инструмента для автоматизации действий браузера Selenium.

Когда работаешь тестировщиком, бывает не знаешь, какую задачу тебе подкинет новый день. Может, это будет нагрузочное тестирование, проверка отказоустойчивости или появится надобность написать скрипт для генерирования данных.

В практике попадаются интересные и необычные задачи. Одной из таких задач является взаимодействие в UI c нестандартными элементами. Поэтому, придумаем задачу, которая на первый взгляд кажется сложной, но на деле оказывается достаточно простой. Пусть она будет звучать так: нарисовать в онлайн-версии программы Paint простой рисунок.

Составим план выполнения задачи:

  1. Открыть Online Paint.
  2. Нарисовать рисунок.
  3. Сохранить его на компьютер.

Перед тем как писать сам тест, нужно подготовить окружение. Это достаточно рутинная задача при создании новых тестов или тестовых проектов, поэтому не буду расписывать долго подготовку окружения к написанию UI теста на Selenium, а составлю чек-лист, чтобы можно было проверить, что мы ничего не забыли (добавлю только, что в этот раз мы напишем скрипт на языке программирования Java и, соответственно, окружение создадим для него):

  1. Добавить Selenium и Junit в pom file:
            <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    

2. Скачать дистрибутив Selenium в main/resources (в этом тесте у меня chromdriver):


3. Написать метод для подключения дистрибутива (для удобства вынесу в @Before):

            @Before
    public void start(){
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(CapabilityType.PAGE_LOAD_STRATEGY, "eager");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--disable-extensions");
        System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver");
        options.addArguments("--start-maximized");
        options.addArguments("--remote-debugging-port=9222");
        driver = new ChromeDriver(options);
    }
    

4. Написать метод закрытия WebDriver:

            @After
    public void stop(){
        driver.quit();
        driver = null;
    }

    

Окружение готово, можно приступим к выполнению. Откроем сайт https://jspaint.app/ и с помощью панели разработчика посмотрим, что же это за элемент используется на сайте, на котором предстоит рисовать.


Оказывается, это canvas. Canvas – элемент HTML5, предназначенный для создания растрового двухмерного изображения с помощью скриптов, обычно на языке JavaScript.

Для пробы пера напишем сначала простой тест для проверки способов взаимодействия с элементом:

            @Test
    public void simplePaint(){
        driver.get("https://jspaint.app/");
         WebElement canvas = driver.findElement(By.xpath("//canvas[@class='main-canvas']"));

         driver.findElement(By.xpath("//div[@title='Кисть']/span")).click();

        Actions builder = new Actions(driver);
        builder.clickAndHold(canvas).moveByOffset(0, -100).
                moveByOffset(-100,0).
                moveByOffset(0,100).
                moveByOffset(100,0).release().perform();
    }
    

Пробный тест прошел легко. Его результат можно увидеть на gif-изображении:


Больше полезной информации вы найдете на нашем телеграм-канале «Библиотека тестировщика».

Теперь усложним задачу – нарисуем смайлик.

Шаги, которые будут выполняться в тесте:

  1. Открыть Online Paint.
  2. Нарисовать смайлик.
  3. Сохранить полученную картинку.

В первом тесте мы получали картинку, двигая пером по заданным координатам. Нарисовать сложную картинку таким способом не так просто. Поэтому можно поменять способ взаимодействия с этим элементом и отправить итоговое изображение с помощью JavascriptExecutor. JavascriptExecutor – это интерфейс Selenium, который позволяет взаимодействовать напрямую с HTML DOM веб-страницы и делает это, выполняя код на JavaScript. Такой способ значительно ускоряет выполнения теста, но теряется полная идентичность действиям пользователя. Является ли это плюсом или минусом – решать вам. В любом случае использование JavascriptExecutor может пригодиться в других тестах, поэтому полезно уметь пользоваться им на практике.

По намеченному плану получается такой код:

         @Test
    public void paintSmile(){
// открываем сайт онлайн пейнта
        driver.get("https://jspaint.app/");
// рисуем смайлик
        if (driver instanceof JavascriptExecutor) {
            ((JavascriptExecutor)driver).executeScript("var canvas = document.getElementsByClassName(\"main-canvas\");\n" +
                    "console.log(canvas);" +
                    "ctx.beginPath();"+
                    "ctx.arc(75,75,50,0,Math.PI*2,true);"+
                    "ctx.moveTo(110,75);"+
                    "ctx.arc(75,75,35,0,Math.PI,false);"+
                    "ctx.moveTo(65,65);"+
                    "ctx.arc(60,65,5,0,Math.PI*2,true);"+
                    "ctx.moveTo(95,65);"+
                    "ctx.arc(90,65,5,0,Math.PI*2,true);"+
                    "ctx.stroke();");
        } else {
            throw new IllegalStateException("This driver does not support JavaScript!");
        }
// сохраняем картинку
        driver.findElement(By.xpath("//div[@class='menu-button файл-(f)-menu-button']")).click();
        driver.findElement(By.xpath("//tr[3]")).click();
        driver.findElement(By.xpath("//button[.='Сохранить']")).click();
    }

    

После выполнения теста можно увидеть такую картинку:


Оказалось, нарисовать картинку в онлайн-Пейнте несложно. Нужно всего-то понять, с каким элементом взаимодействовать и выбрать правильный метод этого взаимодействия.

Выводы

Самые необычные задачи – самые интересные. Но и они всегда выполняются по шагам. Если декомпозировать задачу, то ее выполнение значительно облегчается. Да, во время работы сталкиваешься с определенными трудностями, но это того стоит. Трудности закаляют. Удачи!

Материалы по теме

27
Дек
2021

📚 Топ-10 актуальных книг по QA от новичка до профессионала

В этой подборке представлены наиболее авторитетные и фундаментальные издания по тестированию программного обеспечения.

1. Тестирование Дот Ком

<i>Роман Савин, “Тестирование Дот Ком”</i>
Роман Савин, “Тестирование Дот Ком”

Наверное, это самая популярная книга по тестированию на русском языке, которая отлично подходит для начинающих тестировщиков.

Довольно легкий слог повествования и простая подача материала. С этой книгой вы познакомитесь с необходимой начальной терминологией, чтобы быть «в теме» среди отдела качества разработки ПО. Также она поможет понять, что собственно требуется от тестировщика в решении тех или иных задач. Приведены примеры для простоты усвоения материала.

Рекомендую начать свое погружение именно с этой книги.

Книга в сообществе @progbook

2. The Self-Taught Software Tester

Чхави Радж Досадж<i>, “The Self-Taught Software Tester A Step By Step Guide to Learn Software Testing Using Real-Life Project”</i>
Чхави Радж Досадж, “The Self-Taught Software Tester A Step By Step Guide to Learn Software Testing Using Real-Life Project”

Эта книга – отличное введение в тестирование программного обеспечения для любого читателя. Информация представлена грамотно. Следуя примерам в книге, вы почувствуете, что проходите практическое обучение на реальном проекте.

Если ваша цель – стать тестировщиком программного обеспечения, эта книга станет вашим секретным оружием в становлении первоклассным специалистом.

3. Software testing

<i>Рон Паттон, “Software testing”</i>
Рон Паттон, “Software testing”

Еще одна по-настоящему очень полезная книга для начинающих тестировщиков. В ней вы найдете довольно подробную и очень популярно описанную теоретическую базу тестирования. В довесок, приведено множество примеров для лучшего усвоения материала. Читателя завлечет хороший и доступный язык повествования.

Больше полезных материалов вы найдете на нашем телеграм-канале «Книги для программистов».

4. Introducing to Software Testing

<i>Пол Амманн и Джефф Оффатт, “Introducing to Software Testing”</i>
Пол Амманн и Джефф Оффатт, “Introducing to Software Testing”

Возможно, вас заинтересует данная книга, она затрагивает множество концепций направления тестирования, такие как автоматизация, различные тест дизайны и в целом управление процессом тестирования. Конечно, она больше ориентирована на продолжающих свой путь тестировщиков, которые хотят попробовать себя в автоматизации и больше проникнуться техническими аспектами профессии, но каждый найдет в этой книге свое. Книга хорошо структурирована и полна множеством технических аспектов.

Книга в сообществе @progbook

5. Тестирование программного обеспечения

<i>Сэм Канер, Джек Фолк, Енг Кек Нгуен, «Тестирование программного обеспечения. Фундаментальные концепции менеджмента бизнес-приложений».</i>
Сэм Канер, Джек Фолк, Енг Кек Нгуен, «Тестирование программного обеспечения. Фундаментальные концепции менеджмента бизнес-приложений».

Данный труд предназначен в первую очередь для продолжающих специалистов, которые хотят познакомиться с теорией тестирования. Написана сложным языком, довольно объемная и требует внимательности при чтении. Затрагивает все концепции тестирования. Прочитав её, вы поднимите свой уровень в области качества ПО.

В книге много примеров, включая реальные кейсы, что делает книгу суперполезной и практичной.

Книга в сообществе @progbook

6. Искусство тестирования программ

<i>Гленфорд Майерс, Том Баджетт, Кори Сандлер, «Искусство тестирования программ»</i>
Гленфорд Майерс, Том Баджетт, Кори Сандлер, «Искусство тестирования программ»

Одна из основополагающих книг по тестированию, можно сказать, классическая литература в данной области. Для читающего эта книга станет исчерпывающим руководством по всем типам тестирования – от тестирования веб приложений до тестирования безопасности, тестирования совместимости и автоматизации тестирования.

Тут детально рассмотрена психология тестирования и тестирование в гибкой среде, показаны наиболее эффективные способы обеспечения качества для программных продуктов.

7. Complete Guide to Test Automation

<i>Арнон Аксельрод, Complete Guide to Test Automation</i>
Арнон Аксельрод, Complete Guide to Test Automation

В первую очередь эта книга будет полезна для специалистов, которые намерены развиваться в сторону автоматизации тестирования.

Это надежное и подробное руководство, которое поможет создавать и поддерживать автоматизацию на должном уровне. Охватывает все важные темы, а также дает примеры распространенных сценариев в проектах автоматизации.

Книга в сообществе @progbook

8. Идеальное программное обеспечение

<i>Джеральд Вайнберг, «Идеальное программное обеспечение и другие иллюзии в тестировании»</i>
Джеральд Вайнберг, «Идеальное программное обеспечение и другие иллюзии в тестировании»

Эту книгу следует обязательно прочитать всем специалистам в области разработки и тестирования программного обеспечения. Автор хорошо повествует о ценности тестирования, подводных камнях и общих подходах в разработке и управлению тестированием. Хорошо описаны моменты, на чем тестировщикам следует сосредоточиться, когда дело касается софт скиллов и общения внутри и за пределами команды.

Эта книга – реальное напоминание о том, зачем нужны тестировщики и почему тестировщики никогда не могут быть заменены компьютерами.

9. A Practitioner’s Guide to Software Test Design

Ли Коупленд,<i> «A Practitioner’s Guide to Software Test Design»</i>
Ли Коупленд, «A Practitioner’s Guide to Software Test Design»

Еще одна «библия тестировщика», обязательна к прочтению. В этой книге подробно, поэтапно и с понятными примерами дается описание различных техник проектирования тестов. Автор делится огромным количеством ценных советов, которые помогут улучшить вашу работу уже в процессе чтения. Книга с конкретным изложением, без лишней воды и философии, все четко и по делу.

10. Managing the Testing Process

Рекс Блэк<i>, “Managing the Testing Process: Practical Tools and Techniques for Managing Hardware and Software Testing”.</i>
Рекс Блэк, “Managing the Testing Process: Practical Tools and Techniques for Managing Hardware and Software Testing”.

Хорошая книга для более глубокого понимания управления процессом тестирования, отлично подойдет разработчикам, тестировщикам и менеджерам тестирования. В книге представлено прямое описание того, как нужно правильно управлять процессом тестирования. Рассмотрены роли в этом управлении и его обязанности. В качестве повышения уровня компетенций менеджмента в тестировании, книга очень хороша.

Материалы по теме

01
Дек
2021

Порядок тестирования Pytest

Тестирую flask app с помощью pytest, который проходит тесты в порядке расположения директорий, т.е. у меня сначала расположена директория func_tests, потом unit_tests, в результате тесты падают, если поменять расположение директорий, т.е. …

01
Дек
2021

Порядок тестирования Pytest

Тестирую flask app с помощью pytest, который проходит тесты в порядке расположения директорий, т.е. у меня сначала расположена директория func_tests, потом unit_tests, в результате тесты падают, если поменять расположение директорий, т.е. …

23
Ноя
2021

🐧 Тест для новичков: какой дистрибутив Linux выбрать?

В этом тесте мы собрали 36 популярных дистрибутивов Linux и распределили их в зависимости от потребностей пользователя. Вы просто отвечаете на вопросы, а тест сам подберет список подходящих дистрибутивов для соответствующих целей и уровня п…

19
Ноя
2021

«Чёрная пятница» в GeekBrains

На выбор есть факультеты, профессии, программы и курсы по 7 направлениям: программирование, IT-инфраструктура, аналитика, дизайн, маркетинг, менеджмент и школьникам.
— Читать дальше ««Чёрная пятница» в GeekBrains»

15
Ноя
2021

Как протестировать обученную нейросеть на сухом куске текста

У меня есть обученная нейросеть, которая обрабатывает предложения и предсказывает, является ли оно саркастичным или нет. Так выглядит моя база данных

Я ее обучил через RNN и fit следующим образом
model2.fit(sequences_matrix,Y_train, verbo…

13
Ноя
2021

🐍 Создайте автотест Web UI на Python и Selenium за 7 шагов: инструкция для новичков

Если вам нужно тестировать веб-интерфейсы и логику отображения графических блоков на странице или просто автоматизировать работу в браузере, эта статья для вас. Читайте инструкцию по созданию автотеста на Python и Selenium за 7 простых шагов.

Мы будем использовать Selenium совместно с Python версий 3.x.x. Цель статьи – не дать фундаментальные знания по теории программирования и написания автотестов, а заинтересовать в этой области и показать, как они пишутся в целом.

1. Установка необходимых компонентов

Для начала работы нам потребуется установить Python на рабочую машину.

Переходим на официальный сайт Python и качаем установщик для вашей ОС (мы будем использовать Windows). В процессе инсталляции поставьте галочки на добавлении компонентов в системные переменные PATH. Дождитесь завершения процесса, и если программа попросит перезагрузки, перезагрузитесь. Если у вас Linux, интерпретатор может уже присутствовать в системе, в противном случае стоит установить его из репозитория пакетов вашего дистрибутива.

Проверьте корректность установки, перейдите в терминал (в Windows нажмите Win+R и запустите cmd или Alt+Ctrl+T в графической среде Linux). Выполните следующую команду:

        python --version
    
<i>Рис. 1. Должна быть выведена версия, а если что-то не получилось, проверьте выполнение по шагам и повторите попытку</i>
Рис. 1. Должна быть выведена версия, а если что-то не получилось, проверьте выполнение по шагам и повторите попытку

Далее нам понадобится сам Selenium:

        pip install selenium
    

Дождитесь завершения установки. Поскольку мы будем писать тест, воспользуемся популярной библиотекой pytest. Устанавливается она аналогично:

        pip install pytest
    
Для создания приложений нужна интегрированная среда разработки или IDE (integrated development environment), но можно писать код и в обычном текстовом редакторе. Я выбрал самую популярную и удобную среду PyCharm от компании JetBrains.

Чтобы работать с браузером, помимо Selenium потребуется веб-драйвер: в нашем случае ChromeDriver – по сути это связующее звено в цепочке. Обратите внимание, что версия драйвера должна соответствовать версии браузера и вперед – к созданию проекта и написанию первого скрипта.

2. Первый скрипт с использованием драйвера

Все компоненты готовы, давайте создадим новый проект. Для
этого запускаем PyCharm и в открывшимся окне выбираем New Project.

<i>Рис. 2</i>
Рис. 2

Указываем
имя проекта и нажимаем Create.

Рис. 3
Рис. 3

Напишем первый тест, чтобы проверить работоспособность драйвера.

<i>Рис. 4. Пример кода в файле main.py</i>
Рис. 4. Пример кода в файле main.py

В качестве примера ресурса для тестирования возьмем
популярный сайт для практики автоматизированного тестирования: https://www.saucedemo.com.

Кейс:

  • Зайти на страницу.
  • Найти элемент по id.
  • Вывести в консоль сообщение с результатом поиска.
main.py
        from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/.../.../chromedriver.exe')
driver.get("https://www.saucedemo.com/")
input_username = driver.find_element_by_id("user-name")
if input_username is None:
   print("Элемент не найден")
else:
   print("Элемент найден")

    

После
ввода кода необходимо установить библиотеку Selenium в наш проект.

Для
этого нажмите на подсвеченный текст в редакторе, нажмите Alt + Enter и далее
выберите Install package selenium. Это нужно делать для
каждого неустановленного пакета.

<i>Рис. 5. Пример установки пакета в проект</i>
Рис. 5. Пример установки пакета в проект

Запустить сценарий можно во встроенном эмуляторе терминала IDE или в любом другом:

        python main.py
    
<i>Рис. 6. <span>Пример
запуска скрипта из IDE</span></i>
Рис. 6. Пример
запуска скрипта из IDE

Если все установлено правильно, должен запуститься браузер,
который откроет страницу. Результатом запуска нашего сценария на Python, будет
сообщение: “Элемент найден”.

Рис. 7. Результат выполнения скрипта.
Рис. 7. Результат выполнения скрипта.

3. Поиск элементов

В нашем скрипте присутствует следующая строка:

        input_username = driver.find_element_by_id("user-name")
    
Метод find_element_by_id позволяет процессу найти элемент в разметке HTML по наименованию атрибута id. В реализации драйвера есть несколько способов поиска элементов на странице: по name, xpath, css, id. Поиск по css и xpath являются более универсальным, но он сложнее для начинающих. Использование поиска по name и id намного удобнее, но в практической разработке используется редко. Далее я буду использовать только xpath.

Теперь
давайте напишем кейс аутентификации пользователя на странице входа:

  • Шаг 1: пользователь вводит корректный username и password.
  • Шаг 2: нажимает кнопку ввода.
  • Ожидаемый результат: пользователь попадает на главную страницу магазина. Проверка заголовка на соответствие “PRODUCTS”.
main.py
        import time

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


def first_test():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/.../.../chromedriver.exe')
    driver.get("https://www.saucedemo.com/")

    # Поиск элементов и присваивание к переменным.
    input_username = driver.find_element_by_xpath("//*[@id=\"user-name\"]")
    input_password = driver.find_element_by_xpath("//*[@id=\"password\"]")
    login_button = driver.find_element_by_xpath("//*[@id=\"login-button\"]")

    # Действия с формами
    input_username.send_keys("standard_user")
    input_password.send_keys("secret_sauce")
    login_button.send_keys(Keys.RETURN)

    # Поиск и проверка попадания на главную страницу
    title_text = driver.find_element_by_xpath("//*[@id=\"header_container\"]/div[2]/span")
    if title_text.text == "PRODUCTS":
        print("Мы попали на главную страницу")
    else:
        print("Ошибка поиска элемента")

    time.sleep(5)


if __name__ == '__main__':
    first_test()

    

Разберем
пример пошагово:

  • Для работы с формой найдем и присвоим элементы переменным input_username, input_password и login_button с помощью xpath.
  • Далее вызовем для элемента метод send_keys с данными, которые хотим передать в текстовое поле. В нашем случае в username отправляем “standart_user”, в password“secret_sauce”. Проецируя поведение пользователя нажимаем Enter для ввода данных, используя метод send_keys для найденной кнопки с переданным аргументом Keys.RETURN. Этот аргумент позволяет работать с действиями клавиатуры в Selenium, аналогично нажатию на Enter на клавиатуре.
  • На главном экране нам необходимо найти и присвоить переменной элемент текста Products. Как я говорил раннее, не всегда есть возможность найти элемент по id – здесь как раз тот случай.
        title_text = driver.find_element_by_xpath("//*[@id=\"header_container\"]/div[2]/span")
    
  • Путь xpath до элемента: //*[@id=\"header_container\"]/div[2]/span.
  • Чтобы найти путь xpath, зайдите на https://www.saucedemo.com и нажмите F12, чтобы открыть инструменты разработчика. Затем выберите стрелку-указатель и кликните по элементу до которого хотите найти путь. В нашем случае до Products.
<i>Рис 8. Поиск xpath элемента в инструментах разработчика</i>
Рис 8. Поиск xpath элемента в инструментах разработчика
  • Откроется код элемента в дереве HTML, далее нужно открыть контекстное меню выделенной строки и скопировать xpath.
<i>Рис 9. Копирование пути xpath</i>
Рис 9. Копирование пути xpath
Если кратко рассматривать путь, то //* обозначает, что будут найдены все элементы на странице, а [@id=\"header_container\"] обозначает условие поиска (будут найдены все элементы на странице с тэгом id = "header_container").И далее /div[2]/span – спускаемся на второй дочерний элемент div и далее на дочерний элемент span. Сравните полученный xpath с деревом элемента в инструментах разработчика – сразу станет понятно что к чему.

  • Тут мы просто сравниваем текст найденного элемента с ожидаемым значением и выводим в консоль сообщение.
main.py
        if title_text.text == "PRODUCTS":
    print("Мы попали на главную страницу")
else:
    print("Ошибка поиска элемента")

    

При выполнении скрипта получили следующий результат:

Рис 10. Результат выполнения скрипта
Рис 10. Результат выполнения скрипта

4. Первый тест с поиском и переходом по странице

Кейс:

  • Введем логин и пароль пользователя и зайдем на главную страницу.
  • Найдем позицию с названием “Sauce Labs Fleece Jacket”.
  • Перейдем на страницу товара и нажмем кнопку добавления в корзину.
  • Перейдем в корзину и проверим что там присутствует 1 позиция с названием “Sauce Labs Fleece Jacket”.
main.py
        import time

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


def first_test():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/…/…/chromedriver.exe')
    driver.get("https://www.saucedemo.com/")

    # Поиск элементов и присваивание к переменным.
    input_username = driver.find_element_by_xpath("//*[@id=\"user-name\"]")
    input_password = driver.find_element_by_xpath("//*[@id=\"password\"]")
    login_button = driver.find_element_by_xpath("//*[@id=\"login-button\"]")

    # Действия с формами
    input_username.send_keys("standard_user")
    input_password.send_keys("secret_sauce")
    login_button.send_keys(Keys.RETURN)

    # Поиск ссылки элемента позиции магазина и клик по ссылке
    item_name = driver.find_element_by_xpath("//*[@id=\"item_5_title_link\"]/div")
    item_name.click()

    # Поиск кнопки добавления товара и клик по этой кнопке
    item_add_button = driver.find_element_by_xpath("//*[@id=\"add-to-cart-sauce-labs-fleece-jacket\"]")
    item_add_button.click()

    # Поиск кнопки коризины и клик по этой кнопке
    shopping_cart = driver.find_element_by_xpath("//*[@id=\"shopping_cart_container\"]/a")
    shopping_cart.click()

    # Еще один поиск ссылки элемента позиции магазина
    item_name = driver.find_element_by_xpath("//*[@id=\"item_5_title_link\"]/div")
    if item_name.text == "Sauce Labs Fleece Jacket":
        print("Товар пристутствует в корзине")
    else:
        print("Товар отсутствует")

    time.sleep(5)


if __name__ == '__main__':
    first_test()

    

Из
нового тут добавился только метод click(), который просто кликает по
найденному элементу.

После прохождения всех шагов в консоль выводится результат, что в
корзине имеется товар.

Ожидания в selenium: что нужно знать?

В предыдущем кейсе с большой вероятностью можно столкнуться с проблемой, когда при нажатии на позицию мы сразу кликаем на корзину. При медленном интернете или долгом ответе от сервера в корзину может ничего не добавиться. Для таких случаев предусмотрены ожидания.

Selenium driver поддерживает два вида ожиданий: явное (explicit) и неявное (implicity). Для явных ожиданий есть специальные методы, которые помогут рационально использовать время выполнения теста: например, можно установить минимальное время ожидания и возвращать элемент, если он прогрузился раньше предполагаемого времени.

Пример явного ожидания:

        element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable(
        (By.XPATH, '//*[@id=\"page_wrapper\"]/footer/ul/li[2]/a')
    )
)

    

Процесс ждет 10 секунд пока элемент станет доступным, чтобы по
нему можно было кликнуть. Если элемент так и не прогрузился и недоступен для
клика, генерируется исключение TimeoutException.

Неявные ожидания в свою очередь устанавливаются один раз для
драйвера, а не для каждого элемента. Включается неявное ожидание, когда Selenium не может найти элемент: он ждет установленное время и если не дождется, тоже возвращает TimeoutException. В отличии от явного ожидания, этот тип менее гибок и может оказать плохое влияние на общее время прогона
тестов.

Пример неявного ожидания:

        driver.implicitly_wait(10)
    

Ожидать действия можно и с помощью time.sleep(5). У нас в
примерах есть использование этого метода, но оно считается плохой практикой и обычно применяется только для дебага.

5. Рефакторинг теста, добавление ожиданий

Чтобы
pytest понял, что перед ним именно тестовая, а не обычная функция, сама тестовая функция
должна начинаться с test_.

Обновим наш тест, добавим необходимые ожидания для
стабильности тестовых функций.

Также я вынес отдельную функцию под ожидания, куда мы просто
передаем xpath и driver в виде аргументов.

main.py
        from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
import time

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


# Функция ожидания элементов
def wait_of_element_located(xpath, driver):
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located(
            (By.XPATH, xpath)
        )
    )
    return element


def test_add_jacket_to_the_shopcart():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/…/…/chromedriver.exe')
    driver.get("https://www.saucedemo.com/")

    # Поиск и ожидание элементов и присваивание к переменным.
    input_username = wait_of_element_located(xpath='//*[@id=\"user-name\"]', driver=driver)
    input_password = wait_of_element_located(xpath='//*[@id=\"password\"]', driver=driver)
    login_button = wait_of_element_located(xpath='//*[@id=\"login-button\"]', driver=driver)

    # Действия с формами
    input_username.send_keys("standard_user")
    input_password.send_keys("secret_sauce")
    login_button.send_keys(Keys.RETURN)

    # Поиск и ождиание прогрузки ссылки элемента товара магазина и клик по ссылке
    item_name = wait_of_element_located(xpath='//*[@id=\"item_5_title_link\"]/div', driver=driver)
    item_name.click()

    # Поиск и ожидание кнопки добавления товара и клик по этой кнопке
    item_add_button = wait_of_element_located(xpath='//*[@id=\"add-to-cart-sauce-labs-fleece-jacket\"]', driver=driver)
    item_add_button.click()

    # Ждем пока товар добавится в корзину, появится span(кол-во позиций в корзине) и кликаем по корзине чтобы перейти
    wait_of_element_located(xpath='//*[@id=\"shopping_cart_container\"]/a/span', driver=driver).click()

    # Еще один поиск ссылки элемента позиции магазина
    item_name = wait_of_element_located(xpath='//*[@id=\"item_5_title_link\"]/div', driver=driver)
    if item_name.text == "Sauce Labs Fleece Jacket":
        print("Товар пристутствует в корзине")
    else:
        print("Товар отсутствует")

    time.sleep(5)


if __name__ == '__main__':
    test_add_jacket_to_the_shopcart()

    

Для запуска теста с помощью pytest в терминале введите
pytest main.py. После прохождения всех этапов должен отобразиться результат
прохождения.

6. Проверки, проверки, проверки

Мы плавно перешли к заключительному этапу написания теста – проверке вывода по известному ответу. Хотя тест выполняется успешно, он ничего
не проверяет и является бессмысленным. Будем использовать
стандартные инструкции assert или утверждения. Суть инструмента – проверить, что результат соответствует наши ожиданиям. Если соответствует, наш тест будет
считаться пройденным, а в противном случае – проваленным.

Добавим в тест проверки. Будем проверять, что название
куртки “Sauce Labs Fleece Jacket” и описание как в магазине.

main.py
        from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


# Функция ожидания элементов
def wait_of_element_located(xpath, driver):
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located(
            (By.XPATH, xpath)
        )
    )
    return element


def test_add_jacket_to_the_shopcart():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/…/…/chromedriver.exe')
    driver.get("https://www.saucedemo.com/")

    # Поиск и ожидание элементов и присваивание к переменным.
    input_username = wait_of_element_located(xpath='//*[@id=\"user-name\"]', driver=driver)
    input_password = wait_of_element_located(xpath='//*[@id=\"password\"]', driver=driver)
    login_button = wait_of_element_located(xpath='//*[@id=\"login-button\"]', driver=driver)

    # Действия с формами
    input_username.send_keys("standard_user")
    input_password.send_keys("secret_sauce")
    login_button.send_keys(Keys.RETURN)

    # Поиск и ождиание прогрузки ссылки элемента товара магазина и клик по ссылке
    item_name = wait_of_element_located(xpath='//*[@id=\"item_5_title_link\"]/div', driver=driver)
    item_name.click()

    # Поиск и ожидание кнопки добавления товара и клик по этой кнопке
    item_add_button = wait_of_element_located(xpath='//*[@id=\"add-to-cart-sauce-labs-fleece-jacket\"]', driver=driver)
    item_add_button.click()

    # Ждем пока товар добавится в корзину, появится span(кол-во позиций в корзине) и кликаем по корзине чтобы перейти
    wait_of_element_located(xpath='//*[@id=\"shopping_cart_container\"]/a/span', driver=driver).click()

    # Еще один поиск ссылки элемента позиции магазина
    item_name = wait_of_element_located(xpath='//*[@id=\"item_5_title_link\"]/div', driver=driver)

    item_description = wait_of_element_located(
        xpath='//*[@id=\"cart_contents_container\"]/div/div[1]/div[3]/div[2]/div[1]',
        driver=driver
    )

    assert item_name.text == "Sauce Labs Fleece Jacket"
    assert item_description.text == "It's not every day that you come across a midweight quarter-zip fleece jacket capable of handling everything from a relaxing day outdoors to a busy day at the office."

    driver.close()


if __name__ == '__main__':
    test_add_jacket_to_the_shopcart()

    

Теперь при расхождении результата и ожидаемого
условия будет возвращена ошибка прохождения. Укажем название куртки “Sauce Labs Fleece Jacket1”. Результат выполнения скрипта будет следующим:

Рис 11. Результат выполнения теста.
Рис 11. Результат выполнения теста.

7. Распределим логику

Теперь причешем код, распределив логику по
методам, как, например, было с wait_of_element_located. Разбивать логику необходимо
для написания множества тестов.

main.py
        import pytest
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


# Функция ожидания элементов
def wait_of_element_located(xpath, driver_init):
    element = WebDriverWait(driver_init, 10).until(
        EC.presence_of_element_located(
            (By.XPATH, xpath)
        )
    )
    return element


# Вынесем инициализцию драйвера в отдельную фикстуру pytest
@pytest.fixture
def driver_init():
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    driver = webdriver.Chrome(options=options, executable_path=r'C:/Users/…/…/chromedriver.exe')
    driver.get("https://www.saucedemo.com/")
    yield driver
    driver.close()


# Вынесем аутентификацию юзера в отдельную функцию
def auth_user(user_name, password, driver_init):
    # Поиск и ожидание элементов и присваивание к переменным.
    input_username = wait_of_element_located(xpath='//*[@id=\"user-name\"]', driver_init=driver_init)
    input_password = wait_of_element_located(xpath='//*[@id=\"password\"]', driver_init=driver_init)
    login_button = wait_of_element_located(xpath='//*[@id=\"login-button\"]', driver_init=driver_init)

    # Действия с формами
    input_username.send_keys(user_name)
    input_password.send_keys(password)
    login_button.send_keys(Keys.RETURN)



def add_item_to_cart(xpath_item, driver_init):
    # Поиск и ождиание прогрузки ссылки элемента товара магазина и клик по ссылке
    item_name = wait_of_element_located(
        xpath=xpath_item,
        driver_init=driver_init)
    item_name.click()

    # Поиск и ожидание кнопки добавления товара и клик по этой кнопке
    item_add_button = wait_of_element_located(
        xpath='//*[@id=\"add-to-cart-sauce-labs-fleece-jacket\"]',
        driver_init=driver_init)
    item_add_button.click()

    # Ждем пока товар добавится в корзину, появится span(кол-во позиций в корзине)
    # Возвращаем True или False в зависимости добавлися товар или нет
    shop_cart_with_item = wait_of_element_located(
        xpath='//*[@id=\"shopping_cart_container\"]/a/span',
        driver_init=driver_init)
    return shop_cart_with_item


def test_add_jacket_to_the_shopcart(driver_init):
    # Аутентификация пользователя
    auth_user("standard_user", "secret_sauce", driver_init=driver_init)

    # Добавление товара в корзину и если товар добавлен переход в корзину
    add_item_to_cart(xpath_item='//*[@id=\"item_5_title_link\"]/div',
                     driver_init=driver_init).click()
    # Поиск корзины и клик
    wait_of_element_located(xpath='//*[@id=\"shopping_cart_container\"]/a',
                            driver_init=driver_init).click()

    # Поиск ссылки элемента позиции магазина
    item_name = wait_of_element_located(xpath='//*[@id=\"item_5_title_link\"]/div',
                                        driver_init=driver_init)

    # Поиск описания товара
    item_description = wait_of_element_located(xpath='//*[@id=\"cart_contents_container\"]/div/div[1]/div[3]/div[2]/div[1]',
                                               driver_init=driver_init)

    assert item_name.text == "Sauce Labs Fleece Jacket"
    assert item_description.text == "It's not every day that you come across a midweight quarter-zip fleece jacket" \
                                    " capable of handling everything from a relaxing day outdoors to a busy day at " \
                                    "the office."


if __name__ == '__main__':
    test_add_jacket_to_the_shopcart(driver_init=driver_init)

    
В этом примере логика поделилась на функциональные компоненты (фикстуры). Теперь аутентификация пользователя будет происходить в отдельной функции, что позволит не производить одни и те же действия и дублировать код при каждом тесте, в котором нужно проходить аутентификацию. В качестве примера использования фикстур сделана инициализация драйвера, что позволит использовать инстанс драйвера во всех тестах, не пересоздавая его. Логика добавления товара в корзину тоже была вынесена в отдельный функциональный компонент для дальнейшего использования.

Суть разнесения логики заключается в принципе конструктора: собирать тесты из отдельных частей, подставляя только необходимые данные при переиспользовании функций в разных тестах.

При желании можно и дальше проводить рефакторинг кода.

Рекомендации по архитектуре

  • Очевидно, что в одном файле хранить все вспомогательные функции и тесты неудобно. После добавления еще нескольких тестов даже с распределенной логикой скрипт будет похож на полотно с трудночитаемым кодом. К тому же если вы разрабатываете тесты с коллегами, без конфликтов в коде не обойтись. Для начала нужно разделить проект на модули: в одном будут находиться файлы с тестами, в другом частичная логика, в третьем – ресурсы, в четвертом – утилиты и т.д.
  • Далее следует переходить на разработку автотестов с использованием объектно-ориентированного программирования. Это сэкономит массу времени и поможет в написании сложного и лаконичного кода.
  • Стоит также обратить внимание на паттерны проектирования, особенно на PageObject и PageFactoroy. В эффективном тестировании UI они играют большую роль.
  • Все тестовые данные лучше хранить в неизменяемых классах, константах или в отдельных файлах (json, csv).

Заключение

На этом создание первого автотеста закончено. Некоторые
моменты были рассмотрены поверхностно, что дает возможность пытливым умам
поглотить информацию из других источников. Удачи!

08
Ноя
2021

One Day Offer в MTC Digital

Мероприятие на котором можно попасть в МТС Digital за день. Ищут специалистов, которые хотят поработать над флагманским приложением экосистемы МТС.
— Читать дальше «One Day Offer в MTC Digital»

17
Окт
2021

Запрос GET в Postman срабатывает через раз, когда переменным в Environment присваиваются Динамические переменные

Тестирую API https://petstore.swagger.io
У меня два метода:
POST создает Юзера. Вот этот https://petstore.swagger.io/#/user/createUser
В body запроса:
{
"id": {{$randomInt}},
"username": "{{usr}}",