Интеграция сценарного тестирования в процесс разработки

Публикация № 1089151

Программирование - Практика программирования

80
Разработчик системы «Тестер» Дмитрий Решитко в своем докладе на конференции INFOSTART EVENT 2018 EDUCATION показывает, что процесс тестирования можно очень плотно интегрировать в процесс разработки, что внедрение тестирования – это возможность развития программиста как такового, позволяющая ему упорядочивать ход мыслей и оставаться «в фокусе». Навыки построения процесса кодирования на стыке с тестированием сокращают время на концентрацию, освобождают от страха перед изменениями и улучшают память разработчика.

Меня зовут Решитко Дмитрий, я работаю в компании C.T.Consultants Inc, город Монреаль.

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

 

Ситуация с тестированием

Давайте немного поговорим про ситуацию с тестированием.

  • Несколько лет назад вопросами тестирования занимались только энтузиасты, обладающие особой страстью к повышению качества программных продуктов, а также крупные компании по разработке программного обеспечения – у них по регламенту всегда были выделенные специалисты-тестировщики. Но сегодня, в связи с ростом количества поддерживаемых баз данных, их версий, режимов совместимости, различной разрядности платформы и т.д. вопрос с тестированием приложений выходит на другой уровень. Уже не отвертеться.
  • Одновременно с этим средства по тестированию тоже эволюционируют, применяются известные методики – TDD и BDD. Есть уже, как минимум, пять инструментов по тестированию.
  • С одной стороны, можно было бы говорить о том, что у нас все здорово получается – есть проблема и решение для нее в виде целого набора различных инструментов. Но, с другой стороны, само количество этих инструментов заставляет задуматься о том, что тема тестирования до конца еще не раскрыта. Тем более, что с периодичностью раз в полтора-два года появляется очередное решение, и все это начинается со словами «Мы в свое время попробовали, нам не понравилось, поэтому мы решили разработать свой собственный инструмент». Такая же ситуация сложилась и у меня пару лет назад, и это вдохновило меня написать Тестер.

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

 

Требования к инструменту

 

 

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

  • Основная идея заключалась в том, чтобы процесс тестирования был тесно интегрирован в процесс разработки, чтобы тестирование было ведущим, а не ведомым звеном программирования задач.
  • Среда разработки (IDE) должна быть максимально эргономичной. Казалось бы, такими должны быть любые инструменты, но, когда мы говорим об инструментах для программиста, требования к эргономичности серьезно повышаются, потому что мы пишем код по 8 часов в день, и из-за каких-то незначительных шероховатостей в процессе разработки, некоторые инструменты могут просто отмирать, даже если в них заложена прекрасная методика.
  • Все тесты должны выполняться в отдельной среде. Менеджер тестирования не должен запускаться каждый раз, потому что предполагается, что система тестирования – это просто продолжение вашей среды разработки. То есть, например, на первом мониторе вы занимаетесь основной разработкой – у вас открыт конфигуратор, где вы пишите код 1С, а на втором мониторе у вас открыт менеджер тестирования с оболочкой для создания тестов. Вы вызываете 1С в режиме отладки, подключаетесь к сеансу менеджером тестирования, запускаете тест и смотрите, что происходит. Если тест падает, вы закрываете приложение или возвращаетесь обратно в конфигуратор, пишите код, перезапускаете приложение и опять запускаете тест в системе тестирования. Весь инструментарий разработки тестов должен быть «на кончиках пальцев», все должно быть очень быстро. Обычно, для программистов это важно.
  • База тестов должна быть единой, среда их разработки должна быть облачной. Нам было нужно, чтобы вне зависимости от того, где находится разработчик, у него всегда была возможность, не занимаясь какими-то промежуточными операциями, открыть систему тестирования и сразу приступить к написанию/запуску тестов, просмотру журнала ошибок, скриншотов и т.д.
  • Среда разработки тестов должна обеспечивать контроль доступа к тестируемым приложениям и/или отдельным тестам. Некоторые сценарии могут быть чувствительны к вопросам безопасности систем заказчика (не потому, что там внутри пароли, а сама логика сценария должна быть ограничена для просмотра).

 

Пункты спорные, и я обязан дать некоторые комментарии:

  • Классически, мы привыкли, что в основе создания сценарных тестов лежит процесс “накликивания”, с дальнейшей сериализацией шагов в визуальное дерево инструмента тестирования. Это очевидно, просто и наглядно: шаги затем запускаются, становятся зелеными или красными, а при необходимости - могут быть откорректированы. Так зачем их тогда программировать? Мнение на этот счет такое: любой сценарий, в общем случае, это не просто воспроизведение действий, это некий алгоритм. А лучшего способа выражать алгоритмы в совокупности факторов, кроме как языками программирования, человечество не научилось. Конечно, любой алгоритм можно положить в “интерфейсный корсет” и использовать множество различных свойств, полей и палитр к ним, здесь будут и авто-подстановочные символы и глобальные переменные среды, и возможно еще что-то, что я упустил. И когда (что неизбежно), этих свойств становится слишком много, начинают появляться соглашения, что если включено такое-то свойство, то оно еще где-то на что-то влияет, если сменилась версия, то нужно пройтись обработкой по-включать какие-то флажки или заполнить поля, и так далее. В конечном итоге, всё это приводит к тому, что обучить человека работе с каким-либо инструментом и всеми его особенностями, во времени, становится точно не проще, чем научить его базовым конструкциям языка 1С, десятку функций глобального контекста и методов тестируемого приложения.
  • С кодом значительно проще работать. Его легко читать (потому что вся нужная информация и есть код, не нужно смотреть свойства, запоминать соглашения). Код всегда можно отрефакторить, что-то быстро найти, сгруппировать в процедуру или функцию, произвести глобальную замену, произвести обмен модулями и многое другое, ведь это просто текст. А если мы используем некий инструмент, который хранит ваши тесты в каком-то специализированном виде (например, в XML), то с этим уже начинаются проблемы – и, чтобы иметь возможность динамично переделывать тесты, приходится что-то дорабатывать сверху.
  • Чтобы обеспечить неразрывность процесса программирование-тестирование, механика разработки видится примерно так: основной экран – это конфигуратор, на втором мониторе – среда разработки тестов. Нажимаем F5 – запускаем тест. Если он прошел, возвращаемся в конфигуратор, делаем что нужно, нажимаем Ctrl+Shift+F5 для перезапуска, опять тестируем и т.д. Так этот цикл и продолжается.
  • Среда разработки должна позволять анализировать интерфейс тестируемого приложения, чтобы при написании кода в Тестере вы могли автоматически использовать весь его визуальный контекст. Например, если вы тестируете нажатие на кнопку и пишите «Нажать ()», то при открытии кавычек в скобках система должна автоматически показать, какие кнопки есть в тестируемом приложении, чтобы пользоваться этим было легко и удобно.

 

Очередной набор щекотливых тезисов, требующих пояснения:

  • Мы решили, что для тестирования бизнес-логики не должна использоваться эталонная или специально заготовленная база. По базам мы поговорим немного позже, когда перейдем к практическим примерам.
  • Все данные для тестирования должны создаваться в ходе самого теста – это тоже требование, все ради скорости. Я потом объясню, как мы эти вопросы прорабатываем.
  • Все сценарии должны легко воспроизводиться на любом компьютере любого разработчика, чтобы не было такого, что у нас где-то есть в отдельном месте пул эталонных баз – подготовленных конфигураций с данными, и мы потом этот пул распределяем между всеми разработчиками – такого быть не должно. За все должен отвечать сценарий, который пишет программист.

 

Отчетность по тестам должна быть интерактивной, а не статичной. Это не должна быть простая веб-страничка с «семафорчиками». Допустим, разработчик просит меня посмотреть, из-за чего падает тест, я фильтрую журнал ошибок по его профилю, и по клику перехожу к строке сценария, в которой (строке) возникла проблема. Подобный “экстремизм” в тестировании служит одной мощной цели – тестирование должно быть интегрировано, вживлено непосредственно в процесс разработки, чтобы разработка без швов включала в себя тестирование. Если инструментарий не будет поставлять максимальное удобство в этих вопросах, тестирование всегда будет откладываться. А если оно будет откладываться, начнет возникать целый ряд побочных эффектов, один из которых заключается в том, что тестирование для программиста становится обузой, и приходится уже в административном порядке требовать от него написания тестов или чего-то еще.

Тестер хочет показать, что вопрос тестирования можно интегрировать в разработку очень плотно, и это не будет административной частью сделки программиста с компанией, в которой он работает. Это будет инструмент, который позволит ему развиваться, как программисту, упорядочивать свой ход мыслей, оставаться «в фокусе».

 

Моральная подготовка

 

