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

Мы работали над несколькими миллионами автоматизированных тестов (работа такая) и пришли к выводам, что есть 7 характеристик отлично написанных тестов:

  1. Тест полностью автоматизирован (очевидно)

  2. Тест повторяем: тест не ломается, если приложение не поменялось

  3. Тест заканчивается валидацией

  4. Тест достаточно стабилен, чтобы его использовать в CI/CD

  5. Тест очень легко читать

  6. Тест требует минимальной поддержки

  7. Тест работает параллельно с другими тестами и не ломается

Давайте поясню, что имеется в виду.

Тест полностью автоматизирован

Иногда попадаются такие тесты, которые автоматизированы не полностью. Самые распространенные причины: либо это очень сложно (как в случае с медленными джобами), либо просто невозможно (как проверить, что касса таки открылась?). Мы не рассматриваем такие неполные тесты в этой статье.

Тест повторяем: тест не ломается, если приложение не поменялось

Это относится к основам генерации уникальных данных. Например, мы тестируем регистрацию. Очевидно, что если не генерировать уникальный емейл, то на продакшене такой тест, скорее всего, не будет работать.

Тест заканчивается валидацией

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

Тест достаточно стабилен, чтобы его использовать в CI/CD

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

Тест очень легко читать

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

Тест требует минимальной поддержки

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

Тест работает параллельно с другими тестами и не ломается

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

Оригинально тут.

