Ретроспективные уроки автоматизации: принцип трех А |
22.04.2019 00:00 |
Автор: Виктор Славчев (Viktor Slavchev) Разделавшись с тем, почему автоматизация важна, и где нужно сосредотачивать усилия по автоматизации, перейду к более специфичным советам, связанным с тем, как создавать полезные и простые в поддержке тесты. В этот раз мы сконцентрируемся на принципе ААА. Конечно, как и прочие статьи в этой серии, эта описывает мой личный опыт и знания. Если вам есть, чем дополнить – пожалуйста, сделайте это. Принципы автоматизации Принципы – это нечто хорошее, то, чему стоит следовать. Это абсолютно точно не "лучшие практики" – скорее это общие указания. В норме они эмпирические, что означает, что они основаны на знаниях тысяч людей, которые уже успели облажаться. Этих принципов множество, и я постараюсь рассказать о тех, которые известны мне, в нескольких кратких статьях. К чему эти основы?Возможно, люди с опытом в автоматизации уже закатывают глаза со словами "Чувак, это какой-то детский сад для автоматизаторов" – и это правда, принцип трех А самый базовый из всех возможных. Это основной принцип не только для автоматизации, но и для юнит-тестирования. Я рассказываю о нем, так как наблюдаю людей, концентрирующихся на более продвинутых темах, вроде параллельного запуска тестов, хабов, контейнеров, облачности, Page Object, Фабриках, ScreenPlay… Все это круто, но предназначено для того, чтобы стать вишенкой на торте вашего фреймворка. Если вы не знакомы с базовыми принципами, то вы строите ваш фреймворк на шатком основании. Поэтому я предпочитаю начать с самых основ и предоставить информацию об основных принципах, а не о фреймворках и паттернах, которые могут измениться в любой момент. Любой принцип, в сущности, помогает решить или избежать грядущих проблем. В чем проблема?Одна из наиболее обсуждаемых тем – это нестабильные проверки, а также проверки с неточными и ненадежными результатами. Как я говорил в предыдущей статье, термин "нестабильные проверки" – это, в сущности, попытка переложить ответственность с тестировщика на инструмент, окружение, фреймворк и что угодно еще. По сути, нестабильные проверки – это ошибка в тест-дизайне. Задача принципа ААА – сделать проверки более гибкими и более однозначными в плане выполняемых ими действий. Принцип АААПринцип трех А означает подготовку (Arrange), действие (Act) и оценку результата (Assert). Это значит, что любой тест должен состоять из трех логических компонентов: Подготовка: настройка окружения. Действие: выполнение действия в интересах вашего теста. Оценка: получение однозначного ответа, совпадают ли ожидаемый и фактический результаты. Идея тут в том, чтобы четко разделять, когда вы выполняете действия по настройке, чтобы достичь определенного состояния, и когда вы выполняете действие собственно теста или оцениваете результат. Это помогает выявить ключевые аспекты ваших тестов и улучшить их ревью, поддержку и дебаг. Давайте подробнее рассмотрим каждую стадию. Подготовка (Arrange) Это стартовая фаза вашей проверки – в норме вы сконцентрированы на приведение окружения в определенное состояние, необходимое для задач вашего приложения и контекста. Это может быть, например, вот что:
Почему это важно? Подготовка очень полезна при очистке вашего фреймворка и выяснении, что вам необходимо выполнять каждый раз перед запуском теста. Зачастую вы будете осознавать, что шаг подготовки будет общим или одинаковым для множества тестов – и значит, имеет смысл вытащить его в методы @before, @beforeSuite или SetUp, если ваш фреймворк это позволяет. Это, в свою очередь, поможет избежать дупликации кода, лапши в коде и другого "кода с душком". Действие (Act) Предположим, у вас уже настроены данные, созданы пользователи, записи, или что там вам необходимо, и вы готовы выполнить свой тест или, как я предпочитаю его называть, проверку. Живые люди, проводя тестирование, обычно выполняют действия или наборы действий и наблюдают за поведением тестируемой системой, сравнивая его со специфическим ожидаемым состоянием – оракулом. Автоматизированные проверки тоже выполняют действия, но не способны наблюдать за поведением системы – они могут только удостовериться, что достигнуто определенное состояние, отсюда термин "проверка". Чтобы получить значимую проверку, нужно совершить действие, в результате которого будет получен однозначный, бинарный (правда/ложь) ответ. Это и есть наше действие. Очевидно, что мы должны явно описывать наши действия. Вот неплохие примеры:
Действия в норме довольно вариативны и тесно связаны с контекстом, поэтому они и относятся к логике ваших тестов. Я бы советовал иметь одно действие и один ассерт на проверку – как я уже говорил, один из признаков хороших проверок – это однозначность. Оценка (Assert) Мы все настроили, выполнили действие и получили результат. Теперь, чтобы проверка была полезной, нам необходима какая-то оценка, сравнение фактического результата нашего эксперимента с ожидаемым, или, в широком смысле – с оракулом. Это жизненно важная часть проверки, и именно она уронит проверку при запуске. Тут есть ряд важных моментов, о которых я узнал довольно неприятным образом:
Итак, как же будет выглядеть хороший тест?Ниже пример псевдокода – я хочу продемонстрировать принцип, а не морочить себе голову синтаксисом. public function checkVatPercentageAfterUpdate(){ //Arrange, might be in @before or @beforeMethod Importer.importTestData(data); Client testClient = new Client(username, password); LoginAsClient(username, password); //Act NavigateTo(Profile) SelectCountry("Ireland") SubmitProfile(); string actualPercentage = GrabDataFromField(vatPercentage); //Assert AssertEquals(20%, actualPercentage, "The actual percentage of profile, mismatches the expected result") } Что может пойти не так?Принцип ААА означает, что у вас должна быть одна подготовка, одно действие и одна оценка. Я не люблю концепцию end-to-end автоматизации, помимо всего прочего, за то, что они устраивают из "А" бесконечную цепочку – Arrange, Act, Assert, Act, Act, Assert, Assert (чего-нибудь другого), Assert (что страница все еще страница), и так далее. Это приводит к полнейшей каше, особенно в UI-тестах, и вам это на самом деле не нужно. А учитывая то, что автоматизированные проверки – это код, такая его организация нарушает фундаментальный принцип программирования – принцип единичной ответственности. Он гласит, что один метод должен отвечать за одно и только одно действие. Наши тест-методы и функции должны следовать этому принципу – один тест на функцию. Мы действуем, оцениваем результат, и все. Если мы организуем действия и ассерты в бесконечные цепочки, мы создаем код, который трудно понять, поддерживать и дебажить в случае отказа. Вот и все, что я хотел сказать про принцип ААА. Надеюсь, это полезная информация для новичков в автоматизации, но, возможно, пригодится и опытным коллегам. |