По поводу моральной подготовки:

  • Очень часто, когда мы говорим о тестировании, мы в основном, отмечаем, какие у нас будут хорошие результаты, насколько качественным станет наш софт и т.д. Но многие недооценивают сложность всего вопроса тестирования. Сложность - высокая. Есть парадокс – мы можем смело говорить о том, что научить человека «с чистого листа» программировать на 1С значительно проще, чем научить его затем тестировать то, что он напрограммировал на 1С. Поэтому нужно понимать, что вопросы тестирования – это сложные вопросы. К ним нужно быть готовым. Нужно знать все функции глобального контекста. Если вы в конфигураторе нажимаете «Ctrl+пробел» не для того, чтобы ускорить ввод, а для того, чтобы найти какое-то ключевое слово или функцию, потому что вы их не помните, с написанием тестов могут возникнуть большие трудности. Я бы предложил в этот момент не думать о тестировании, а подтянуть знания глобального контекста и основные методы по работе с коллекциями до уровня, когда они будут «на кончиках пальцев».
  • Писать тесты, это – определенная дисциплина. Дело в том, что мы программисты, можем две недели заниматься прокрастинацией, а потом за день войти в режим «потока» и резко начать писать кучу кода, «накидывать» объекты один за другим. А потом по окончании всего этого процесса успешно сдать проект и хвалить себя: «Какой я классный программист, сделал за день то, что нужно было за две недели». Я считаю, что это – неправильный подход, этим не нужно злоупотреблять. Если к вам в этот момент подойти и отвлечь от вашего режима «потока», то в вашей работе произойдет надлом, и вы не сможете вернуться в ментальный контекст того процесса, в котором находились, когда накидывали объекты, писали тьму кода. Это потом резко забывается. Даже если вы пытаетесь в голове весь этот контекст удержать – пишете какие-то заметки, скриншоты, применяете другие инструменты, то по прошествии времени все равно вряд ли сможете вернуться в то состояние, в котором находились. А тестирование позволяет формализовать этот процесс – каждый маленький тест, который вы создаете в системе, фактически работает как “зафиксировать транзакцию” и высвобождает ваши мозги от удержания в них текущей информации.

 

 

Практическое применение Тестера. Проверка адреса

 

 

Давайте немного пройдемся по практике. На слайде показан процесс тестирования приложения. На заднем плане – наша модифицированная разработка ERP, а справа в режиме менеджера тестирования запущен сам «Тестер».

Вот так он выглядит: справа – дерево тестов, а слева – код выбранного теста.

Здесь у нас есть задача – проверить, что длина адреса в справочнике «Лидов» соответствует длине адреса в «Контактной информации» контрагента.

Предположим, что есть некий справочник «Контактная информация», где хранится номер квартиры, адрес улицы и т.д. Этот справочник подчинен ряду других, например, «Физическим лицам», «Контрагентам» и т.д. Цель у него одна – собрать и сохранить в системе контактную информацию в каком-то едином формализованном виде.

И, например, возникает задача создать блок CRM, в котором, как вы знаете, одним из ключевых моментов является сбор интересов потенциальных покупателей с помощью документа «Лид», куда вводится первичная информация по клиенту – в том числе, его адрес, телефон и т.д. Но в «Лиде», например, могут быть не указаны номер дома или страна, а указан только адрес улицы. Более того, для документа «Лид» могут быть дополнительные требования к доступу – там может быть какой-то хитрый RLS, который делает невозможным использование справочника «Контактной информации».

Но поскольку, если все сложится хорошо, «Лид» в конечном итоге трансформируется в покупателя и его «Контактную информацию», нам нужно проверить, что размерность тех реквизитов, которые мы накидали на форму «Лида», соответствует размерности реквизитов, которые находятся у нас в «Контактной информации».

Первое, что приходит в голову – это сделать определяемый тип со строкой в 150 символов и присвоить его этим полям. Но если ваша конфигурация является поставщиком для мобильного решения, то возникает проблема, потому что в мобильном решении определяемые типы не очень хорошо работают. Это первое.

А второе – документ «Лид» не обязательно будет мигрировать в мобильное приложение, там для него может не найтись отражения. В этом случае вам все-таки придется создавать этот реквизит, как отдельный, и ухаживать за ним – проверять, что его размерность в «Лиде» соответствует той же размерности в «Контактной информации».

 

 

На слайде показан этот же тест, но уже в среде Visual Studio Code. Мы создаем массив в тысячу элементов, превращаем его в строку, присваиваем сначала одному реквизиту, потом другому – эта информация сравнивается и выдается сообщение о том, все ли у нас в порядке или нет.

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

 

 

Тестер также умеет работать в режиме «накликивания» сценариев. Но, если в том коде, который вы видели до этого, было 30 строк, то в результате «накликивания» получится вот такая простыня – около 90 строк кода.

В этом режиме удобно быстро накидывать определенную последовательность действий, но, если нужно что-то проверить, например, сравнить два реквизита и их значения, это «кликанием» уже не проверить, придется писать какой-то дополнительный код.

 

 

