Додо сказал:
— Правильность формы несущественна! А потом расставил всех без всякого порядка по кругу. Никто не подавал команды — все побежали, когда захотели.
Л.Кэрролл, «Приключения Алисы в стране чудес»
Развивая автоматизацию тестирования, можно найти много мест, куда приложить силы. Распыляя усилия и преследуя ложные цели мы не только потратим время и ресурсы впустую, но и нанесем разработке вред.
Если знать, на каком уровне развития находится автоматизация тестирования проекта сейчас и куда в такой ситуации инвестировать, можно не просто добиться большей отдачи, но и улучшить разработку в целом. Основные принципы инвестирования ресурсов можно попробовать сформулировать в виде короткого манифеста.
Пожалуй самый распространенный и общепризнанный манифест в области автоматизации тестирования был создан в 2003 году Джерардом Месарошем и его коллегами из ClearStream Consulting.
В своем заявлении они декларируют 12 требований, которым обязан удовлетворять каждый отдельный тест. Для примера, одно из таких требований — краткость. Тест должен быть настолько простым насколько это возможно, но не проще.
В дальнейшем описанные идеи получили развитие в книге «Шаблоны тестирования xUnit. Рефакторинг кода тестов xUnit Test Patterns». Это ценное руководство для разработчиков, где Месарош подробно разбирает множество проблем, связанных с unit-тестами и предлагает шаблоны программирования для их решения.
Однако, понимания как разрабатывать отдельные тесты недостаточно для успешного развития автоматизации. Ресурсы всегда ограничены. Поэтому ключевым фактором успеха будет еще и понимание того, какие качества нужно развивать в первую очередь.
Базовые качества тестов — это доверие и поддерживаемость. Их и необходимо обеспечить в первую очередь.
Доверие — полная уверенность всех работающих с автоматизированными тестами в результатах их запуска. Если зеленые тесты не гарантируют, что проверка отработала — им не будут доверять ручные тестировщики. Если красный тест не означает наличия проблемы — не будут верить программисты. Если тесты случайным образом будут то красные, то зеленые — их станут игнорировать все в равной мере.
Поддерживаемость — возможность разработчиков работать с кодом приложения, не вкладывая неприемлемый объем усилий в поддержку существующих тестов в рабочем состоянии.
Несбалансированность объема работ по поддержке тестов и объема изменений в коде приведет к коллапсу разработки. Представьте, что внесение изменений в код в одном случае требует изменений одного тестового класса, а в другом случае — сотни тестовых классов, или просто на каждую измененную строку кода нужно исправить сто строк в тестах. Тогда стоимость разработки взлетит до небес, а разработчики будут стремиться вносить в код минимум изменений. В итоге код продукта уйдет в заморозку и его развитие прекратится.
Упавший тест, который не выявил сути выявленной проблемы, “expected true was false”, потребует глубокого разбирательства в коде теста для ее решения. Такие усилия будут постоянно тратиться впустую, отнимая время у действительно важных задач.
Обеспечение доверия к тестам и их поддерживаемости — технически сложная и трудоемкая задача, но ее решение дает небольшой видимый эффект. Многие воспринимают наличие этих качеств как должное. Однако, если тесты неподдерживаемые или к ним нет доверия, любые другие инициативы по автоматизации обречены на провал.
Добившись успеха в соблюдении санитарных норм можно перейти к максимизации пользы, которую тесты могут принести для разработки. Для этого нужно максимально, но без ущерба стабильности, повысить скорость прогона тестов и обеспечить их расширяемость — возможность создавать новые тесты.
Скорость — полное время, необходимое для прогона тестов, которое определяет их применимость на качественном уровне.
Обнаружение ошибок на максимально ранней стадии — принцип, позволяющий существенно повысить продуктивность разработки, поскольку всегда проще исправить проблемы в момент их возникновения. И именно быстрые тесты позволяют это обеспечить.
Быстрые тесты обращают внимание разработчика на ошибку, пока он еще в игре. Если тесты выполняются долго, то разработчик узнает об ошибке уже после переключения на другие задачи. Это слишком поздно, так как потребуются дополнительные усилия, чтобы вернуться к проблеме. Пустая трата времени. Раздражает. Демотивирует.
Расширяемость — возможность разработчиков создавать новые тесты быстро и качественно.
Если создание каждого теста превращается в изобретение велосипедов в духе «как подменить поведение метода», «как создать тестового пользователя», «как сделать скриншот страницы» и т.д., вряд ли можно ожидать, что покрытие кода тестами будет расти. Скорее оно будет ползти.
Покрытие тестами всего нового кода — основной способ получить максимальную отдачу от написания тестов, поскольку именно новый код наиболее подвержен ошибкам и доработкам. Однако, воплотить этот принцип, не решив проблемы расширяемости тестов, будет очень трудно.
Обеспечение скорости выполнения тестов и их расширяемости — способ получить от автоматизации ощутимую пользу и сделать написание тестов осознанно привлекательным для разработчиков.
С точки зрения ручного тестирования, на данном этапе работа сокращается опосредованно. Проблема, найденная автотестами, будет исправлена разработчиком сразу, и не потребует участия ручного тестирования. Это хорошо, но это далеко не все, что могут дать тесты.
Работая с автотестами и сохраняя одновременно ручное тестирование, хочется объединить эти процессы естественно, чтобы каждый из них получал максимальную выгоду от другого. А для этого нужно интегрировать процессы автоматизации и ручного тестирования и обеспечить покрытие продукта тестами.
Покрытие — автоматическая проверка, как минимум, всех ручных кейсов по всему продукту, либо по его отдельным модулям.
Реализация полного покрытия тестами естественным образом, требует написания новых тестов. Если проблема расширяемости тестов не решена, такой процесс окажется неоправданно дорог, а тесты полученные в результате будет трудно поддерживать. Расширение множества тестов неизменно приведет к увеличению времени на их исполнение. Тут важна скорость, медленные тесты существенно теряют в цене, даже если их очень много.
Интеграция с ручным тестированием — замена части работ ручного тестирования прогоном автоматизированных тестов.
В идеале нужно стремиться, чтобы «то, что не менялось» никогда не тестировалось вручную повторно. Конечно, добиться этого сложнее всего.
Идея интеграции тестов в процесс ручного тестирования также не имеет смысла, если не обеспечена расширяемость тестов, поскольку автоматизация ручных сценариев будет невозможна в должной степени. Скорость тестов так же важна. Слишком медленный прогон автоматических тестов приведет к тому, что тестировщику будет проще проверить все руками, нежели ждать выполнения автоматики.
Обеспечение покрытия и интеграция с ручными тестированием — то, что придает концепции автоматизированного тестирования целостный и законченный вид.
В долгосрочной перспективе автоматизация тестирования необходима, и затраты ресурсов на ее обеспечение неизбежны. Однако, если добиться результата на качественном уровне, можно хотя бы начать сокращение издержек на ручное тестирование. Это само собой приведет к сокращению цикла разработки.
Раз уж мы вынуждены писать тесты, нужно добиться того чтобы эти усилия приносили максимум пользы для всех, а работа двигалась быстрее.
Дмитрий Мамонов
Департамент разработки,
Подразделение мержа в мастер,
Отдел работы с гит,
Ведущий оператор баш консоли 2 разряда
— Правильность формы несущественна! А потом расставил всех без всякого порядка по кругу. Никто не подавал команды — все побежали, когда захотели.
Л.Кэрролл, «Приключения Алисы в стране чудес»
Развивая автоматизацию тестирования, можно найти много мест, куда приложить силы. Распыляя усилия и преследуя ложные цели мы не только потратим время и ресурсы впустую, но и нанесем разработке вред.
Если знать, на каком уровне развития находится автоматизация тестирования проекта сейчас и куда в такой ситуации инвестировать, можно не просто добиться большей отдачи, но и улучшить разработку в целом. Основные принципы инвестирования ресурсов можно попробовать сформулировать в виде короткого манифеста.
Манифест автоматизации тестирования
Доверие к тестам и их поддерживаемость — важнее всего.
Скорость и расширяемость тестов важны только при наличии доверия и поддерживаемости.
Покрытие всего продукта тестами и интеграция автоматизации с ручным тестированием имеют смысл только при достижении доверия, поддерживаемости, скорости и расширяемости тестов.
Критика
Пожалуй самый распространенный и общепризнанный манифест в области автоматизации тестирования был создан в 2003 году Джерардом Месарошем и его коллегами из ClearStream Consulting.
В своем заявлении они декларируют 12 требований, которым обязан удовлетворять каждый отдельный тест. Для примера, одно из таких требований — краткость. Тест должен быть настолько простым насколько это возможно, но не проще.
В дальнейшем описанные идеи получили развитие в книге «Шаблоны тестирования xUnit. Рефакторинг кода тестов xUnit Test Patterns». Это ценное руководство для разработчиков, где Месарош подробно разбирает множество проблем, связанных с unit-тестами и предлагает шаблоны программирования для их решения.
Однако, понимания как разрабатывать отдельные тесты недостаточно для успешного развития автоматизации. Ресурсы всегда ограничены. Поэтому ключевым фактором успеха будет еще и понимание того, какие качества нужно развивать в первую очередь.
Соблюдение санитарных норм
Базовые качества тестов — это доверие и поддерживаемость. Их и необходимо обеспечить в первую очередь.
Доверие — полная уверенность всех работающих с автоматизированными тестами в результатах их запуска. Если зеленые тесты не гарантируют, что проверка отработала — им не будут доверять ручные тестировщики. Если красный тест не означает наличия проблемы — не будут верить программисты. Если тесты случайным образом будут то красные, то зеленые — их станут игнорировать все в равной мере.
Поддерживаемость — возможность разработчиков работать с кодом приложения, не вкладывая неприемлемый объем усилий в поддержку существующих тестов в рабочем состоянии.
Несбалансированность объема работ по поддержке тестов и объема изменений в коде приведет к коллапсу разработки. Представьте, что внесение изменений в код в одном случае требует изменений одного тестового класса, а в другом случае — сотни тестовых классов, или просто на каждую измененную строку кода нужно исправить сто строк в тестах. Тогда стоимость разработки взлетит до небес, а разработчики будут стремиться вносить в код минимум изменений. В итоге код продукта уйдет в заморозку и его развитие прекратится.
Упавший тест, который не выявил сути выявленной проблемы, “expected true was false”, потребует глубокого разбирательства в коде теста для ее решения. Такие усилия будут постоянно тратиться впустую, отнимая время у действительно важных задач.
Обеспечение доверия к тестам и их поддерживаемости — технически сложная и трудоемкая задача, но ее решение дает небольшой видимый эффект. Многие воспринимают наличие этих качеств как должное. Однако, если тесты неподдерживаемые или к ним нет доверия, любые другие инициативы по автоматизации обречены на провал.
Максимизация пользы для разработчиков
Добившись успеха в соблюдении санитарных норм можно перейти к максимизации пользы, которую тесты могут принести для разработки. Для этого нужно максимально, но без ущерба стабильности, повысить скорость прогона тестов и обеспечить их расширяемость — возможность создавать новые тесты.
Скорость — полное время, необходимое для прогона тестов, которое определяет их применимость на качественном уровне.
Обнаружение ошибок на максимально ранней стадии — принцип, позволяющий существенно повысить продуктивность разработки, поскольку всегда проще исправить проблемы в момент их возникновения. И именно быстрые тесты позволяют это обеспечить.
Быстрые тесты обращают внимание разработчика на ошибку, пока он еще в игре. Если тесты выполняются долго, то разработчик узнает об ошибке уже после переключения на другие задачи. Это слишком поздно, так как потребуются дополнительные усилия, чтобы вернуться к проблеме. Пустая трата времени. Раздражает. Демотивирует.
Расширяемость — возможность разработчиков создавать новые тесты быстро и качественно.
Если создание каждого теста превращается в изобретение велосипедов в духе «как подменить поведение метода», «как создать тестового пользователя», «как сделать скриншот страницы» и т.д., вряд ли можно ожидать, что покрытие кода тестами будет расти. Скорее оно будет ползти.
Покрытие тестами всего нового кода — основной способ получить максимальную отдачу от написания тестов, поскольку именно новый код наиболее подвержен ошибкам и доработкам. Однако, воплотить этот принцип, не решив проблемы расширяемости тестов, будет очень трудно.
Обеспечение скорости выполнения тестов и их расширяемости — способ получить от автоматизации ощутимую пользу и сделать написание тестов осознанно привлекательным для разработчиков.
С точки зрения ручного тестирования, на данном этапе работа сокращается опосредованно. Проблема, найденная автотестами, будет исправлена разработчиком сразу, и не потребует участия ручного тестирования. Это хорошо, но это далеко не все, что могут дать тесты.
Сокращение цикла разработки и ручного тестирования
Работая с автотестами и сохраняя одновременно ручное тестирование, хочется объединить эти процессы естественно, чтобы каждый из них получал максимальную выгоду от другого. А для этого нужно интегрировать процессы автоматизации и ручного тестирования и обеспечить покрытие продукта тестами.
Покрытие — автоматическая проверка, как минимум, всех ручных кейсов по всему продукту, либо по его отдельным модулям.
Реализация полного покрытия тестами естественным образом, требует написания новых тестов. Если проблема расширяемости тестов не решена, такой процесс окажется неоправданно дорог, а тесты полученные в результате будет трудно поддерживать. Расширение множества тестов неизменно приведет к увеличению времени на их исполнение. Тут важна скорость, медленные тесты существенно теряют в цене, даже если их очень много.
Интеграция с ручным тестированием — замена части работ ручного тестирования прогоном автоматизированных тестов.
В идеале нужно стремиться, чтобы «то, что не менялось» никогда не тестировалось вручную повторно. Конечно, добиться этого сложнее всего.
Идея интеграции тестов в процесс ручного тестирования также не имеет смысла, если не обеспечена расширяемость тестов, поскольку автоматизация ручных сценариев будет невозможна в должной степени. Скорость тестов так же важна. Слишком медленный прогон автоматических тестов приведет к тому, что тестировщику будет проще проверить все руками, нежели ждать выполнения автоматики.
Обеспечение покрытия и интеграция с ручными тестированием — то, что придает концепции автоматизированного тестирования целостный и законченный вид.
В долгосрочной перспективе автоматизация тестирования необходима, и затраты ресурсов на ее обеспечение неизбежны. Однако, если добиться результата на качественном уровне, можно хотя бы начать сокращение издержек на ручное тестирование. Это само собой приведет к сокращению цикла разработки.
Раз уж мы вынуждены писать тесты, нужно добиться того чтобы эти усилия приносили максимум пользы для всех, а работа двигалась быстрее.
Дмитрий Мамонов
Департамент разработки,
Подразделение мержа в мастер,
Отдел работы с гит,
Ведущий оператор баш консоли 2 разряда
Поделиться с друзьями
Комментарии (12)
red-9m
20.02.2017 18:17Ожидал увидеть если не все, то хотябы что-то из этого:
1. Сравнение подходов ручного и автоматического тестирования, плюсы и минусы.
2. На сколько автоматические тесты могут заменить ручные, какие соображения и противопоказания.
3. Добавлять ли юнит тесты в автоматические или они должны жить отдельно.
4. С чего начать «приручать» автотесты.dm_wrike
20.02.2017 18:22-14. Начать нужно с доверия.
3. Не думаю что это принципиальный вопрос. Могут быть за и против в зависимости от ситуации.
На остальные пункты ответы есть в предыдущей статье.
lxsmkv
Вообще хочу отметить что часто когда статьи (а я их читал достаточно) говорят об автоматизации тестирования, как правило не разделяют виды тестирования. Получается что тезисы безоговорчно равноприменимы ко всем видам тестирования. На практике это не так. И нужно и важно выделять специфику разных видов автоматизированного тестирования.
Например: «Тесты должны быть независимы друг от друга. Их можно выполнять в любой последовательности».
Для юнит-тестов это высказывание может быть верным. Там подготовка теста (Setup) не сильно влияет на время прогона.
Но UI тесты, (приемочные тесты, где мы проверяем кусок фунционала в качестве пользователя) могут отклоняться от этого правила потому, что тесты должны быть быстрыми. Если я каждый раз буду заходить в свой раздел приложения перед началом проверки, то это будет занимать больше половины всего времени.
Я руководствуюсь принципом — тест должен делать только то что является предметом теста. Вход в раздел является тестом, и выполяется первым. После этого не нужно выполнять вход. Поэтому у меня тесты идут друг за другом. И это нормально. Упал вход, все тесты за ним посыпались — разрабы чинят вход. Потому что иначе пользователь до нижележащего фунцкионала просто не доберется. Все честно. Я мог бы исхитриться и обойти процедуру входа для последующих тестов, но это бы исказило пользовательский сценарий. Для сравнения: я мог бы выполнять вход перед каждым тестом, но если он сломан результат будет тем же. В первом случае первый тест покажет что вход не был выполнен, а последующие за ним тесты покажут что подраздел не найден. Во втором случае все тесты покажут что вход не был выполнен. Красных тестов будет что так что эдак одинаково.
Вобщем, для каждой задачи свой подход. Нельзя сваливать всю автоматизацию в одну кучу. И это главная проблема среди проблем автоматизации.
dm_wrike
Независимость тестов это технический способ обеспечить их стабильность,
а значит и доверие к ним. Это важно если это достижимо.
Если независимость стоит слишком дорого, можно искать другие технические решения.
То что вы говорите вполне оправдано.
lxsmkv
Стабильность тестов в моем понимании это когда тесты на одной и той же версии продукта выдают при повторном выполнении один и тот же результат. Результат может быть и красным, но он не должен изменяться при повторении. Если тесты всегда выдают стабильный красно-зеленый результат — на доверии это скажется негативно. Значит обеспечив стабильность мы еще не обеспечили доверие. Так же если все тесты всегда зеленые это тоже скажется на доверии негативно. Может они и не тестируют ничего.
А стабильность сама по себе действительно очень важна. У нас были фазы где мы красно-зеленые тесты гоняли чтобы проверить обновления в инструменте. Если все как и раньше — едем дальше.
Другое дело надежность, она определяет вероятность ложного срабатывания (срабатывание это красный результат) Вот надежность она влияет на «доверие». Еще раз, стабильность — одинаковый результат при повторном исполнении в одинаковых условиях, надежность — обратная величина количеству ложных срабатываний. Если стабильность можно проверить повторным прогоном, надежность проверить можно только заглянув в код.
Автоматизация помогает выявить неявные изменения. Это может кому-то показаться странным но несмотря на то что наши UI тесты описывают пользовательские сценарии, сам «предмет теста» как я его называю, практически всегда в порядке, в 85% случаев ломается что-то вокруг, и тесты перестают работать. И это хорошо. Т.е. тесты ненадежные. Мы обмотали наш продукт красной проволкой и смотрим где эта проволока порвется. Получается как в том анекдоте, что «по дырочкам никогда не рвется». И пусть. Главное чтобы тесты реагировали на изменения.
А вообще я не доверяю тестам ни своим ни чужим. Всегда есть что-то что я не учел, пусть это даже пробел в спецификации. Тесты всегда недостаточно хороши. Так что такая категория как доверие, она слишком человеческая, чтобы применять ее в техническом плане. Я доверяю автоматизации тогда когда она находит ошибки в ПО. Находит — хорошо, не находит — плохо. А полагаюсь я на автоматизацию каждый день иначе я бы просто был не в состоянии даже близко проверить столько конфигураций
Dreamk
Простите, но вы или новичек в автоматизации или не серьезно ей занимаетесь. Тут есть сразу две проблемы(может больше): 1. При вашем подходе вы не сможете параллелить тесты. 2. При вашем подходе вы вообще ничего не протестируете(упал вход, чинят вход). Вот реальный кейс: разработчики выкатывают патч, в котором кроме изменений в логине(которые и сломали) есть так же изменения в других частях приложения. И вот при вашем подходе, когда тесты зависимы — все будут сидеть и ждать пока пофиксят логин(ну или переключаться на другие таски). А если делать независимы — то при сломанном логине, тесты по документообороту, обмену сообщениями, чем угодно еще, что входило в патч — будут идти и давать результат. В итоге уже после первого прогона станет более менее ясно — сломали логин или вообще все сломали и не выкатываемся
lxsmkv
Ну у нас такая ситуация, что не мы выполняем тесты мы их только пишем и анализируем результаты. Инструмент у нас самописный и приложение embedded. И результат автоматизированных тестов мы получаем только на следующий день, хотя новый билд у ручных тестировщиков уже сегодня, и соотв. информация «рабочий» ли билд известна уже сегодня. Т.е автоматизация не перед ручным тестированием, а после ручного смоук теста. Да, после. И все были бы рады, если бы автоматизация могла предоставить общую картину состояния билда, а она и предоставляет, только заказчик собирает все результаты в общий процент и смотрит на него. А контекстов штук двенадцать, разные команды, все пишут свои тесты. Кроме того у нас кроме красного результата есть еще и желтый, желтый результат не отображается в статистике, и не я это придумал. Вобщем все весьма и весьма грустно.
Ну да, можно сказать, что заказчик не серьезно подходит к автоматизации.Ведь она даже в бюджет команд не заложена. Чистая прихоть заказчика.
Так что, как правильно все проходили а в жизни по разному бывает. И добрых книжных истин хватает везде, а информации как же люди справляются в жизни — об этом в основном никакой информации.
Меня просто не устраивает когда догму пытаются втюхать так как будто вот только так и правильно. Как правильно разрабатывать об этом десятилетиями спорят, наверное потому что серебрянной пули нет. Так и тут.
Но спасибо вам за ответ, здравая мысль она вдохновляет.
lxsmkv
Я еще несколько раз перечитал ваш ответ, и понял что же меня при первом прочтении резануло: по вашей логике продукт со сломаным логином можно выдавать пользователю? И зачем оно ему если он даже зайти в систему не сможет?
То что другая команда за 200 километров от нас после такого фейла чинит логин в срочном порядке не значит что все курят, все работают дальше, над своим функционалом. У нас такая система что для работы мы можем откатить сторонние артефакты назад, и проапдейтить свою ветку и работать с работающей версией логина.
У нас некоторые по три-четыре недели артефакты не обновляют.
И тесты у меня не совсем все друг за другом идут, а только шаги пользовательских сценариев, Один пользовательский сценарий у кого-то это один тест, а у меня test-suite (тестовый набор). Kаждый шаг в них это свой тест, чтобы в тест-репорте видно было с какого места последовательность запнулась. На каждый сценарий (тестовый набор) свой setup и teardown. T.e. их можно рапараллелить по тестовым наборам. Но не каждый тест в отдельности.
Чтобы вы представляли масштаб, то над чем мы работаем по обьему функционала схоже с ванильной Android OS. Наша работа только несколько компонент во всей системе.
Dreamk
Нет, вы не правильно поняли. Я к тому, что главная задача — сократить время на тестирование. и в вашем случае — вы фиксите баги последовательно(так как находятся они последовательно во время запуска автотестов). А в моем случае — все тестируется паралелельно и соответственно фиксятся они тоже паралелльно.
lxsmkv
Да, при таком подходе есть недостаток, что завалившийся тест перекрывает «видимость» на следущий за ним функционал. И пока причина не будет устранена, эти перекрытые части остаются непротестироваными. С другой стороны, по скольку багрепорты пишу тоже я, а мой ресурс не бесконечен, такой подход работает. Писать тест так чтобы он выполнялся в любом случае, заставило бы нас сильно залезать во внутреннее состояние системы, а это во первых на нашей системе очень сложно (при проектировании тестируемость в нее не закладывали), во вторых черевато побочными эффектами.