Тестируем OData в eCATT – 2

Тестируем OData в eCATT – 2

VirVit No Comment
Заметки на полях

Привет.

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

Наша задача – протестировать OData сервис, чтобы любое изменения в его работе тут же показывалось в тестах. Это позволит нам заранее видеть как то или иное изменение скажется на всей системе, особенно, если у нас десятки и сотни тестов, а не 1-2.

OData по сути это формат обмена сообщениями между разными системами. Здесь нет визуальной составляющей, которую нужно или можно тестировать. То есть, мы не сможем проверить, как работа сервиса влияет на отрисовку таблички в приложении или реакцию кнопочки. Об этом я вам позже расскажу.

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

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

Пора работу работать. С версии базиса 7.40 появилась отдельная транзулька SECATT_ODATA, которая делает простую и полезную штуку – пишет тесты за нас. В ней всего три шага и описывать их нет смысла – в сети много примеров как нагенерить тестов. И ни одного примера как использовать это нагенеренное чудо. Поэтому как генерить – в гугл, остальные остаемся со мною.

После генерации у меня появилось две полезные вещи. Первая, это сам класс с тестами, где один тест это один метод класса.

А вторая, это контейнер тестовых данных, которые этот тест (класс) будет кушать, сравнивать и пережевывать. Контейнер можно посмотреть в транзакции SECATT.

Если вы посмотрите исходник класса в части метода SETUP(), который подготавливает данные для тестирования, то увидите, что там хардкодом прописан этот самый контейнер.

Уже сейчас мы можем запустить тест и проверить результат.

Увы, пошутил я. Из-за безопасности в начале определения класса вставлена мина. Нужно развернуть Local Classes, выбрать свой класс и поменять у него уровень риска. Например, вот так.
class LZCL_ZLOGGER_SRV_E_AU_LOGENTRY definition for testing
duration medium
risk level harmless.

Активировать и запустить. Оно запустится. Так как сервис у нас глупый, он по умолчанию вытаскивает все записи журнала за сутки. У меня это тысячи строк. Поэтому долго.

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

Получилась визуальная ерунда, что замечательно. Будем копать. Для начала создадим среду для тестирования, то есть нужно создать запись в журнале, вызвать сервис, чтобы он вернул эту запись, а потом убрать за собой.

Начнем с создания своего объекта для журнала. В SM54 открываем кластер ракурсов APPL_LOG и создаем объект ZTEST, подобъект ZTEST. Дальше заполняем тестовый контейнер с данными. Это в транзакци SECATT в части Test Data.

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

Вот сухой остаток, что получается, после исправления кучки кода и удаления лишних методов.

Какие особенности мне встретились на пути.

Если мы удаляем метод в основном классе, где реализована логика проверок, то надо удалять методы в локальном Unit-Test классе (и определение, и реализацию).

При запуске теста система автоматически запускает вначале служебный метод SETUP, затем метод теста, затем TEARDOWN. Эти служебные методы нужны для подготовки (SETUP) данных и уборки за собой (TEARDOWN). Это позволяет проводить тестирование на чистых данных и не засорять систему. Так как мы работаем в данном сервисе с логами, то тут появляются сложности. Например, у нас каждый раз новый LOGNUMBER, так как система живая. За сутки пока я тестировал сервис у меня набежало 600 тысяч различных сообщений. Мне пришлось принудительно вводить фильтр в код, чтобы работать только со своими записями. Соответственно, чтобы не нагружать систему, я вынес логику создания и удаления записей в журнале в общеклассовые методы: CLASS_SETUP и CLASS_TEARDOWN. То есть, у меня при старте теста только один раз создаются две записи из контейнера тестовых данных, по ним прогоняются все тесты, а потом записи удаляются. Эти методы статические.

Ввиду какой-то особенности работы системы журналирования SAP через функциональные модулю группы SBAL запись в базу не всегда производилась оперативно, поэтому на момент срабатывания CLASS_TEARDOWN в журнале еще не было записей, система не могла их удалить. Если проходить в отладчике, то все срабатывало. COMMIT не помог. Видимо дело во внутренних буферах, на которые я пока не стал тратить время и поставил глупую заглушку – подождать 5 секунд. Все сразу заработало.

Чтобы запустить тест на выполнение нужно в SE80 выбрать базовый класс и по правой клавише мыши Execute->Unit Tests.

Если там же запустить Unit Tests With Coverage, то получим картинку, где система подскажет, какие куски кода не покрыты тестами.

С помощью транзакции ATC и SCI можно организовать автоматизированное выполнение тестов до переноса в систему качества, например. Пока тесты не прошли перенос не разрешается.

Вот так это будет выглядеть.

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

Исходники можно взять тут.
SPOOL_20530
SPOOL_20531

Вы должны быть авторизованы, чтобы оставить комментарий.