company_banner

Что ещё мы проверяем при помощи Selenium, кроме логики интерфейса

    Привет, Хабр!

    Меня зовут Виталий Котов, я работаю в отделе тестирования Badoo. Большую часть времени я работаю с Selenium. Этот замечательный инструмент мы используем для решения разнообразных задач: от тестирования функционала до упрощения работы с логами ошибок и проверки взаимодействия с API.

    О том, какие задачи нам помогает решать Selenium, и пойдёт речь в этой статье. Поехали! :)



    Немного о Selenium


    Первое, что расскажет нам Google по запросу “Selenium”:

    Selenium — это инструмент для автоматизации действий веб-браузера. В большинстве случаев используется для тестирования Web-приложений, но этим не ограничивается.

    Selenium позволяет делать почти то же самое, что мы могли бы делать руками: открывать страницы и взаимодействовать с ними. Однако он делает это быстрее и надёжнее, так как у него не может “замылиться” глаз и он не может по ошибке кликнуть не туда.

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

    Проверка функционала


    Что обычно пользователи делают на сайте? Они его открывают, кликают туда-сюда, видят какие-то результаты своих кликов: редиректы, попапы, подсветку элементов и так далее. Этот процесс хочется (и нужно) тестировать. Необходимо удостовериться, что пользователь увидит именно тот отклик на своё действие, который заложен в нашей бизнес-логике.

    Для этого создаются сценарии, которые описывают действия пользователей. Например:

    1. Открыть сайт.
    2. Кликнуть на кнопку авторизации.
    3. Дождаться загрузки формы авторизации.
    4. Ввести логин и пароль.
    5. Кликнуть на кнопку сабмита.
    6. Дождаться редиректа на авторизованную страницу.

    Если на сайте сломана авторизация (например, программист что-то напутал — и метод getUser теперь всегда возвращает false), у Selenium не получится пройти шаг 6. Тест упадёт и сообщит нам об этом. На деле же где-то в коде будет брошен Exception, и процесс завершится соответствующим кодом ошибки.

    Такая последовательность действий называется функциональным тестированием. Это, пожалуй, самый распространённый способ использования Selenium. Но бывают и более интересные.

    Сбор JS-ошибок


    Обычный пользователь JS-ошибки не видит. Это и правильно — ему незачем. А вот разработчикам важно понимать, не “стреляет” ли их код в каких-то случаях. JS-ошибки я бы разделил в данном контексте на два вида: заметные пользователю и те, которые пользователю не мешают.

    С первым видом ошибок всё понятно. Если на сайте из-за JS-ошибки не произойдёт отклика на действие пользователя, Selenium-тест это заметит.

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

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

    Наши Selenium-тесты проверяют все самые популярные действия, которые совершают пользователи на сайте. Если ошибка есть, она наверняка произойдёт во время прохождения этих тестов. Достаточно просто научить Selenium обращать на такие ошибки внимание.

    Решал я эту задачу следующим образом: добавил темплейт, который подключался только для тестовых серверов. В этом темплейте был кусочек JS-кода, который собирал JS-ошибки в определённый объект. Как-то так:

        var errorObj = {
            _errors : [],
    
            addError : function(message, source, lineno) {
                this._errors.push(
                    "Message: " + message + "\n" +
                    "Source: " + source + "\n" +
                    "Line: " + lineno
                );
            },
    
            getErrors : function() {
                return this._errors;
            }
        }
    
        window.onerror =  function(message, source, line_no) {
            errorObj.addError(message, source, line_no);
        }
    

    То же самое можно было бы делать в самом Selenium-тесте при помощи команды execute. Она позволяет исполнять JS-код на странице так, будто пользователь открыл консоль браузера и исполнил код в ней. Но тогда мы могли бы упустить часть ошибок.

    Дело в том, что исполнить этот код в Selenium-тесте можно только после полной загрузки страницы. Следовательно, все ошибки, которые появятся в ходе самой загрузки, останутся незамеченными. С темплейтом такой проблемы нет, поскольку код в нём исполняется до основного JS-кода.

    После добавления темплейта все ошибки начали собираться в объект errorObj, доступный глобально. И вот теперь можно было использовать команду execute. Я добавил в наш Selenium-фреймворк метод, который исполнял errorObj.getErrors(), то есть получал все ошибки, которые попали в errorObj, и сохранял их на стороне самого Selenium-теста.

    Напомню, что Selenium-тесты мы пишем на PHP. Код сбора ошибок получился примерно такой:

        public function collectJsErrors()
        {
            $return_errorObj = /** @lang JavaScript */
                'if (typeof errorObj !== "undefined") {return errorObj.getErrors();} else {return null;}';
    
            $js_result = $this->execute($return_errorObj)->sync();
    
            foreach ($js_result as $result) {
                $current_stacktrace = $result;
    
                //check if an error is known
                foreach (self::$known_js_errors as $known_error) {
                    if (strpos($current_stacktrace, $known_error) !== false) {
                        continue 2;
                    }
                }
    
                //check if the error already caught
                foreach ($this->getJsErrors() as $error) {
                    $existed_stacktrace = $error['error'];
                    if ($current_stacktrace == $existed_stacktrace) {
                        continue 2;
                    }
                }
    
                //collect an error
                $this->addJsError([
                    'error' => $result,
                    'location' => $this->getLocation(),
                ]);
            }
        }
    

    Мы получаем ошибки из JS-объекта errorObj и каждую обрабатываем.

    Некоторые ошибки нам уже известны. Мы знаем, что они есть на проекте и либо уже находятся в процессе исправления, либо воспроизводятся только в “лабораторных” условиях. Например, ошибки, которые появляются только для тестовых пользователей и которые связаны с тем способом, которым мы их подготовили к тесту. Такие ошибки в тесте мы игнорируем.

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

    Для каждой новой ошибки мы добавляем URL и сохраняем всю информацию в массив.

    Метод collectJsErrors() мы вызываем после каждого действия на сайте: открытие страницы, ожидание и клик по элементу, ввод каких-то данных и так далее. Как бы мы ни взаимодействовали с интерфейсом, мы обязательно убеждаемся, что это действие не стало причиной возникновения ошибки.

    Массив с собранными ошибками мы проверяем только в конце теста в tearDown(). Ведь если ошибка как-то затронет пользователя, тест и так упадёт. А если не затронет, то ронять тест сразу плохо, сначала нужно проверить сценарий до конца. Вдруг за этой ошибкой есть более серьёзные проблемы.

    Таким образом нам удалось научить Selenium-тесты отлавливать клиентские ошибки. А сами ошибки стало проще воспроизводить, зная, какой тест их ловит.

    Проверка вёрстки


    Сами по себе Selenium-тесты не предназначены для проверки вёрстки. Конечно, если элемент, с которым придётся взаимодействовать, невидим или скрыт другим элементом, тест нам об этом “скажет”. Такое Selenium умеет делать “из коробки”. А вот если кнопка уехала куда-то вниз и выглядит плохо, тут уже Selenium-тесту в целом всё равно — его задача по ней кликнуть…

    Тем не менее проверять вёрстку вручную перед каждым релизом (а для Desktop Web, например, у нас их два в день) на каждой странице, на каждом браузере — это долго. Да и снова может вмешаться человеческий фактор: глаз “замыливается”, о чём-то можно забыть… Нужно этот процесс как-то автоматизировать.

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

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

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

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

    Для получения скриншотов писем пришлось прибегнуть к некоторой хитрости. Дело в том, что получить HTML сгенеренного письма в тесте значительно проще, чем зайти на реальный почтовый сервис (а мы говорим всё ещё про Selenium-тесты), найти там нужное письмо, открыть его и сделать скриншот. Просто потому, что получить HTML письма можно на нашей стороне, используя “бекдор” (у нас есть инструмент QaAPI, который позволяет в тестовом окружении для тестовых пользователей с помощью простого cURL-запроса получать данные о конкретном пользователе и манипулировать ими). А вот для стороннего сервиса пришлось бы писать, стабилизировать и поддерживать Page Object’ы: локаторы, методы и так далее.

    Понятно, что почти все почтовые клиенты отображают письмо несколько иначе, чем мы это увидим на “голом” HTML. Но какие-то серьёзные ошибки в вёрстке, ломающие внешний вид письма даже вне контекста, таким образом успешно ловятся.

    Но что делать с полученным HTML? Как убедиться, что он отображается корректно во всех браузерах? Оказалось, довольно просто. На нашем коллекторе есть пустая страничка, куда может зайти Selenium-тест и выполнить простой execute:

        public function drawMailHTML(string $html)
        {
            $js = /** @lang JavaScript */
                'document.write("{HTML}")';
            $js = str_replace('{HTML}', $html, $js);
            $this->execute($js)->sync();
        }
    

    Если выполнить это на нужном браузере, можно увидеть, как HTML будет в нём выглядеть. Осталось только сделать скриншот и отправить его в тот же коллектор.

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

    Для решения этой задачи можно прибегнуть к простому сравнению картинок по пикселям. В этом случае придётся учесть все переменные, которые есть на вашем проекте. В примере с письмом, например, это могут быть имя пользователя и его фотография. В таком случае прежде чем делать скриншот, придётся чуток подправить HTML, заменив картинки и имена на дефолтные. Или же генерить письма для пользователей с одинаковыми именем и фото. :)

    Для менее постоянного контента таких манипуляций может быть гораздо больше.

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

    В PHP для этих целей отлично подходит библиотека ImageMagick. Также подобные тесты у нас пишут JavaScript-разработчики, они используют Resemble.js.

    В качестве примера можно рассмотреть страницу авторизации Badoo:



    Допустим, по какой-то причине потерялся чекбокс «запомнить меня». Из-за этого кнопка сабмита оказалась чуть выше. Тогда дифф будет выглядеть следующим образом:



    На картинке фиолетовым отмечены расхождения между эталонным скриншотом и тем, на котором не хватает элемента. Сразу видно, что именно не так.

    Системе сравнения можно задать критическое количество пискелей, и если ни один скриншот не превышает это количество, можно слать уведомление, что все хорошо. Если же какие-то скриншоты стали отличаться существенно — бить в набат…

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

    Проверка взаимодействия клиента с API


    В Badoo все клиенты (Desktop Web, Mobile Web, Android- и iOS-приложения) общаются с сервером по определённому API, основанному на HTTP. У такого подхода есть ряд преимуществ. Например, намного проще разрабатывать клиенты и сервер параллельно.

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

    Чтобы мониторить такие вещи ещё на этапе разработки и тестирования, мы тоже используем Selenium-тесты. В начале этих тестов мы генерим cookie, которую называем “device id”. Её значение мы передаём на сервер, который для данного “device id” начинает записывать все API-запросы, которые к нему приходят.

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

    По окончании тестов мы отправляем серверу сигнал о прекращении записи. Сервер генерит специальный лог, по которому можно понять, сколько запросов каких типов было сделано. Если это количество отклоняется от эталонного более чем на N процентов, автотестировщикам приходит специальное уведомление, и мы начинаем разбираться в ситуации. Иногда это поведение ожидаемое (например, при появлении нового запроса, связанного с новым функционалом на сайте) — тогда мы корректируем эталонные значения. А иногда оказывается, что клиент по ошибке создаёт лишние запросы, и это нужно исправить.

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



    Каждый цвет обозначает определённый тип запроса. Если какой-то запрос станет повторяться чаще, визуально это будет заметно. На этот случай у нас тоже есть специальное уведомление, так что не нужно заходить и смотреть статистику перед каждым релизом.

    Серверные логи


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

    В самом начале любого Selenium-теста создаётся специальная cookie “testname”, в которую мы передаём название текущего теста. Соответственно, если ошибка на сервере сгенерилась во время прохождения автотеста, воспроизвести её в большинстве случаев проще, так как мы знаем сценарий воспроизведения. Чтобы найти задачу, из которой ошибка пришла в релиз, можно запустить Selenium-тест на всех релизящихся задачах и посмотреть их логи.

    У нас этот процесс автоматизирован, об этом я писал в предыдущей статье.

    В целом такой подход позволяет намного быстрее разбираться с серверными ошибками в релизе и локализовывать их.

    Автоматический заказ пиццы в пятницу вечером


    А почему, собственно, нет? :)



    Итоги


    Selenium — это инструмент, позволяющий манипулировать браузером. А как именно и зачем, это уже решать тем, кто этот инструмент использует. Проявив смекалку, можно существенно облегчить себе жизнь.

    Само собой, для некоторых видов проверок существуют свои, более подходящие, инструменты. Например, Selenium не сможет полноценно заменить сканеры уязвимостей или быстрые парсеры, написанные, скажем, на cURL-библиотеках. Также его довольно странно использовать для нагрузочного тестирования — в этом случае скорее удастся проверить отказоустойчивость Selenium-фермы, нежели боевого приложения. :)

    Однако есть некий набор задач, для которых Selenium отлично подходит. Я рассказал о том, как он помогает нам. Буду рад услышать об интересных способах использования Selenium в ваших компаниях.

    Спасибо за внимание.
    Badoo 354,31
    Big Dating
    Поделиться публикацией
    Комментарии 36
    • +2
      Ребята, есть штуки вроде Sentry, их можно даже в production использовать (особенно полезно для отлова тяпляпов из-за разработчиков браузерных расширений). Самое главное, там есть вещь, которая называется breadcrumbs — в них вы можете записать цепочку действий, которая приводит к возникновению ошибки.
      Есть еще один момент с Sentry — она умеет отлавливать ошибки из разных кодовых баз, например из PHP и JS. Это удобно, когда какая-нибудь PHP-ошибка вызывает ошибку в JS.
      • +3
        Привет. Когда я готовил статью, я узнавал у наших ребят из фронтэнда, как именно они собирают логи с клиента. Мне рассказали о Sentry в том числе, но сказали, что мы свою систему сборки писали примерно в то же время или чуть раньше. Тогда на рынке ничего подходящего не нашлось.

        Насколько я понял, наша система в целом работает аналогично. Мои коллеги из разработки меня поправят, если я не прав.
        • +1
          А вы не могли бы рассказать, как вы добились стабильной работы Selenium? На моей практике половина тестов сваливалась с таймаутами или просто web-driver зависал.
          • +1
            Вы имеете в виду — в целом или конерктно со сборкой JS-ошибкой?

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

            Если Вы про сбор JS-ошибкок, то там с нестабильностью проблем не было.
            • +1
              Вы что-то не так делаете. Мой рекорд — трое суток непрерывной работы тестов (проверка отображения около 100 тыс единиц сложного контента). Не обошлось без подводных камней, например, в Хроме при работе с Selenium почему-то не запускается уборка мусора в Javascript, поэтому когда элементы на страничке обновляются без перезагрузки (ajax) через пару часов браузер сжирал несколько гигабайт оперативной памяти при одной открытой вкладке и падал. Все решилось принудительным перезапуском после проверки N единиц контента ( параметр подбирали по опыту)
              • 0
                тесты последовательные были или параллельные? если параллельные, то сколько потоков?
                • 0
                  последовательные, но по оршанизационным причинам: наш тестовый сервер использовался и для других тестов, запуск в несколько потоков мог замедлять их тоже. Кроме того, в работе использовался самописный фреймворк-надстройка над селениум(содержащий абстракции для нашего контента), который не был thread safe, а на его обновление времени не было.
              • 0
                Главное и основное правило не использовать голый Selenium Webdriver. Такой подход имеет много недостатков. Лучше применить какой-нибудь «фреймворк» на основе Webdriver — в мире java например популярен Selenide.
            • +3
              Да, спасибо, мы знаем про sentry — отличное решение, но у нас для сбора и агрегации клиентских ошибок уже достаточно давно написано свое, и оно по-сути очень похоже на то как работает sentry/raven.js. Тут же речь именно про препродакшн тестирование и про то, что нам важно не только как интерфейс выглядел, но и то что при этом не сыпались какие-нибудь ошибки, и если все же сыпались — то вот как мы их привязываем к результату прогона
            • +2
              Перед тем как заказать пиццу, можно ещё заполнять таймшиты и создавать ITSM тикеты.

              Мы еще сделали browser-extension в помощь тестерам, сохраняет скриншоты и данные последних N просмотренных страниц, позволяет их просмотреть вместе с query string, post data и т.п., сохранить всё как PDF и послать разработчикам, чтобы было видно какие шаги привели к проблеме.
              • +2
                Привет.
                У нас есть похожее решение, но его автор не я. Я попрошу автора выделить время и рассказать. :)
                • +2

                  Интересный функционал. Мы рассматривали BugReplay, но в итоге просто иногда записываем видео (когда надо) и почти всегда пишем HAR. Этого вполне достаточно (пока).
                  Но как мы знаем, аппетит приходит во время еды и пока функционала нет, то его никто и не просит.
                  Вы это расширение где-то опубликовали?

                  • +1
                    Нет, не публиковали. Там есть некоторая часть которая специфичная только для нашего проекта, поэтому смысла не видели. На самом деле там наверное всего строчек 100-150, так что художественной ценности не представляет.

                    Еще одно интересное расширение делали, позволяет открыть два окна (например одно в QC, а другое в production) и синхронизировать навигацию и скроллинг между ними.

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

                    К сожалению универсально реализовать сложно, так что тоже сильно гвоздями прикручено к нашей специфике.
                • +1
                  Подскажите пожалуйста про вот эти штуки:

                  /** lang JavaScript */

                  Это IDE? Если да — та какие IDE это поддерживают? Или это для каких-то других целей?
                  • 0
                    Как минимум PhpStorm, но есть подозрение, что и другие Idea-based IDE
                    • +1
                      Привет.
                      Да, это для IDE. Для PHPStrom. В этом случае он подсвечивает код внутри строки так, как JS-код.
                  • +1

                    При помощи WD можно еще свою психику проверять. Этот функционал работает даже лучше чем основной.

                    • +1
                      Нет, что Вы… Настоящая проверка психики — угадать, как поведет себя тот или иной код на JavaScript. Например, вот:

                      null > 0
                        false
                      
                      null < 0
                        false
                      
                      null == 0
                        false
                      
                      null >= 0
                        true
                      
                    • 0
                      Для проверки верстки можно использовать applitools, особенно если таких проверок много или они критичны для бизнеса. метод с попикселным сравнением не слишком надежный
                      • 0

                        Applitools стали популярны примерно полтора года назад. VRT (Visual regression testing) мы начали делать года четыре назад :)

                      • +1
                        Для сбора ошибок можно брать логи браузера прямо в Selenium.
                        seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/logging.html
                        • 0
                          Привет.
                          Насколько я помню, это до сих пор не во всех браузерах работает. Нам же требовалось универсальное решение.

                          Но я посмотрю повнимательнее, спасибо!
                          • +2
                            Да, Safari, IE, EDGE — не отдают лог.
                            Проблема в том что W3C никак не определится с логированием webdriver.
                            В IE можно решить через аргументы драйвера (запись в файл с LEVEL = ERROR)
                            В EDGE пока не хотят делать, но думают об этом )
                            developer.microsoft.com/en-us/microsoft-edge/platform/issues/12238249
                            • 0
                              У меня в своё время возникала проблема и с ФФ. В спеке geckodriver'а логирование не описано, что ли, поэтому не поддерживается.
                              • +2
                                Ну сейчас всё в порядке.
                                firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/TraceLogs.html

                                Кстати в FF как и в Chrome можно и полный http лог в файл записать.
                                about:networking в FF и chrome://net-internals у Chrome
                                Можно и через аргументы браузера запись в файл включить.
                                developer.mozilla.org/en-US/docs/Mozilla/Debugging/HTTP_logging
                                dev.chromium.org/for-testers/providing-network-details
                                • 0
                                  Попробую ещё, спасибо за наводку! Плюс не позволяет поставить карма, к сожалению.
                                  • 0

                                    Спасибо за наводку, интересно.
                                    HAR мы вытягиваем с помощью экстеншена для Firefox и средствами performance logs для Chrome. Решение хорошо описано у ребят из https://sitespeed.io
                                    Я вот прямо сейчас глянул на то, что Mozilla предлагает — не уверен, что так можно сделать, например, в Selenoid (может, невнимательно смотрел).

                                    • +1
                                      В Selenoid для FF можно передать переменные среды в browsers.json
                                      "env" : ["MOZ_LOG=timestamp,rotate:200,nsHttp:5,cache2:5,nsSocketTransport:5,nsHostResolver:5", "MOZ_LOG_FILE=/tmp/log.txt"]
                                      У хрома всё можно сделать через capabilities добавив аргументы:
                                      --net-log-capture-mode=IncludeCookiesAndCredentials
                                      --net-log-capture-mode=IncludeSocketBytes
                                      --log-net-log=/tmp/network_log.json
                                      --log-net-log-level=0

                                      Да, хром может и показать записанный файл, достаточно загрузить его в
                                      chrome://net-internals/#import
                                      • 0

                                        интересно. попробуем, спасибо.

                          • 0

                            Привет
                            В webdriver есть возможность получить все логи браузера, в том числе и JS ошибки.

                            • 0
                              Добрый день.
                              Вроде обсудили веткой выше. Вы же об этом?
                            • 0
                              Здравствуйте! Извините за, возможно, глупый вопрос. Касаемо темплейтов: вы просто добавляете темплейт со скриптом внутри в код тестируемой страницы? Как это у вас происходит: вы изменяете код страницы на тестовых серверах, попросив помощи у разработчика, либо самолично имеете доступ к коду? либо как-то исполняете код, который добавит этот темплейт в код страницы на время исполнения автотеста, не меняя её исходного кода? Ещё раз прошу прощения за дилетантский вопрос. Если не затруднит, хотелось бы почитать, как именно это реализовано. Спасибо!
                              • +1
                                Добрый день.
                                Тут, скорее, вопрос не в том, у кого какие доступы есть. Тут вопрос ответственности. Никто, ни разработчики, ни QA-инженеры ничего не делают сами по себе, только потому, что это взбрело в голову.
                                Задачи предварительно обсуждаются, а после их выполнения проходят Code Review со стороны разработки и несколько этапов тестирования со стороны QA. Вся работа исключительно командная.
                                О том, как у нас построено тестирование в целом и о Code Review в частности очень подробно написал руководитель отдела тестирования — Илья Агеев. Почитайте , это интересно.
                                • +2
                                  Спасибо за ответ, обязательно прочту. И спасибо за статью! Мысль про отлов JS-ошибок очень актуальна в рамках нашего проекта, поэтому возьму на вооружение и попробую запустить у себя нечто подобное.

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

                            Самое читаемое