Комментарии (39)


  1. gecube
    06.01.2022 14:28

    Тест повторяем. Тест не ломается если приложение не поменялось

    Это относится к основам генерации уникальных данных. Например, мы тестируем регистрацию. Очевидно, что если не генерировать уникальный емейл то на продакшене такой тест скорее всего не будет работать.

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


    1. tzlom
      06.01.2022 14:47

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

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

      Генерация случайных логинов в этом случае скорее всего не нужна


    1. nin-jin
      06.01.2022 16:06
      +1

      На продакшене тестов быть не должно вообще.

      Почему?


      1. amedvedjev
        06.01.2022 16:49

        тут очевидно зависит от того что тестим. скажем в банке на ПРОДе особо не потестишь.


        1. nin-jin
          06.01.2022 17:36
          +1

          Почему?


          1. amedvedjev
            06.01.2022 17:43

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


            1. nin-jin
              06.01.2022 18:04
              +1

              Берёте реальных пользователей, деньги и в путь.


              1. amedvedjev
                06.01.2022 18:06

                Вы брали или вы фантазируете?

                Я в 3 банках работал. Никто на проде реально не тестит автотестами.


                1. nin-jin
                  06.01.2022 18:16

                  А ещё недавно везде всё вручную тестировали.


                  1. amedvedjev
                    06.01.2022 18:19
                    -1

                    Вот вот. Руками. И только на личном счете.


                1. Ommonick
                  06.01.2022 20:48

                  Я работал в двух. В одном тестили на проде даже с переводами. В другом тестили read-only сценарии, но возможно будут и иные.


                  1. gecube
                    06.01.2022 21:04

                    . В одном тестили на проде даже с переводами. 

                    автотестами?


                    1. Ommonick
                      06.01.2022 22:20

                      да. и следили за балансом, комиссий не было.


                    1. Tellamonid
                      07.01.2022 20:26
                      +1

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

                      И если в течение часа не было транзакций, то они сами делали транзакцию на один фунт между своими счетами или картами, и смотрели, отразится ли она в системе.

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


                      1. gecube
                        07.01.2022 20:59

                        Первое, что Вы абсолютно правильно обратили внимание на важность мониторинга. С этим я абсолютно полностью согласен. Причем мониторинг не только технических параметров, но и бизнесовых.

                        Во-вторых, касательно примера - он какой-то странный. Дело в том, что Банк сам по себе никогда не транзачит. Транзакция всегда является сущностью, которая санкционирована человеком, ну, либо какой-то автоматизированной системой. Но вот как раз тут можно опять же закрыться мониторингом. Смотрите. Человек работает с банк-клиентом - будь это мобильное приложение, или веб сайт Банка. А раз так, то транзакция - это всегда HTTP запрос. Мы их можем считать и смотреть, что в нашей АБСке столько же реальных транзакций, сколько было запросов. ОКей. В какой-то момент времени мы могли понять, что к нам клиенты не могут постучаться. Но это решается вторым слоем мониторинга - не знаю, тот же downdetector прекрасно ловит каскадные отказы. Та же история с интеграциями по API... В конце-концов можем внедрить в приложение модуль слежения типа Sentry...

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


                      1. souls_arch
                        08.01.2022 01:49
                        +2

                        Знаете, что мне сказали крайний раз в втб24 и на горячей и в отделении? Они сказали, под сафари банк-клиент работает збс, им глубоко плевать что больше он ни под одним браузом много месяцев не запускается под https вовсе или работает с косяками и в ограниченном режиме в том же гуглохроме. Который они честно предупредили, что наклали на саппорт. Сказали юзайте мобайл апп. Которое тоже ужас как кривое. Хотя на айос уверен все мб ок. Скоты, ворочая миллиардами экономят на разрабах нанимая индусов подешевше и это инфа из первых рук. Теряют миллионы клиентов из-за этого только. Уважения такому бизнесу нет. Сбер не лучше. А уж многие банки поменьше..


                      1. gecube
                        08.01.2022 03:37

                        Согласен, проблемы есть. И не только у ВТБ. Но то, что Вы рассказываете - и к юнит тестам, ни к интеграционным тестам отношения не имеет. Это вообще отдельный класс UI тестов со своими подходами. И, увы, что ВТБ со своми многомиллионными бюджетами на разработку не может это осилить. Зато эджайл, скрам и девопс.

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


                      1. souls_arch
                        08.01.2022 01:43

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


                  1. amedvedjev
                    06.01.2022 21:05

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

                    Поэтому и сказал что не разгонишься.

                    А перевод и лирика это конечно легко и на Проде. Но этого крайне мало и не проверяет важную бизнес логику.


                    1. Ommonick
                      06.01.2022 22:22

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


                1. GospodinKolhoznik
                  07.01.2022 09:30

                  Работал в финансовом секторе и в России и в США. И там и тут прод системы тестами были обмазаны с головы до ног. И руководство постоянно давило на то, что надо добавит ещё и ещё всех возможных и невозможных проверок как на тестовые системы, так и на продакшн.


                  1. amedvedjev
                    07.01.2022 09:40

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

                    Еще прокатывало создание счета без каких либо транзакций.

                    Все остальное боялись проверок.

                    Я говорю о больших скандинавских банках.


              1. gecube
                06.01.2022 19:09

                Регулятор не позволяет. Если речь про банки.

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


              1. Deosis
                07.01.2022 13:32
                -1

                Вы согласны, чтобы джун сделал тестовый перевод 100 тысяч с вашего счета на свой?


                1. nin-jin
                  07.01.2022 18:08

                  Да, если мне на следующий день вернут деньги вместе с 10% его зарплаты.


      1. gecube
        06.01.2022 19:34

        На всякий случай уточню, что речь не про А/Б или функционал, закрытый фиче-флагом. В Банках этим тоже активно пользуются... но это не те тесты, о которых речь в статье.


    1. artem_testr Автор
      06.01.2022 22:47

      Я просто постарался привести простой пример. Если честно то я ОЧЕНЬ редко видел на практике что люди стартуют тесты с чистой базой - обычно стейджинг и никто его никогда не чистит


      1. Tellamonid
        07.01.2022 20:09

        мы с базой только так и тестируем. Приводим нужные таблицы в изначальное состояние (fixture), делаем, что нужно, и проверяем конечное состояние.

        Мы пишем на Джаве, поэтому обычно используем для наката датасета, и для проверки (assert'а), библиотеку dbUnit.


        1. artem_testr Автор
          07.01.2022 20:34

          @TellamonidУверяю Вас, Вы круты и мы это видем очень редко )


    1. artem_testr Автор
      06.01.2022 22:50

      Я не упоминал негативных тестов отдельно потому что и позитивные и негативные тесты должны удовлетворять этому же критерию IMHO


  1. AndreySinelnikov
    06.01.2022 20:27

    Короче, изобрели F.I.R.S.T.?


    1. artem_testr Автор
      06.01.2022 22:49

      Ой, а ссылочку можете дать? Никогда про него не слышал.


      1. Vadem
        07.01.2022 03:39

        Это из книги "Чистый код" Роберта Мартина. Глава про юнит тесты.

        F.I.R.S.T. - Fast, Independent, Repeatable, Self-validating, Timely.


        1. artem_testr Автор
          07.01.2022 04:58

          Тут я пишу в основном про end-to-end тесты, поэтому, мне кажется, немного другие критерии


          1. Tellamonid
            07.01.2022 20:14

            А, вы про end-to-end. Для них мы перед прогоном всей пачки тестов чистим базу. И обеспечиваем независимость тестов, чтобы они могли бежать в параллель. В нашем случае достаточно, чтобы каждый тест бежал за свою бизнес-дату. И, конечно, есть отдельный тест, который проверяет, что бизнес-даты у тестов не пересекаются.


            1. artem_testr Автор
              07.01.2022 20:59

              Это очень круто и Лучшая Практика.


  1. souls_arch
    07.01.2022 23:51

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


  1. ivanych
    08.01.2022 00:08

    Пункты 2 и 4 это одно и то же.

    Пункты 5 и 6 бессмысленны. Вернее, это просто констатация очевидного, подходящая для чего угодно, хоть для тестов, хоть для тестируемого.

    Пункт 3 - о чём он вообще? Что это за тест, который не является валидацией? Тест - это по определению валидация.

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


    1. Ommonick
      08.01.2022 12:50

      Меня пункт "валидация" тоже смутил. Можно было написать "ассерты" - было бы понятней. А валидацию оставьте на проверку параметров в функциях например.