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

This is a draft of a small book about reporting formats in software testing

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

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

В наше время ни один серьёзный программный проект не обходится без тестирования. Тестирование может быть для отдельных компонентов (юнит-тестирование), без 100% покрытия кода или нерегулярным, но оно должно быть. Регулярное тестирование даёт представление о текущем качестве проекта, помогает на ранней стадии разработки найти дефекты и узнать о появлении регрессий. Зачастую тестирование встраивают в процесс разработки с помощью инструментов непрерывной интеграции: Jenkins CI, BuildBot, Travis CI и т.д. И для хранения результатов используют эти же инструменты, хотя они для этого не приспособлены.

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

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

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

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

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

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

  • форматы, изобретённые компаниями для использования в своих коммерческих продуктах, зачастую спецификация таких форматов закрыта
  • форматы, изобретённые в открытых проектах и имеющие открытую спецификацию

Это может показаться удивительным, но открытость поспособствовала распространению форматов из второй категории. Как это получилось выяснить? Я проанализировал полсотни наиболее распространённых открытых проектов и получил следующие данные: 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)

Самый старый формат для представления результатов тестирования. Использовался для юнит-тестирования первой версии интерпретатора Perl в 1987 году. Модуль Test::Harness был написан Tim Bunce и Andreas König, чтобы позволить авторам модулей для Perl получить все преимущества TAP. Позднее получил распространение для других языков программирования и сейчас существует огромное количество фреймворков для тестирования с поддержкой TAP. Формат крайне простой.

Его формальная спецификация существует в модулях TAP::Spec::Parser и TAP::Parser::Grammar. Поведение модуля Test::Harness является де-факто стандартом реализации поддержки TAP. Хотя существует описание формата на сайте testanything.org. В 2008 году на конференции YAPC::Europe была предпринята попытка разработать IETF стандарт для 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 ...

tappy:

Some projects have mixed programming environments with many programming languages and tools. Because of TAP's simplicity, it can function as a lingua franca for testing. When every testing tool can create TAP, a team can get a holistic view of their system. Python did not have a bridge from unittest to TAP so it was difficult to integrate a Python test suite into a larger TAP ecosystem.

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 это семейство фреймворков для юнит-тестирования под разные языки программирования. Smalltalk был первым языком программирования, для которого Kent Beck в 1994 году разработал тестовый фреймворк SUnit. Все фреймворки xUnit имеют похожий формат вывода тестовых результатов - XML.

Пример вывода результатов теста в формате 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 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 Да?

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

Инструменты для обработки результатов в тестировании

Récidive - cервис для хранения и анализа тестовых результатов. Несмотря на свою кажущуюся простоту обладает следующей функциональностью:

  • лёгкая установка - один запускаемый файл
  • простой UI с наглядным представлением результатов тестирования
  • удобный анализ результатов с графиками
  • удобный поиск, как на GitHub
  • независимость от языка программирования
  • возможность децентрализации тестирования (Crowdsourced testing)
  • код доступен под лицензией BSD

По словам опытных инженеров сервис с тестовыми результатми с возможностью интеграции с разными CI удобнее, чем плагин в одном из них.

Похожие инструменты:

Инструмент Пользователи Комментарий
Subunit2SQL OpenStack Формат: SubUnit. Видео, слайды, Using SubUnit2SQL with the gate
Badger 2ГИС Форматы: JUnit. Видео: CodeFest, SQAdays
Allure Яндекс Форматы: JUnit
Tapper Амазон Формат: TAP (Test Anything Protocol). Разработка приостановлена.
Jenkins: Test Results Analyzer Plugin - Форматы: JUnit, TAP (Test Anything Protocol).
testrepository - Форматы: SubUnit.
Récidive - Форматы: SubUnit, JUnit, TAP (Test Anything Protocol). Слайды

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

Подсветка синтаксиса стандартных тестовых форматов

  • highlight.js: SubUnit, TAP и JUnit (как XML)
  • VIM: SubUnit и JUnit (как XML)
  • Pygments (Python syntax highlighter): TAP

P.S. эта книжка - мой крестовый поход против разножопицы с тестовыми результатами в тестировании ПО :)

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