Обработка багов продукта в тестах, или принудительный Assert

Добрый день.

Проблема

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

Чего хочу

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

Пример реализации

@Test
public void test()
{
     // Patch
     Assert.assertTrue(true);

    // Test code
}

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

Подскажите возможные варианты решения проблемы. Как Вы обрабатываете баги в автотестах?

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

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

Плюсы такого подхода:

  1. Тесты не скрывают проблемы в проекте
  2. по идее это стимулирует всех исправлять баги быстрее

Минусы:

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

Данный минус - дело техники)
Да, такой вариант рассматривал и даже пробовал, спасибо.
Если реализую - поделюсь результатами.

1 лайк

Я по этому поводу делал доклад два года назад. Слайды и видео – ниже.

Смысл в том, что где-то в коде есть списко всех багов, для которых мы хотим сделать обход или отключить проверку.
В блоках if/else в коде автоматизации, перед тем как выполнять проверку, проверяется наличие бага в этом списке. Если он есть – то проверка не производится.

В презентации есть еще несколько вариаций этого сценария.

:octocat: Исходный код

И Еще:

В свое время подобную связь реализовал следующим образом:

  • в месседж ассерта помещался ID бага в Jira;
  • сам assert перехватывался, парсился, билдилась структура репорта;
  • перед записью в velocity контекст репорта, формировалась ссылка путем конкатенации линка на проект в Jira и номера бага из ассерта;
  • в итоге, в кастомном репорте для каждого теста мы получали линк на баг / стори (с требованиями) в Jira.

Спасибо всем.
Мы реализовали следующим образом.

  1. При возникновении ошибки (от веб-драйвера, в тесте, в пейдж обджекте и т.д.) выбрасывается определенный Exception.
  2. На уровне теста такие Exception отлавливаются и данный участок фиксируется как непройденный.
  3. Одновременно с этим:
  • делается скриншот страницы с именем, содержащим имя тестового метода, дату и время ошибки.
  • текст исключения фиксируется в лог.
  • также в лог записывается ошибка уровня error с человеко понятным объяснением на каком участке теста произошла ошибка.
  1. Данная ошибка постится в трекер Redmine при помощи Redmine Java Api на группу автоматизаторов, в котором указывается:
  • имя упавшего теста
  • данные теста - платформа, сайт, браузер и т.д.
  • скриншот
  • логи уровня error и warning, которые имели место за время прохождения нестабильного участка.
  1. В случае если ошибка в данном тесте повторяется и такой тикет уже есть, информация добавляется в виде комментария к существующему тикету. Если же тикет был разрешен и закрыт, то будет создан новый тикет.
    Пример тикета см. на скриншоте.
  2. Мы рассматриваем проблему. Если это баг теста - фиксим и закрываем тикет. Если это баг сайта - оформляем баг, связываем его с текущим тикетом и поле фикса закрываем оба тикета.

Таким образом мы организовали удобную систему ведения багов в Redmine который оповещает нас на email.

3 лайка

Задумка с постом бага в трекер неплохая, но… Приведенной информации совсем недостаточно, чтобы его воспроизвести. Без степов, по одному только названию теста и ошибке, что actual не соответствует expected, толку от такого описания будет мало. Девелоперы не умеют читать мысли. А тратить время на то, чтобы лезть в код автотестов, чтобы выявить шаги, - мало кто захочет. А что если фреймворк не использует DSL? Что если тесты написаны на сугубо техническом языке, без намека на наличие логики? В этом случае на анализ бага уйдет уйма времени. QA в ответе за предоставление информации в удобоваримом виде. Автоматизаторов это тоже касается. Т.е. в качестве импрувмента я бы посоветовал логировать также и степы (если конечно архитектура позволяет). Кстати, это вроде умеет Thucidydes.

Поясню…) Кроме ошибки типа “Упал такой-то тест”, здесь фиксируются также сообщения системные - от веб-драйвера и т.д. И сразу видна причина. Проблем пока не возникало с непониманием)
А по поводу информации для менеджеров и девелоперов - у нас отдельная подсистема. Здесь же я описал как МЫ (автоматизаторы) работаем с системой и обрабатываем ошибки.
Возможно привел неудачный пример на скриншоте. Я хотел показать саму идею. На самом деле в тикетах видны все возникшие исключения от веб-драйвера что вместе со снимком экрана позволяет быстро локализовать проблему.

P.S. Все степы логируются и фиксируются в отчетах HTML и дополнительно отправляются на email в случае возникновения ошибки в тесте.

А какой смысл постить в трекер баг, содержащий лог драйвера и прочей низкоуровневой информации? Если эти баги смотрят лишь автоматизаторы, то чем вас не устраивает CI email report, в котором будет вся та же информация? Или вы на каждый упавший тест трекаете отдельно время на фикс? Тогда я действительно не так понял.

ИМХО, репортить баги конвеером для себя же - нецелесообразно. Больше времени потратите на их ревью и закрытие. Более полезным было бы как раз размещение информативных багов для девелоперов и manual QA, содержащих степы по их воспроизведению. Но, если вам так удобно, it’s up to you.

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

Эту схему мы уже обкатываем несколько месяцев. Мы к ней шли около 2-х лет. Перепробовали несколько способов. Этот оказался наиболее эффективным и позволяет быстро реагировать на ошибки, репортировать их и сопровождать. Я не призываю всех использовать эту схему. Я делюсь)

В случае большой команды - вполне возможно. Лично я не работал в большой команде автоматизаторов. Максимум 4 человека. Но риск появления ошибок в скриптах должен минимизироваться внедрением процесса code review. На текущем проекте применяем Stash с системой пул реквестов и мин числом апруверов = 2. Один из которых должен быть дев. сеньором / лидом. Нас обязывают также проводить pre-commit анализ при помощи Sonar’a. Дженкинс также применяет пост билд анализ с выводом результатов на удаленный сонар-сервер. Т.е. говно-код не пройдет мимо никак. А если и прошел вдруг, то сонар сразу протрубит имя того, кто должен внести изменения в свой код.

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

Я тоже поделился вариантом возможного импрувмента. А внедрять или нет - личное дело каждого. ))

Я считаю, что если авто-тесты фейлятся по причине бага в ПО - нужно заводить blocker и “добиваться” чтоб его пофиксили как можно быстрее.

Менять код авто-теста - не нужно так делать, очень плохая практика.

Я раньше иногда практиковала скипать тесты с багами. Но потом принципиально перестала:

class MyTestCase(unittest.TestCase):

    @unittest.skip("skipping - KA-59779")
    def test_example(self):
        pass

Согласен, что помечать не работающие тесты как passed за счет каких-либо исключений - не верно. Это получается принудительный подгон результатов для “зеленого кружка”.
А если уж все таки решено связывать, то тут вариантов кучу можно придумать:
1)как выше было описано - сделать аннотацию с именем бага. И ее можно(если вы используете например java - через aspectJ парсить, смотреть и запускать/не запускать. Ну или если не через aspectJ, то например в beforeMethod как то аннотации разбирать.
2)Сложнее - присваивать тестам id какие-нибудь уникальные, или имена. И при заведении бага , скажем, указывать этот id. Дальше - дело техники.

Заведение багов из кода - это конечно крутая фича, но как бороться с “левыми” ошибками? Так можно погрязнуть в разного рода непонятных багах.

И опять же - настолько ли фатально, что тест падает пока не пофиксят ошибку? По мне, падение - это как раз стимуляция к более быстрому фиксу

  1. "Согласен, что помечать не работающие тесты как passed за счет каких-либо исключений - не верно. Это получается принудительный подгон результатов для “зеленого кружка”.

От идеи скипать тест, если в функционале продукта есть баг, - отказались. Если есть баг, тест будет падать.

  1. “Заведение багов из кода - это конечно крутая фича, но как бороться с “левыми” ошибками? Так можно погрязнуть в разного рода непонятных багах.”

Если баг “левый” - не приложения, а теста - фиксаем и закрываем тикет, иначе - оформляем баг и не закрываем текущий тикет до фикса. Это больше для нас, автотестеров, чем для других. Еще раз… тикет в Redmine - это отличный способ ведения статистики упавших тестов - ошибки, ворнинги, что упало, где упало, скрины и т.д… И также видно кто занимался решением проблемы и сколько ушло на это времени.
Если все места во фреймворке правильно обработаны - непонятных багов не будет. У нас с этим более менее нормально. Создается тикет с информацией - мы разбираем.