А вот такое дерево получается, если мы начинаем «кликать» сценарии в инструменте «Сценарное тестирование» от 1С.

 

 

Причем, анализа «накликанных» значений в сценарном тестировании от 1С тоже нет. Чтобы сделать такую проверку, придется добавить еще один какой-то шаг, нажать кучу кнопок и т.д.

Итого, можно сравнить – слева на слайде тест, написанный кодом в «Тестере», а справа – то, что мы «накликали» в «Сценарном тестировании» 1С.

 

Преимущества написания тестов кодом

 

В чем преимущество написания тестов кодом? Есть ряд сценариев, которые очень сложно реализовывать именно «кликанием»:

  • Это сравнение значений на большее/меньшее,
  • Считывание информации и принятие решений по этой информации. Например, если нужно понять, в каком состоянии находится та или иная функциональная опция и протестировать зависящее от нее поведение.
  • То же самое относится к динамическому определению окружения – «накликанный» тест предопределяет начальное состояние, и манипулировать этой информацией сложно.

 

 

Эталонная база

 

Что использовать в качестве базы для тестирования?

Если в предыдущем примере с тестированием размерности адресов все просто – там не нужны никакие тестовые данные, не нужны эталоны – мы просто создаем две формы, сравниваем их, и этого достаточно. То с тестированием бизнес-логики дело обстоит совсем не так. Когда мы начинаем работать с данными, нам нужно понимать – а что у нас будет эталонной базой, как мы это будем делать, какими у нас должны быть тестовые данные и т.д.

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

В общем, с эталонной базой много мороки. Я считаю, что тест сам должен заботиться обо всех задачах, которые на него возложены.

 

Генерация данных для тестирования

 

Что такое данные для тестирования?

Это некие начальные данные и данные, которые создаются во время тестирования.

С начальными данными все понятно – это данные, которые в вашей базе есть по умолчанию: единицы измерения, определенные роли, пользователь «Администратор», подразделение «Администрация» и т.д. Это то, на что ваши тесты могут полагаться. Если вы разрабатываете какую-нибудь типовую конфигурацию, то желательно вообще разработать какой-то отдельный тест, который будет проверять консистентность начальных данных. Просматривая такой тест, новый разработчик, который приходит в команду, сразу сможет понять, какие данные предполагается использовать для тестирования – чтобы ему не пришлось создавать заново подразделение «Администрация» и т.д.

 

 

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

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

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

 

 

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

 

 

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

В следующий практический пример будет вовлечена описанная выше структура сценария.

 

На слайде ниже (подробно с примером можно ознакомиться на сайте проекта Тестер), кодом сценария формируется структура параметров теста, затем, по ней создается окружение, и следом запускается целевая часть программируемого участка задачи. Многократный запуск теста будет пропускать создание окружения и выполнять только целевую часть, которую обычно программисты делают вручную.

 

 

На слайде ниже, изображен пример проверки табличных данных тестируемого приложения с использованием макета:

 

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

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

Журнал заданий позволяет выполнять тестирование на удаленных компьютерах:

 

 

Отчетность, может использоваться как оперативное табло поиска и анализа ошибок, так и средством рассылки результатов тестирования по расписанию:

 

 

Заключение

 

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

 

 

****************

Данная статья написана по итогам доклада (видео), прочитанного на конференции INFOSTART EVENT 2018 EDUCATION. Больше статей можно прочитать здесь.

Приглашаем вас на новую конференцию INFOSTART EVENT 2019!

80

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. karpik666 2637 08.07.19 16:22 Сейчас в теме
Удалось пообщаться во время Инфостарт Event, отличный специалист и человек.
irina_selezneva; fenixnow; goshasilver; +3 Ответить
2. goshasilver 08.07.19 17:07 Сейчас в теме
считаю лучшая самописка для тестирования, а документация так ваще...
fenixnow; +1 Ответить
3. kote 499 09.07.19 00:35 Сейчас в теме
Где можно пощупать "Тестер" ?
5. AlexKo 96 09.07.19 10:28 Сейчас в теме
Выглядит замечательно, документация прекрасная, надо попробовать
6. tsukanov 55 09.07.19 13:59 Сейчас в теме
Я человек простой. Вижу сделанное Решитко, ставлю + не глядя.
Таких программеров крайне мало.
7. sapervodichka 1415 12.07.19 10:10 Сейчас в теме
В лоб ошибки можно так протестировать https://infostart.ru/public/1056811/ например после обновления прогнать не помешает
Оставьте свое сообщение