Как писать тест-кейсы: полное руководство
Во время тестирования QA-инженер работает с большим количеством документации. Чеклисты, наборы тестов, тестовые сценарии, планы тестирования, отчеты о тестировании, анализ тестирования — это лишь часть списка документов, которые должны уметь создавать тестировщики. В этой статье мы расскажем вам, как создавать тест-кейсы для ручного тестирования.
Что такое тест-кейс и зачем он нужен
Тест-кейс — это четкое описание действий, которые нужно выполнить для проверки отдельной функции вашего приложения.
Тестировщик создает тест-кейс, чтобы проверить, работает ли определенная фича должным образом, и чтобы подтвердить, что функционал, UI/UX и другие параметры системы удовлетворяют всем соответствующим стандартам, руководствам и требованиям клиентов.
Чем отличаются тест-кейс и чеклист
Тест-кейсы используются для сложных проектов. Например, когда от поведения системы зависит человеческая жизнь. Это могут быть проекты, связанные с пожарной безопасностью, здравоохранением, финансами и т. д. В таких случаях все нужно тестировать очень тщательно.
Чеклист QA — это список того, что нужно протестировать. Благодаря ему процесс тестирования проходит более четко и аккуратно.
Обычно при работе с простыми системами — сайтами, мобильными приложениями и т. д. — нет необходимости в тест-кейсах. Часто в команде бывает только один-два тестировщика, которые хорошо знают свой продукт. В таком случае время, потраченное на создание и поддержку тест-кейсов, никогда не окупится. Лучше создать чеклист со списком функций, которые нужно проверить — это будет более рационально.
Позитивные, негативные и деструктивные тест-кейсы
В позитивных тест-кейсах используются корректные входные данные и сценарии ожидаемой работы системы. Цель здесь — убедиться, что программный продукт выполняет то, что должен делать, и что система не выдаст ошибку, если это не предусмотрено.
В целом позитивное тестирование гарантирует, что система соответствует требованиям при позитивных сценариях нормального использования.
Например, если поле пароля принимает десять символов, пользователь должен иметь возможность создать такой пароль.
Негативные тест-кейсы используют некорректные входные данные и проверяют, не делает ли программа того, чего не должна делать. Негативное тестирование призвано гарантировать, что при получении некорректных входных данных система не будет работать по нормальному сценарию (например, выбросит ошибку).
Если вернуться к нашему примеру, пользователь не должен иметь возможность создать пароль, состоящий из 11 символов.
Деструктивные тест-кейсы создаются, чтобы узнать предел прочности системы. Нагрузочное тестирование — распространенный вариант деструктивного тестирования.
Для деструктивного тестирования QA-специалисты могут применять следующие методы:
Атрибуты тест-кейса для ручного тестирования
Как и все тестировочные документы, тест-кейс имеет определенный формат. Он содержит следующие атрибуты:
Кроме того, для некоторых тест-кейсов могут потребоваться дополнительные атрибуты:
Характеристики хорошего тест-кейса
Прежде всего, тест-кейс не должен быть зависимым или связанным с другими тест-кейсами. Он должен быть полным и самодостаточным. Следует избегать расплывчатых описаний шагов или ожидаемых результатов. Любые ограничения, отсутствие необходимой информации или чрезмерное количество деталей делают тест-кейсы менее эффективными.
Короче говоря, хороший тест-кейс:
Best practices в написании тест-кейсов
Под best practices мы подразумеваем правила, которые помогают создавать простые, понятные и полезные тест-кейсы:
Формирование тест-кейсов
Обычно при написании тест-кейсов тестировщики пользуются таблицами Excel. Но вы также можете использовать инструменты управления тестированием, такие как TestRail.
Примеры тест-кейсов для ручного тестирования
Позитивный тест-кейс
Давайте попробуем создать наш собственный тест-кейс для ручного тестирования функции поиска на e-commerce сайте компании FootWear. Начнем с позитивного теста.
ID: FWSF-1. (Лучше использовать числа в возрастающем порядке. FWSF = FootWear Search Functionality. Попробуйте придумать комбинацию букв, имеющую отношение к проекту или функции, которую вы собираетесь тестировать).
Заголовок: Проверить результаты поиска с корректными входными данными. (Узнать, какие значения допустимы, мы можем в требованиях).
Предусловия: Нужно иметь предварительно настроенные продукты из разных категорий, отображаемые на сайте. (Для проверки функциональности нам необходимо иметь элементы, доступные для поиска. Вы можете настроить это в панели администратора или в базе данных).
Шаги:
Ожидаемый результат: На странице результатов поиска отображаются все релевантные результаты.
Деструктивный тест-кейс
Еще один пример — деструктивный тест-кейс.
ID: FWSF-2.
Заголовок: Проверить устойчивость поиска к SQL-инъекциям.
Предусловия: Подготовьте SQL-запрос, который вы собираетесь вставить в поиск.
Шаги:
Ожидаемый результат: Для защиты от SQL-инъекций отображение предупреждающих сообщений должно быть отключено.
Негативный тест-кейс
Наконец, вот вам негативный тест-кейс.
ID: FWSF-3.
Заголовок: Проверить ввод на недопустимые значения.
Предусловия: Выпишите недопустимые значения для поля ввода поиска из системных требований.
Шаги:
Ожидаемый результат: Отображается предупреждающее сообщение «Пожалуйста, используйте только допустимые символы». Поиск можно продолжить.
Итоги: тестирование тест-кейса
Итак, мы разобрали основы написания тест-кейсов. Совет напоследок: чтобы проверить, насколько хорош ваш тест-кейс, покажите его человеку, который ничего не знает о проекте, над которым вы работаете. Вопросы, которые вы услышите, помогут определить слабые места вашего тест-кейса. Обратите внимание на эти моменты и постарайтесь внести изменения как можно скорее, иначе в будущем для поддержки тест-кейсов потребуется гораздо больше времени и усилий.
Как сделать хороший тест: 10 правил
А еще примеры и шаблоны
Содержание
Наверняка вы не хотите делать тест ради теста. А хотите чего-то большего:
С первым все ясно: читатель должен пройти тест и узнать что-то новое или о чем-то задуматься. Например, о своих личных предпочтениях или о том, как на самом деле устроена жизнь вокруг:
Со вторым тоже все просто. Цель может быть прикладной — например, мы хотим ненавязчиво рассказать о нашем курсе по инвестициям. Тут все понятно: на заголовок кликают люди, которые интересуются темой и хотят узнать про себя что-то новое. Получают развлекательный контент и в конце узнают о курсе.
Или, наоборот, цель может быть более призрачной — например, нам важно писать про бизнес. У нас есть целый раздел про это, мы хотим подогревать интерес к теме разными способами: тот, кому пока скучно читать длинный текст, возможно, клюнет на что-то развлекательное. Скорее всего, человеку выпадет хороший результат, мы заложим в его голову идею, и, вероятно, в следующий раз он уже созреет для более серьезных форматов.
Чтобы результаты теста выглядели убедительно, нужно придумать, на чем именно будут основаны ваши расчеты. Вам может казаться, что вы делаете максимально шуточный тест и придумывать какое-то обоснование необязательно. Но чаще всего это заметно, и у читателей возникнут вопросы:
В некоторых тестах результат можно выдавать рандомно. Подумайте, насколько такое решение уместно в конкретном тесте: оно должно выглядеть как фича, а не баг.
Примеры разных видов логики:
Бывают тесты, в которых главное — результаты. Бывают тесты, в которых главное — вопросы. Здесь важно продумать, как правильно расставить акценты, чтобы и читатель был доволен, и вы рассказали людям все, о чем хотели.
10 вопросов всегда лучше, чем 15, а 7 — лучше, чем 10. Можно пойти еще дальше и сделать тест из двух вопросов — и даже из одного! Все зависит от цели и от того, что в вашем тесте главное, — не стоит прятать это слишком далеко.
Также старайтесь соблюдать баланс: если вопросов много, то пусть и вопросы, и варианты ответов будут максимально короткими. Если вопросов мало, то можно себе позволить сделать вопросы или варианты ответов подлиннее. Варианты с картинками выбирать проще, даже если на этих картинках написан текст. Конечно, это не всегда возможно. Просто помните об этом и стремитесь к идеалу.
Старайтесь формулировать вопросы емко, убирайте лишние подробности. Избегайте длинных придаточных и громоздких фраз. Ваш вопрос должен быть понятным и конкретным.
В идеальном мире текст результата всегда должен отвечать на вопрос в заголовке. Человек заинтересовался вопросом в заголовке и хочет получить на него ответ. А если ответа нет, то, вполне вероятно, человека постигнет разочарование. Это не те эмоции, которые нужно получать от тестов.
Желание увидеть результат — это главное, почему человек проходит наш тест. Проходить тест трудно. Нужно думать, читать и нажимать на кнопки. Кнопок бывает много: узнать правильный ответ, перейти к следующему вопросу, узнать результат. Это активное потребление контента. Поэтому в тестах результат — это награда. Если человек получит слишком короткий или неинтересный результат, он также будет разочарован. У него останется ощущение, что результат не стоил затраченных усилий. Поэтому к результатам надо отнестись внимательно и сделать их с любовью.
Если человек получил удовольствие от прохождения теста и от его результата, он становится довольно лояльным пользователем и благосклонно отнесется к нашему предложению продолжить вечеринку. Поэтому при создании теста мы сразу думаем о том, что еще предложить читателю. Мы можем предложить пройти еще один тест или прочитать текст по теме. В каждом результате может быть что-то уникальное: например, если человек показал слабый уровень знаний по какому-то предмету, мы можем отправить его читать про азы, а если высокий — проходить более сложный тест. Или во всех результатах может быть ссылка на что-то одно. Все зависит от цели.
Тесты — это развлекательный формат. Возможно, читателю скучно и он хочет развлечь себя. Возможно, у читателя был тяжелый день и он хочет отвлечься. Но он точно не хочет прочитать что-то неприятное про себя. Поэтому старайтесь даже в самых плохих результатах описывать недостатки мягко, упоминайте возможные сильные стороны и добавляйте во все это самоиронии и дружеского подмигивания.
Помните, что и механики тестов, и сама концепция таких тестов построены на допущениях — мы даем очень приблизительный результат. Кроме того, продумать абсолютно все довольно тяжело и весьма вероятно, что где-то в вашей логике найдется слабое место. Поэтому нужно максимально застраховать себя от провалов. Если вы сами чувствуете, что халтурите или чересчур притягиваете нечто за уши, убирайте: это однозначно заметят.
Используйте слова: «возможно», «вероятно», «кажется» и так далее. Старайтесь не упоминать в результатах конкретные вещи, если механика теста не гарантирует вам, что читатель выбрал определенный результат. Зачастую бывает так: один из вариантов ответа — «обожаю хот-доги», читатель фыркает про себя, выбирает другой ответ, но по ответам в других вопросах оказывается, что он должен основать компанию по производству сосисок. Поэтому результат нужно завуалировать таким образом, чтобы даже тем, кто не любит хот-доги, было понятно, почему им выпал такой результат. Добавляйте в описание результата примеры не из вопросов, а другие, из жизни, которые расширяют картину.
Помните, что правила созданы, чтобы их нарушать. Если вы понимаете, что какое-то правило противоречит вашей идее или цели, и вы знаете, как сделать лучше, — делайте. Но сначала согласуйте все с редактором: возможно, он уже сталкивался с подобным и знает, как поступить, или просто поможет найти решение.
Виды тестов
Тесты-квизы: с правильными и неправильными ответами:
Практика написания тестов. Лекция Яндекса
С праздниками, друзья! Если вы не против научиться на каникулах чему-то новому, прочитайте лекцию Кирилла Борисова — разработчика систем авторизации Яндекса. Кирилл объясняет, как построить процесс тестирования Android-приложений, знакомит с современными инструментами и спецификой их использования.
— Прежде чем двинуться вперед, давайте устроим небольшой соцопрос. Кто из вас знает, что такое тесты? Кто пишет тесты? А кто знает, зачем он пишет тесты? Примерно одни и те же люди.
Тем, кто с тестами знаком понаслышке и не прикладывал к ним руки, хочу представить пример простейшего теста.
Как видите, ничего страшного. Это самый простой тест, который проверяет, что законы математики еще не изменились и 2 + 2 по-прежнему равно 4. Это всё. У вас перед глазами полноценный тест.
На самом деле тест — это просто функция на каком-то языке программирования. В нашем с вами случае это скорее будет Java, хотя может быть Kotlin и т. д.
Тест запускается неким программным пакетом, тестовым фреймворком, который берет на себя всю черную работу по их обнаружению, запуску, обработке результатов и т. д. Самым частым является пакет jUnit, который дальше будет рассматриваться в нашей лекции, но ничто не останавливает вас от использования каких-то других пакетов или написания своего собственного.
Тесты группируются в классы. Порядочная функция должна жить в классе. Затем эти классы разбиваются по смысловому признаку на различные категории тестов, которые мы рассмотрим позже.
Тесты — это благодать и польза. Во-первых, они позволят освободить ваших тестировщиков от рутинных задач по проверке уже исправленных багов, так называемой регрессии, и, в свою очередь, помогут им воспроизводить сложные случаи, которые требуют большого набора действий и поддаются автоматизации.
Но вы скажете: погодите, какие тестировщики? Я простой независимый разработчик, я один пишу приложение, один выкладываю, один зарабатываю деньги. Не хочу вас расстраивать, но вы — тот самый тестировщик, просто потому что вам все равно рано или поздно придется проверять, как работает приложение, тыкать основные сценарии его использования и т. д. И этому бедному тестировщику очень помогут автотесты.
Во-вторых, они повысят у вас, разработчика, уверенность в вашем коде. Знание о том, что написанное в вашем коде какой-то бездушный компьютер проверяет, что это все работает так, как ожидается, поможет вам не заботиться об этом и свободно разрабатывать код. Как только что-то непредсказуемым образом изменится, тут же вскачет красный флажок, и вы поймете, что нужно чинить.
На самом деле это приводит к тому, что у вас повышается качество кода. По мере того, как вы будете покрывать свой код тестами, по мере того, как вы будете перерабатывать его, чтобы можно было его тестировать, вы неожиданно заметите, что код становится все более приятным глазу, все более легким для прочтения и понимания. Вы даже сможете привлекать других программистов, которые также будут читать этот код и понимать, что это замечательное произведение программистского искусства.
Но самое главное — они помогают вам сохранять совместимость. По мере того, как ваше приложение будет расти и цвести, вы так или иначе будете задевать другие участки кода, на которые могут полагаться другие люди. Представим, что вы не один в команде, у вас есть такие же собратья разработчики, и они пишут свои модули, ориентируясь на то, как работают ваши модули. Если вы покрыты тестами, если вы обеспечили себе проверку того, что оно все еще работает так, как вы это задумали, как только вы что-то сломаете, вы об этом узнаете сразу же. Тем самым вы поможете им не думать, что вдруг он сегодня что-то сломал, пойду перепроверю. По сути, вы возлагает все заботы на бездушный компьютер, оставляя себе просто для творчества.
К сожалению, как и все в этом мире, ничего не приходит просто так. У всего есть своя цена. Думаю, очевидно, что у вас будет уходить еще больше времени на разработку. От этого никуда не деться. Тесты вам придется писать, вам придется о них думать, придется их тестировать, и все это занимает драгоценное время. Но как и вложение сил во что-то хорошее, оно рано или поздно окупится.
Во-вторых, вам придется повысить навыки. У всех нас есть пространство для роста, в том числе в области технических навыков. По мере того, как вы будете писать тесты, вам придется изучать новые инструменты и методики. Но все это идет вам на пользу.
А самое страшное, что может испугать не только вас, но и вашего менеджера, может понадобиться рефакторинг. Страшное слово, которое вселяет ужас в любого человека, планирующего выпуск ПО. К сожалению, тесты — не волшебная палочка-выручалочка. Чтобы они могли работать, вам придется перерабатывать свой программный код, к примеру, чтобы использовать какие-то программные интерфейсы, которые были ранее недоступны, либо сделать его более модульным, чтобы было проще тестировать. К сожалению, все это все требует времени, денег и усилий — самого ценного в нашей индустрии.
И в конце концов в сумме все это усложняет выпуск кода. Когда вы раньше могли взять и просто скомпилировать код, отправить в Play Store и пойти есть пиццу, в этот раз у вас уже это не получится. Скорее всего, у вас появятся такие процессы, как запуск кода, проверяющего ваш код, просмотр отчета о тестах, отправка это на сервер Continuous Integration и т. д. К сожалению, это цена, которую придется заплатить, но как и все предыдущее, оно в будущем окупится.
Самый заковыристый вопрос, связанный с тестами, который слышу чаще всего, когда пытаюсь протолкнуть эту идею: а как мне убедить моего менеджера? Потому что эти люди не понимают, зачем нам нужны тесты. Они думают, что опять эти программисты что-то придумали, они хотят какие-то тесты, нам нужно делать фичи, выпускать.
К сожалению, аргументов на это достаточно мало, но есть проверенный список, который вам всегда поможет.
Во-первых, их очень радует, когда в вашем конечном продукте становится меньше багов. По мере того, как вы будете покрывать ваш код тестами, количество ошибок, в том числе глупых, которые проскальзывают совершенно случайно, будет уменьшаться. Ведь вы будете их обнаруживать и своевременно исправлять. Именно это приводит к тому, что у вас происходит ускорение поиска причин ошибок, и как только к вам прибегает менеджерами с криками: «Шеф, все пропало», вы тут же смотрите на список пройденных и заваленных тестов, понимаете, где и что сломалось, исправляете и спасаете день.
Все это приводит к тому, что экономятся деньги и время. Это радует практически всех. По мере того, как у вас уходит меньше усилий на поиск ошибок в вашем коде, меньше усилий на переработку этого кода и исправление его, вы можете тратить больше времени на действительно интересные вещи: разработку новых фич, приносить больше денег за меньшие промежутки времени. В теории. Не знаю, как это работает конкретно в вашем случае, но должно работать примерно так.
А главное, вдумайтесь, вы приходите в новую компанию и спрашиваете, есть ли у вас тесты? Они говорят: «Да, у нас 100% покрытие, все проверяется». И вы думаете, что я пришел в правильную компанию. Согласитесь, очень круто. И когда к вам уже придут молодые гордые разработчики, вы скажете — а у нас тут тесты, 97% покрытия, мы все тут тестируем. И они будут смотреть и понимать, что да, это крутая компания, крутая команда разработки, хочу с ними остаться.
Переходим к конкретной теории. Посмотрим на уже упомянутые тесты в разрезе.
Перед вами скелет практически любого типового теста в вакууме. Он состоит из нескольких блоков, которые обязательно отмечены желтым цветом, и серое — для тех, кому это понадобится.
Самое важное — название теста. Я встречал много людей, которые думают, зачем давать тестам какие-то осмысленные названия? Тест1, Тест2, Тест3 это уже хорошо, различаются и ладно.
На самом деле название теста как название книги. Это что-то, что должно в очень короткий промежуток уместить как можно больше смысла. Это то, что вы увидите в вашем отчете, то, что будет светиться в вашем редакторе кода. Вы должны по одному названию теста уже получить примерное представление о том, что же он проверяет, что же в нем происходит. Поэтому стоит приложить усилия и подумать о том, как вложить в одном предложении из трех-четырех слов смысл того, что вы проверяете.
Далее их обязательных блоков идет совершение действия. Чтобы что-то проверить, нам нужно что-то сделать. В этом блоке выполняется какое-то воздействие на вашу систему. К примеру, дергаете функцию, запускаете сервис, открываете окошко. Получив результат этого действия, вы переходите к главной, самой сладкой части любого теста — проверке результатов. Именно здесь находится сердце теста. Именно здесь вы проверяете, что мир изменился таким образом, как вы от него ожидало. Что открылось окошко, а не удалились все файлы с устройства. Что у вас запустилась видеозапись, а не произошло стирание памяти и т. д.
А что же несут в себе серые блоки, отмеченные здесь, подготовка окружения и освобождение ресурсов? На самом деле, это те скучные повторяющиеся части, которые рано или поздно начнут появляться в вашем коде.
Если у вас все ваши тесты связаны, к примеру, с файлами, если вы в каждом тесте создаете один и тот же файл, открываете одни и те же файлы, потом закрываете их, удаляете, зачем все это носить с собой из теста в тест? Можно просто воспользоваться любым из инструментов вашего тестового фреймворка, и вынести их в отдельную небольшую функцию, которая будет вызываться перед вашим тестом и после него.
На самом деле, это может пригождаться не всегда. Ваш тест вполне может обходиться и без этих необязательных блоков. Но если что-то случится, знайте, что это не беда, вы просто выносите их в отдельную функцию, и все работает.
Таким образом ваш тест остается исключительно из обязательных частей, простой и элегантный.
Мы поняли, что такое тест и как его написать. А что мы будем тестировать?
Есть несколько теорий о том, что надо тестировать с помощью автотестов. Практически все сходятся к тому, что есть ряд таких типичных случаев. Во-первых, первое — happy path, типовой путь выполнения вашего кода. Это то, что вы знаете, что я нажму на кнопочку, и появится окошко. Вы сначала проверяете его, что действительно вы нажали на кнопку, и появилось окошко. Или ввели ваше имя, и оно подсветилось особым образом. Все, вы знаете, как это должно работать, вы ожидаете, что это будет так работать, но на всякий случай пишете на это тест. Потому что если вдруг это сломается, будет печально.
Затем вы проверяете все возможные краевые случаи. К примеру, если человек введет свое имя японскими иероглифами или если вдруг в графу возраста он введет эмодзи. Что я буду делать в таком случае? Справится ли мой код с этим?
Вы пишите на каждый такой случай отдельный тест, который проверяет, что ваше приложение будет действовать определенным образом, к примеру, выкинет окно с ошибкой, либо же просто завершится и больше откажется запускаться — все на ваш выбор.
Затем вы переходите к самому банальному. Что будет, если я начну запихивать null в любое место своего кода, куда только подумаю. Ага, а у меня есть функция — отправлю null. У меня есть опциальный аргумент — отправлю null. и т. д. Ваш код, по-хорошему, должен быть устойчив к тому, что к одному из ваших аргументов неожиданно придет пустота. И в самую последнюю очередь, думаю, стоит коснуться сценария, когда не работает ничего. Ваше приложение, предназначенное для того, чтобы отсылать ваши фоточки в Instagram каждые пять секунд, неожиданно понимает, что у него нет сети. И нет камеры. Что делать? По-хорошему, надо, чтобы ваше приложение каким-то осмысленным образом дало понять пользователю, что, извините, я не буду работать. Именно это вам стоит протестировать, что в случае, когда все пошло не так, ваше приложение по-прежнему работает хоть как-то ожидаемым образом. Ничто так не огорчает пользователя как окошечко NullPointerException с ошибкой от Android или что-то в этом роде, страшно подумать.
Когда все это тестировать? Как только начинаем разработку или когда уже закончили? На этот счет нет единого мнения, но есть набор устоявшихся концепций. Во-первых, нет смысла писать тесты, когда код вашего приложения меняется буквально каждый час. Если вы с вашими друзьями находитесь в плену музы, и буквально каждый час меняется концепция, вы меняется всю структуру программы, архитектура плывет, если к этому еще будете писать тесты, у вас будет больше времени уходить на то, чтобы постоянно переписывать эти тесты вслед за вашей творческой мыслью.
Хорошо, у вас код уже более-менее устоялся, но ваш дизайнер тоже попал в тиски этой страшной женщины (музы) и начинает дергать ваш UI каждую минуту — о боже мой, новый дизайн, мы поддерживаем новую концепцию.
Писать тесты, которые взаимодействуют c UI, в этот момент тоже не очень хорошая идея, потому что вам также придется их переписывать практически с нуля.
Как только у вас стабилизировался код приложения, UI уже не скачет по экрану, стоит ли писать тесты дальше? Да, хотя бы потому, что рано или поздно в вашем приложении обнаружатся так называемые регрессии, в простонародье баги. Это что-то, что обозначает нарушение работы вашего приложения. К примеру, ваше имя отображается справа налево, потому что мы случайно подумали, что мы в стране с арабской клинописью и т. д. Это регрессия, это баг, но нужно написать тест, чтобы проверить, что в будущем в этих условиях ваше приложение будет работать все-таки ожидаемым образом.
Вот три случая, когда точно следует писать код. Когда он не плывет, когда не плывет UI, и когда у вас обнаружится уже какой-либо баг. С этого вы начнете свой путь.
Тесты делятся на несколько категорий. Такая пирамида тестов показывает примерный порядок того, в каком плане надо начинать писать тесты в вашем приложении. В основе этой пирамиды лежат так называемые юнит-тесты. Это самый низкий уровень, соль земли. Это тесты низкоуровневые, когда вы тестируете отдельные юниты в изоляции друг от друга.
Ученые до сих пор спорят по этому вопросу, пишут научные работы. Каждый решает сам для себя, что является юнитом в его приложении. Чаще всего в качестве юнита выбирается какой-либо класс, и тестируется функция этого класса, методы этого класса, различные условия его взаимодействия. Мы предполагаем, что класс — это некая замкнутая в себе сущность, к примеру, класс, вычисляющий длину строки или класс шифрования и т. д. Обычно он не связан с другими какими-то классами в относительно явном смысле, и его можно протестировать.
Этих тестов у вас будет большинство. Именно эти тесты у вас будут запускаться чаще всего. Если у вас будет привычка запускать каждые пять минут — это нормально. Мы так делаем, и все идет хорошо.
Юнит-тесты предназначены для того, чтобы в первую очередь контролировать вас в процессе написания вашего кода, именно потому что они самые низкоуровневые и должны проходить как можно быстрее.
По мере того, как вы их запускаете, к примеру, нажали Ctrl + S, и тут же у вас прогнались тесты, и вы тут же заметили, что что-то поломалось. Согласитесь, лучше обнаружить ошибку, пока она еще не успела проникнуть куда-то еще.
Рассмотрим пример такого юнит-теста. Рассмотрим любимый нами класс статических утилит. Есть класс, содержащий ровно одну функцию, которая проверяет наше гипотетическое приложение, ввел ли пользователь сильный пароль, взломают ли его хакеры или нет. Эта простейшая функция содержит три основных условия, три основных инварианта про то, что наш сильный пароль не должен содержать меньше семи символов, должен содержать в себе хотя бы одну заглавную латинскую букву, и как минимум одну цифру. Иначе это курам на смех.
Если все эти три условия проходят, мы возвращаем, что все хорошо, регистрируйте пользователя, мы идем дальше.
Как же мы это будем тестировать? Нашим юнитом мы здесь выбираем эту функцию isStrongPassword, и будем тестировать каждый из этих трех случаев отдельно.
Начнем с первого условия, что в наши функции должны передаваться строки длиной больше 6 символов, чтобы они были признаны успешными. В нашем первом тест-кейсе мы проверяем, что если мы передаем строчки, у которых меньше семи символов, то наша функция вернет false. За это отвечает функция assertFalse, которая вскинет руки в панике и остановит весь процесс тестирования, если ей вместо false внезапно придет true в качестве аргумента.
В таком же духе мы проверяем наши основные случаи, и проверяем один контрпример, что если мы все-таки передадим нашей функции длиной больше, чем 6 символов, она же вернет true. Такой тест-кейс в вакууме. Мы проверили какие-то условия, вызывающие падение нашей функции. Мы проверили, что если мы передаем ей ожидаемые параметры, она отвечает ожидаемым образом. И в таком же духе мы тестируем все остальное.
У нас отдельный тест-кейс на условие проверки того, что в нашем пароле есть хотя бы одна цифра. У нас есть отдельный тест-кейс на проверку того, что в нашем пароле есть хотя бы одна буква. И вы спросите, где же четвертый тест-кейс? У нас же там было четыре пути выхода из функции. На самом деле, мы в предыдущих трех тест-кейсах уже проверили, что если мы передаем пароль, который отвечает всем нашим этим условиям, то мы так или иначе вернемся true.
Давайте посмотрим на главную звезду этих тестов, на функции, начинающиеся со слова assert. Они принадлежат классу функций, называемых ассертами. Эти функции являются всего лишь вспомогательными инструментами, представляемыми тестовым фреймворком jUnit, которые просто помогают вам выразить ваши намерения. К примеру, если у вас вызывается функция assertEquals, вы говорите, что я ожидаю, что эти два параметра должны быть равны. Если нет — все сломалось, все пропало, завершайте проверку. Если assert = null, not null и т. д.
Эти функции и являются вашими инструментами проверки в тестах. Пока они получают на входе ожидаемое условие, тест не прерывается. Как только он прерывается, значит, у вас есть проблема.
Если вам кажется, что ассерты из предыдущих слайдов сложно читаемые, к вашим услугам специальные инструменты, написанные нашим комьюнити.
Одним из самых популярных является AssertJ.
Он является попыткой сделать проверку результатов выполнения вашего кода, более читаемым, приблизить его к стандартному английскому языку. Простейший пример — ассерт That(count).isGreaterThan(original). Это читается намного проще, чем assert true a