Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Everything You Need to Know About Software Test Formats

Статья опубликована

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

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

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

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

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

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

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

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

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

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

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

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

Формат Количество проектов
TAP 19
JUnit 8
SubUnit 3
Собственный 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 для тестирования [2]. Формат был создан для тестирования первой версии интерпретатора Perl в 1987 году [4]. Позднее Tim Bunce и Andreas König написали модуль Test::Harness, что позволило использовать формат для тестирования модулей Perl. Сейчас формат имеет поддержку не только в Perl, но и в других языках программирования [3] и фреймворках для тестирования [1]. В 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>

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

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

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

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

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

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

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

Инструмент Пользователи Комментарий
Subunit2SQL OpenStack Формат: SubUnit. Видео, слайды, Using SubUnit2SQL with the gate
Badger 2ГИС Форматы: 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 году"

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment