Всё, что вам нужно знать о форматах отчётов в тестировании ПО

Каждый раз, когда я встречаюсь с проектом, в котором без причины изобрели свой новый формат отчётов мне хочется сделать что-то ещё для популяризации существующих форматов. За последнее время таких случаев было несколько. В первый раз я добавил поддержку подсветки синтаксиса TAP в библиотеку highlight.js, потом добавил поддержку синтаксиса формата SubUnit. Ну и в последний раз после встречи с одним из таких проектов я собрал воедино всю информацию по этим форматам в одном месте и получилась небольшая книжка. Таким образом, этот текст — мой крестовый поход против разножопицы с тестовыми результатами в разработке ПО :)

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

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

Зачем вообще нужны отчёты?

В каких случаях вам может потребоваться хранение отчёта о выполненном тестировании:

  • оценка текущего качества проекта на основе покрытия тестами и получение ответов на вопросы: Закончено ли тестирование? Готов ли продукт к релизу? С какой скоростью разработка сходится к релизу?
  • получение статистики о частоте воспроизведения дефекта;
  • оценка эффективности тестов (насколько полезен тест и находит ли дефекты?);
  • обмен данными между командами, если роли в команде разделены (например, разработчики и тестировщики);
  • стабильность тестов и функциональности в продукте (PASS/FAIL rate) с течением времени.

К тому же данные о тестировании можно использовать для постоянного улучшения самого тестирования.

Обзор существующих форматов

Зачастую разработчики даже не задумываются о том, в каком формате тесты сохраняют отчёты. Если это простые тесты, то достаточно вывода в формате PASS/FAIL. Если это функциональные тесты, то такой информации становится недостаточно, потому что нужно сохранять логи, тайминги и другие данные о выполнении теста. Хорошо, если используется тестовый фреймворк, в котором есть поддержка одного из распространённых форматов. А если нет, то в мире появляется ещё один формат для хранения результатов тестирования.

Благодаря изобретательности инженеров в мире разработки ПО существует множество форматов отчётов. Но одни получили большее распространение, чем другие. Все форматы можно поделить на две категории:

  1. закрытые форматы, изобретённые компаниями для своих коммерческих продуктов;
  2. открытые форматы.

Это может показаться удивительным, но открытость поспособствовала распространению форматов из второй категории. Как это получилось выяснить? Я проанализировал полсотни наиболее распространённых открытых проектов и получил следующие данные: 24 проекта хранят тестовые результаты и эти данные доступны публично, половина проектов если и использует какой-то формат для тестовых отчётов, то это один из трёх форматов: TAP, JUnit и SubUnit.

ФорматКол-во проектов
TAP19
JUnit8
SubUnit3
Собственный29

А что с популярностью этих же форматов в коммерческих проектах? Результаты опроса об использовании форматов тестовых данных в разработке коммерческого ПО (36 голосов):

  • TAP — 3%;
  • JUnit — 58%;
  • SubUnit — 3%;
  • Другой формат — 36%.

Вообще в природе помимо форматов TAP, JUnit, SubUnit существуют и другие форматы, но я их не буду здесь рассматривать и приведу список только в качестве информационной справки: DejaGnu, Selenium, TAPOUT, Microsoft Test, HP QuickTest Professional, IBM Rational Functional Tester, Gallio Test Report, Parasoft C/C++test, Ranorex, TestRail.

Теперь подробнее о каждом из трёх форматов.

Test Anything Protocol (TAP)

Самый старый формат для представления результатов тестирования. По сути lingua franca для тестирования. Формат был создан для тестирования первой версии интерпретатора Perl в 1987 году. Позднее Tim Bunce и Andreas König написали модуль Test::Harness, что позволило использовать формат для тестирования модулей Perl. Сейчас формат имеет поддержку не только в Perl, но и в других языках программирования и фреймворках для тестирования. В 2008 году на конференции YAPC::Europe была предпринята попытка разработать IETF стандарт для TAP, но эта попытка не увенчалась успехом. Но есть текстовое описание формата на сайте testanything.org, а модули TAP::Spec::Parser и TAP::Parser::Grammar считаются референсной реализацией TAP.

Пример вывода результатов теста в формате TAP:

# Hardware architecture: x86_64
# Timestamp: 2016-06-16 06:23 (GMT+1)
# 
TAP version 13
1..258
ok 1 - zdtm/static/conntracks # SKIP manual run only
ok 2 - zdtm/static/maps03 # SKIP manual run only
ok 3 - zdtm/static/mlock_setuid
ok 4 - zdtm/static/groups
ok 5 - zdtm/static/maps05
ok 6 - zdtm/static/pdeath_sig
ok 7 - zdtm/static/xids00
ok 8 - zdtm/static/proc-self
ok 9 - zdtm/static/file_fown
ok 10 - zdtm/static/eventfs00
ok 11 - zdtm/static/uptime_grow # SKIP manual run only
ok 12 - zdtm/static/signalfd00
ok 13 - zdtm/static/inotify_irmap
ok 14 - zdtm/static/fanotify00
ok 15 - zdtm/static/session00
ok 16 - zdtm/static/rlimits00
ok 17 - zdtm/static/maps04
ok 18 - zdtm/static/pty03
ok 19 - zdtm/static/pty02
...

Пример отчёта с дополнительными полями:

1..1
 not ok 1 Wrong length 
     ---
     wanted: 5
     found: 4
     time: 2011-02-01 00:09:01-07
     extensions: 
         files: 
             1.txt:
                 name: 1.txt 
                 file-type: text/plain 
                 file-size: 43 
                 content: c2FtcGxl ...

SubUnit

SubUnit является потоковым форматом. Изначально был разработан в 2005 году Робертом Коллинсом для юнит-тестирования. Для SubUnit доступны утилиты для анализа результатов (subunit-stats, subunit-ls и т. д.) и библиотеки для Python, C, C++ и Shell. Формат активно используется в тестировании компонентов проекта OpenStack, Linux дистрибутива Ubuntu и Samba. Есть две версии формата: первая версия хранит результаты в текстовом представлении, вторая — в двоичном. Для обоих версий доступна подробная спецификация формата.

Пример вывода результатов теста в формате SubUnit:

 time: 2011-05-23 22:49:38.856075Z
 test: mytest.SampleTestCase.runTest 
 failure: mytest.SampleTestCase.runTest 
 [ 
     Traceback (most recent call last): File "/media/windows/dev/java/qaworkspace/pythonnosetests/src/mytest.py", line
     11, in runTest self.assertEqual(len(s), 4, 'Wrong length') AssertionError: Wrong length 
 ] 
 time: 2011-05-2322:49:38.858163Z

JUnit

xUnit — это собирательное название семейства фреймворков для модульного тестирования, структура и функциональность которых основана на SUnit, предназначавшегося для языка программирования Smalltalk. SUnit, разработанный Кентом Беком в 1998 году, получил широкую популярность и был адаптирован для множества других языков. Названия фреймворков этого семейства образованы аналогично «SUnit», обычно заменяется буква «S» на первую букву (или несколько первых) в названии предполагаемого языка («JUnit» для Java, «NUnit» для программной платформы .NET и т. д.). Несмотря на общие корни, форматы для всех фреймворков основаны на XML, но структура может отличаться (см. xunit-plugin).

Пример вывода результатов теста в формате JUnit:

<testsuites>
  <testsuite time="0.239100933074951"
             failures="10"
             name="access_t"
             tests="14"
             errors="1">
    <testcase name="(init)" time="0.180249929428101" />
    <testcase time="0.00193119049072266" name="1 - inet allow all">
      <failure type="TestFailed"
               message="not ok 1 - inet allow all"><![CDATA[not ok 1 - inet allow all]]></failure>
    </testcase>
    <testcase name="2 - inet allow unix" time="0.00225496292114258">
      <failure type="TestFailed"
               message="not ok 2 - inet allow unix"><![CDATA[not ok 2 - inet allow unix]]></failure>
    </testcase>
    <testcase time="0.00211286544799805" name="3 - inet deny all"></testcase>
    <testcase name="4 - inet deny unix" time="0.00119209289550781">
      <failure type="TestFailed"
               message="not ok 4 - inet deny unix"><![CDATA[not ok 4 - inet deny unix]]></failure>
    </testcase>

Плюсы и минусы разных форматов

Несмотря на то, что все три формата создавались для одной цели — юнит-тестирования, они имеют различия. В таблице ниже проводится сравнение этих форматов.

ПараметрTAPSubUnitJUnit
Человекочитаемый форматДаv1 — да, v2 — нетДа?
Независимость от языка программированияДаДаНет (несмотря на то, что форматы тестовых отчётов всех фреймворков JUnit похожи друг на друга, эти форматы имеют отличия)
Поддерживаемые языки программированияPerl, Python, PHP, Java, C, C++, C#, Lua, Shell, Ruby, Javascript, Pascal, PostgreSQL, Haskell, Lisp, Forth и другиеPython, C/C++, ShellJava, .NET, C/C++, Fortran, Haskell, Perl, PHP, Python, Ruby
Начало использования198820061994?
Возможность группирования тестов по категориям или тегамНет (в состоянии обсуждения)ДаДа
Возможность расширенияДа, есть возможность добавить YAML в отчётНет?Нет?
ДокументацияCпецификация 13-й версииНесколько примеров использованияНет
Описание спецификацииЕсть референсная реализация формата в Perl модуле Test::Harness, также была попытка разработать IETF стандарт для формата TAPОписание обоих версий формата есть в Python Package IndexОфициального описания стандарта не существует, но есть XML схема для JUnit
Поле со временем выполнения тестаДа, в YAMLДаДа
Поддержка расширенных статусов тестовНетНетНет?
Возможность прикрепления файлов к тестовым отчётамДа, файлы закодированные в Base64, можно добавлять в YAMLДа, можно добавлять файлы, закодированные в Base64Да?

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

Инструменты для хранения и анализа результатов в тестировании ПО

Зачастую тестирование встраивают в процесс разработки с помощью инструментов непрерывной интеграции (Jenkins CI, BuildBot, Travis CI, Teamcity и т. д.) и их же используют для анализа результатов. Мой опыт показывает, что отдельные сервисы хранения и анализа результатов с возможностью интеграции с системами CI удобнее, чем плагин в одной из них. Другие опытные тестировщики это подтверждают. Хотя я понимаю, что эти два случая не показательны :)

В таблице перечислены системы для анализа отчётов о тестировании в одном из трёх стандартных форматов.

ИнструментПользователиКомментарий
Subunit2SQLOpenStackФормат: SubUnit. Видео, слайды, Using SubUnit2SQL with the gate
Badger2ГИСФорматы: JUnit. Видео: CodeFest, SQAdays
AllureЯндекс и другиеФорматы: JUnit. Расширение для Jenkins CI.
TapperАмазонФормат: TAP (Test Anything Protocol). Разработка приостановлена.
Jenkins: Test Results Analyzer Plugin?Форматы: JUnit, TAP (Test Anything Protocol). Расширение для Jenkins CI.
testrepository?Форматы: SubUnit.

Полезные ссылки

  1. Список тестовых фреймворков с поддержкой xUnit и TAP
  2. «Because of TAP’s simplicity, it can function as a lingua franca for testing»
  3. Поддержка TAP в языках программирования
  4. История формата Test Anything Protocol
  5. XML vs TAP
  6. История формата xUnit
  7. Обсуждение на StackOverflow спецификации формата JUnit XML
  8. SubUnit vs JUnit
  9. Software Engineering Radio Episode 167: The History of JUnit and the Future of Testing with Kent Beck
  10. Выпуск 19 подкаста «Python Testing» — Python unittest with Robert Collins
  11. What We Learned about Continuous Integration from Analyzing 2+ Million Travis Builds
  12. «Первую версию JUnit в самолете во время перелёта из Цюриха в Атланту в 1997 году»


Список библиотек и инструментов с подсветкой синтаксиса стандартных тестовых форматов:

Похожие статьи:
Я руковожу проектами уже восемь лет, и за это время успел познакомиться с разными командами и заказчиками. О работе с одним...
На нашем YouTube канале появились новые видеоролики.Обзор чехла LifeProof nuud и fre для iPad...
Дисклаймер. Данный опус поможет понять за что «хвататься» при оценке проекта...
Оператор мобильной связи Tele2 сообщил о начале проведения акции в...
Представляем новую статью цикла «Карьера в IT». В этой части...
Яндекс.Метрика