Подходы к разработке за последние десять лет претерпели серьезные изменения, требования к тестировщикам (QA, QE, инженерам по качеству) тоже поменялись. Но не все тестировщики готовы перешагнуть на качественно новый уровень. Вчера можно было прийти с улицы, чтобы попасть в профессию. Чтобы сегодня стать востребованным специалистом, нужно быть инженером. Когда начинал карьеру, на курсах показывали презентацию с обоснованием необходимости тестирования. Подпись к слайду гласила: «Чем раньше находишь баг в жизненном цикле продукта, тем дешевле его фикс». Рейты тестировщиков ниже, чем у программистов. Наймём тестировщиков → обеспечим качество и сэкономим на разработке. Профит!  Тестировщики были охотниками за багами. Программисты пишут фичи, готовится релиз, релиз проходит стадию QA. В то время тестировщик «надевал шляпу» реального пользователя и начинал выполнять типичные сценарии. Считалось, что на эту позицию подойдёт человек без технического бэкграунда.  Скорость разработки современных проектов возросла. Появилась концепция CI/CD. Никого не удивляют проекты с ежедневными релизами. Компании поняли, что ручные проверки не масштабируются. Тестировщики занялись автоматизацией приёмочного тестирования с помощью Selenium или ему подобных фреймворков. Изменение внутренностей скрыто, только бы фронтенд оставался с необходимыми локаторами.  Так и повелось. У менеджеров автоматизация тестирования ассоциируется с одним навыком: работа с Selenium. В погоне за серебряной пулей они увидели в нём ответ на все вопросы. Рынок подстроился под спрос. Мы долго искали в компанию QA-автоматизаторов для тестирования веб-сервисов. Я просмотрел пару сотен резюме и провёл несколько десятков собеседований. Если обобщить впечатления, можно выделить три основных проблемы, которые часто мешают принять человека на работу. Здесь под архитектурой я подразумеваю высокоуровневое описание взаимодействий компонентов системы. Условно, по каким «трубам» перетекают данные, где они хранятся и как используются.   Во время собеседования кандидат может возразить, мол, нам и не требуются знания архитектуры. Работаем с чёрным ящиком. Зачем заботиться о внутреннем устройстве? Я не верю, что с таким подходом инженер придумает все возможные тестовые сценарии. Если знать внутреннее устройство продукта и читать код, можно избежать дублирования тестов на высоких уровнях пирамиды тестирования. 
Вариант пирамиды от Мартина Фаулера В тестировании чёрного ящика есть такая же ловушка, как и в security through obscurity. Нельзя полагаться только на этот тип тестирования. Продукт может удовлетворять заявленным требованиям, при этом включать большое количество скрытых багов. Тогда по аналогии с безопасностью через неясность, единственным гарантом качества будет наше неведение о том, как система устроена внутри. Преимущество тестирования методом чёрного ящика в том, что тесты не зависят от имплементации. Здорово. Но это искусственное ограничение не должно мешать разбираться во внутренностях. Когда тестировщик знает, как работает продукт: 
Малевич агитирует за тестирование чёрного ящика Наверное, всё та же любовь к чёрному ящику привела ко второй проблеме. Нередко возникает ситуация, когда кандидат, у которого Selenium указан в качестве основного инструмента в резюме, не разбирается, как работает браузер и протокол HTTP. Тестирование для таких автоматизаторов — это прежде всего создание скриптов с действиями пользователя. Поверхностный подход, который создаёт лишние ограничения.  Примеры HTTP-кодов и типы HTTP-запросов большинство соискателей называет. Следующий вопрос чаще всего ставит в тупик. Есть страница логина. Пользователь вводит корректные данные для авторизации и кликает на кнопку входа. Что происходит в браузере в этот момент? Почему последующие действия с сайтом не требуют повторной авторизации? Если тестировщик не ответил на эти вопросы, у меня закрадывается сомнение в его компетентности. Это говорит о том, что кандидат: Разработчику будет проще пофиксить баг, если он описан с техническими деталями. «Мой код не попадёт на продакшен, зачем заботиться о качестве?»
Мне видится это попыткой разделить песочницы. Пускай разработчики заботятся о чистоте кода, а мы как умеем.  Помните, в каскадной модели после разработки была стадия верификации? Во времена методологии ватерфолла ответственность за качество переложили на отдел тестирования. Ни к чему хорошему это не привело. Программисты не задумывались о готовности фичи, ожидая, что о проблемах сообщит QA. Пинг-понг между отделами приводил к замедлению разработки. Это цена за разделение ответственности. С приходом Agile команды консолидировались. Пропали «мы» и «они». Команда отвечает за конечный результат. А раз инженерные практики стали общими, то и требования к коду тестов должны выдвигаться такие же, как к коду продукта. Для отсева кандидатов мы отправляли тестовое задание без дедлайна: Лишние усложнения
Нагромождение абстракций, врапперов над классами и бойлерплейт код внутри тестов.
Тестовые методы лучше делать максимально короткими. В этом помогут функции-хелперы и отделение сетапа от действий над объектами и проверками. Нарушение конвенций по именованию классов, методов, переменных
CamelCase в перемешку с подчеркиваниями. Так сейчас не носят. Линтеры и подсказки IDE спасают. Хардкод путей к вспомогательным ресурсам Классическое «на моей машине работает». Хранение бинарных файлов внутри репозитория
Для решения этой проблемы есть git-lfs. Отсутствие консистентности в методах
В одном из решений кандидат описал методы для удаления и пометки «выполнено» так: В первом методе передают текст задачи, во втором — индекс в списке. Пользоваться таким API больно. System.out.println() для логгирования
Не даёт вспомогательной информации, в каком классе произошло событие. Использование Thread.sleep
Для решения этой проблемы есть библиотека awaitility. Она помогает добавить обратную связь к ожиданию выполнения необходимого условия. Общие исключения вместо асертов
Пример: тест добавляет несколько пунктов в список задач и отмечает все пункты как выполненные. Идея в том, что в случае проблем, метод findElement вернёт NoSuchElementException и тест свалится. Если позже посмотреть на результаты прогона тестов, NoSuchElementException введёт в заблуждение: непонятно, по-настоящему тест упал или код теста кривой. Нужно использовать асерт с понятным сообщением об ошибке в случае падения теста. Злоупотребление асертами с булевыми значениями
assertTrue или assertFalse используется для всего подряд: Здесь лучше использовать assertEquals, чтобы иметь контекст при падении теста. Не предусмотрена параметризация запуска тестов
Пример: URL сайта для тестирования прибит гвоздями в коде. Отдельно стоит упомянуть работу с git. Чаще всего задание присылали одним коммитом. Писать понятные коммит-месседжи и разбивать большую задачу на несколько обособленных — необходимый навык, особенно в командной работе. Описанные выше проблемы — мой личный опыт и впечатления после собеседований. По наблюдениям годы опыта кандидата никак не коррелирует с количеством пробелов. Избегайте тестировщиков-гомеопатов, инвестируйте время в прокачку технических навыков сотрудников. Тестировщикам есть, чему поучиться у разработчиков и наоборот. Да прибудет сила с теми, кто строит инженерную культуру и плывёт против течения. Я буду рад ошибаться и счастлив, если в вашей компании с наймом всё по-другому. UPD 11/02/20: На вебинаре «Портрет тестировщика» делюсь мнением о том, как вижу профессию изнутри. Software Developer In Test