Модульное тестирование кода C [закрыто]

этим летом я работал над встроенной системой, написанной прямо C. Это был существующий проект, который компания, в которой я работаю, взяла на себя. Я привык писать модульные тесты на Java с помощью JUnit, но был в недоумении относительно лучшего способа написания модульных тестов для существующего кода (который нуждался в рефакторинге), а также нового кода, добавленного в систему.

есть ли способ сделать модульное тестирование простым кодом C так же просто, как модульное тестирование Java-кода, например, JUnit? Любое понимание, которое будет применяться конкретно к встроенной разработке (кросс-компиляции на платформе arm-linux), будет высоко оценено.

30 ответов


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

AceUnit

AceUnit (Advanced C и Embedded Unit) выставляет себя в качестве удобной платформы для тестирования C-кода. Он пытается имитировать JUnit 4.x и включает отражение-подобное способности. AceUnit может использоваться в средах ограничения ресурсов, например, для разработки встроенного программного обеспечения, и, что важно, он отлично работает в средах, где вы не можете включить один стандартный файл заголовка и не можете вызвать одну стандартную функцию C из библиотек ANSI / ISO C. Он также имеет порт Windows. Он не использует вилки для ловушки сигналов, хотя авторы выразили заинтересованность в добавлении такой функции. Вижу Домашняя страница AceUnit.

GNU Autounit

почти так же, как Check, включая разветвление для запуска модульных тестов в отдельном адресном пространстве (фактически, первоначальный автор Check заимствовал идею из GNU Autounit). GNU Autounit широко использует GLib, что означает, что для связывания и таких нужны специальные опции, но это может не быть большой проблемой для вас, особенно если вы уже используете GTK или GLib. Вижу Домашняя страница GNU Autounit.

кунит

также использует GLib, но не вилка для защиты адресного пространства модульных тестов.

Кунит

стандартный C, с планами реализации Win32 GUI. В настоящее время не вилка или иным образом защитить адресное пространство модульных тестов. В раннем развитии. Вижу Домашняя страница Кунит.

симпатичный

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

CppUnit

основная платформа модульного тестирования для C++; вы также можете использовать ее для тестирования кода C. Он стабилен, активно развивается и имеет интерфейс GUI. Основные причины не использовать CppUnit для C-во-первых, он довольно большой, а во-вторых, вы должны написать свои тесты на C++, что означает, что вам нужен компилятор C++. Если это не похоже на проблемы, это определенно стоит рассмотреть вместе с другими фреймворками модульного тестирования C++. Увидеть главная страница CppUnit.

embUnit

embUnit (Embedded Unit) - еще одна платформа модульных тестов для встроенных систем. Этот, по-видимому, заменен AceUnit. Домашняя страница встроенного блока.

MinUnit

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

Кунит для мистера Андо

реализация CUnit, которая является довольно новой и, по-видимому, все еще находится в ранней разработке. Вижу Кунит для мистера Андо Домашняя страница.

последний раз этот список обновлялся в марте 2008 года.

другие:

CMocka

CMocka-это тестовая платформа для C с поддержкой макетных объектов. Он прост в использовании и настройке. CMocka официальный сайт.

критерий

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

HWUT

HWUT общий инструмент модульного тестирования с большой поддержкой C. Это может помочь создать Makefiles, генерировать массивные тестовые случаи, закодированные в минимальные "таблицы итераций", прогулка по государственным машинам, генерация c-заглушек и многое другое. Общий подход довольно уникален: вердикты основаны на "хорошем stdout/плохом stdout". Однако функция сравнения является гибкой. Таким образом, для проверки может использоваться любой тип скрипта. Он может быть применен к любому языку, который может производить стандартный вывод. См.HWUT Домашняя страница.

Википедия дает подробный список структур модульного тестирования C в разделе список блок тестирования: C


лично мне нравится Google Test framework.

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

Это то, что люди имеют в виду, когда говорят о "швы". В C код единственный вариант - использовать предварительный процессор или компоновщик для макета ваших зависимостей.

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

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

обратите внимание, что вы фактически включаете файл C, а не файл заголовка. Это дает преимущество доступа ко всем статическим членам данных. Здесь я издеваюсь над своим лесорубом (который может быть в logger.o и дайте пустую реализацию. Это означает, что тестовый файл компилируется и ссылки независимо от остальной части базы кода и выполняется изолированно.

Что касается кросс-компиляции кода, для этого вам нужны хорошие средства на цели. Я сделал это с помощью googletest cross, скомпилированного в Linux на архитектуре PowerPC. Это имеет смысл, потому что там у вас есть полная оболочка и ОС для сбора результатов. Для менее богатых сред (которые я классифицирую как что-либо без полной ОС) вы должны просто создавать и запускать на хосте. Ты все равно должен это сделать. таким образом, вы можете запускать тесты автоматически как часть сборки.

Я считаю, что тестирование кода C++ обычно намного проще из-за того, что код OO в целом гораздо менее связан, чем процедурный (конечно, это зависит от стиля кодирования). Также В C++ вы можете использовать такие трюки, как инъекция зависимостей и переопределение метода, чтобы получить швы в код, который иначе инкапсулируется.

Майкл перья есть отличная книга о тестировании устаревшего кода. Одновременно в главе он описывает методы работы с не-ОО-кодом, которые я настоятельно рекомендую.

редактировать: Я написал блоге о процедурном коде модульного тестирования, с источник доступен на GitHub.

редактировать: есть новая книга выходит из прагматичных программистов это конкретно касается модульного тестирования кода C, который рекомендую.


Minunit - невероятно простая структура модульного тестирования. Я использую его для модульного тестирования кода C для AVR микроконтроллеров.


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

http://cutest.sourceforge.net/

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

  • файл заголовка включен везде, где ты называешь самые милые процедуры
  • один дополнительный 'C' файл скомпилированный / связанный в образ
  • некоторый простой код, добавленный в main to настройка и вызов модульных тестов-I просто есть это главное() функция, которая компилируется, если UNITTEST определяется во время строить.

система должна поддерживать кучу и некоторые функции stdio (которые есть не во всех встроенных системах). Но код достаточно прост, что вы, вероятно, могли бы работать в альтернативах этим требованиям, если ваша платформа не имеет их.

с некоторым разумным использованием extern " C " {} блоков он также поддерживает тестирование C++ просто отлично.


Я говорю почти то же самое, что и ratkok, но если у вас есть встроенный поворот в модульные тесты...

единство - настоятельно рекомендуется основа для модульного тестирования кода.

примеры в книге, которая упоминается в этой теме TDD для встроенного C записываются с использованием Unity (и CppUTest).


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

пример:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}

существует элегантная платформа модульного тестирования для C с поддержкой макетных объектов под названием cmocka. Он требует только стандартной библиотеки C, работает на ряде вычислительных платформ (включая встроенные) и с различными компиляторами.

Он также поддерживает различные форматы вывода сообщений, такие как Subunit, Test Anything Protocol и jUnit XML reports.

cmocka был создан также для работы на встроенных платформах, а также имеет окна поддержка.

простой тест выглядит так:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

на API полностью документированы и несколько примеров являются частью исходного кода.

чтобы начать работу с cmocka, вы должны прочитать статью LWN.net:модульное тестирование с макетом объектов в C

cmocka 1.0 был выпущен в феврале 2015 года.


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

Cmock сканирует файлы заголовков и генерирует фиктивные функции на основе найденных прототипов. Mocks позволит вам протестировать файл C в полной изоляции. Все, что вам нужно сделать, это связать тестовый файл с mocks вместо вашего реального объекта файлы.

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

тесты состоят из типичных функций testA(), testB (), в которых вы строите ожидания, вызываете функции для тестирования и проверки утверждений.

последний шаг-создать бегун для ваших тестов с unity. Cmock привязан к платформе тестирования unity. Unity так же легко узнать, как и любой другой модульный тест.

стоит попробовать и довольно легко понять:

http://sourceforge.net/apps/trac/cmock/wiki

обновление 1

другое рамки я расследую это Cmockery.

http://code.google.com/p/cmockery/

Это чистая платформа C, поддерживающая модульное тестирование и издевательство. Он не имеет зависимости от ruby (в отличие от Cmock) и имеет очень небольшую зависимость от внешних библиотек.

для настройки насмешек требуется немного больше ручной работы, потому что она не генерирует код. Это не представляет большой работы для существующего проекта, так как прототипы не сильно изменятся: как только у вас есть ваши насмешки, вам не нужно будет их менять какое-то время (это мой случай). Extra typing обеспечивает полный контроль над насмешками. Если есть что-то, что вам не нравится, вы просто меняете свой издеваться.

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

плюс он содержит некоторые изящные трюки C, которые я не знал.

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


Как Новичок C, я нашел слайды под названием развитие управляемое испытанием в C очень полезная. В основном, он использует стандарт assert() вместе с && для доставки сообщения без каких-либо внешних зависимостей. Если кто-то привык к полной структуре тестирования стека, это, вероятно, не будет делать :)


здесь Кунит

и Встроенный Блок структура модульного тестирования для встроенной системы C. Его дизайн был скопирован с JUnit и CUnit и многое другое, а затем адаптирован для встроенной системы C. Встроенный блок не требует std c libs. Все объекты выделяются в области строительства.

и Тэсси автоматизирует модульное тестирование встроенного программного обеспечения.


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

есть методы, связанные с инъекцией зависимостей, которые специфичны для C, которые я больше нигде не видел.


мы уже писали чит (размещенного на GitHub) для удобства использования и переносимости.

Она не имеет зависимостей и не требует установки или настройки. Требуется только файл заголовка и тестовый случай.

#include <cheat.h>

CHEAT_TEST(mathematics_still_work,
    cheat_assert(2 + 2 == 4);
    cheat_assert_not(2 + 2 == 5);
)

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

$ gcc -I . tests.c
$ ./a.out
..
---
2 successful of 2 run
SUCCESS

Он имеет красивые цвета тоже.


Я не использую фреймворк, я просто использую поддержку цели autotools "check". Реализуйте "main" и используйте assert(s).

мой тестовый файл Makefile.am (s) выглядит так:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp

CppUTest - настоятельно рекомендуется основа для модульного тестирования кода.

примеры в книге, которая упоминается в этой теме TDD для встроенного C записываются с помощью CppUTest.


Я использую CxxTest для встроенной среды c / C++ (в первую очередь C++).

Я предпочитаю CxxTest, потому что у него есть скрипт perl/python для создания тестового бегуна. После небольшого наклона, чтобы получить его настройку (еще меньше, так как вам не нужно писать тестовый бегун), он довольно прост в использовании (включает образцы и полезную документацию). Большая часть работы заключалась в настройке "аппаратного" доступа к коду, чтобы я мог эффективно тестировать модуль / модуль. После этого легко добавить новое модульные тесты.

Как упоминалось ранее, это платформа модульного тестирования C / c++. Поэтому вам понадобится компилятор C++.

CxxTest Руководство Пользователя CxxTest Вики


кроме моей очевидной предвзятости

http://code.google.com/p/seatest/

- Это хороший простой способ для модульного тестирования кода. имитирует в xUnit


после прочтения Minunit я подумал, что лучший способ-основать тест в макро assert, который я использую как оборонительную технику программы. Поэтому я использовал ту же идею Minunit, смешанную со стандартным assert. Вы можете увидеть мою структуру (хорошее имя может быть NoMinunit) в блог k0ga



Google имеет отличную систему тестирования. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

и да, насколько я вижу, он будет работать с простым C, т. е. не требует функций c++ (может потребоваться компилятор C++, не уверен).


Cmockery - это недавно запущенный проект, который состоит из очень простой в использовании библиотеки C для написания модульных тестов.


во-первых, посмотрите сюда:http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

У моей компании есть библиотека C, которую используют наши клиенты. Мы используем cxxtest (библиотека модульных тестов C++) для тестирования кода. CppUnit также будет работать. Если вы застряли в C, я бы рекомендовал RCUNIT (но CUnit тоже хорош).


Если вы знакомы с JUnit, то я рекомендую CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

Это предполагает, что у вас есть компилятор C++ для выполнения модульных тестов. если нет, то я должен согласиться с Адам Розенфельд, что проверить то, что вы хотите.


Я RCUNIT сделать некоторое модульное тестирование для врезанного кода на ПК перед испытывать на цели. Хорошая абстракция аппаратного интерфейса важна, иначе endianness и сопоставленные с памятью регистры убьют вас.


попробовать lcut! - http://code.google.com/p/lcut


один из методов заключается в разработке кода модульного теста с помощью C++ xUnit framework (и компилятора C++), сохраняя при этом источник для целевой системы в качестве модулей C.

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


LibU (http://koanlogic.com/libu) имеет модуль модульного теста, который позволяет явные зависимости набора тестов / случая, изоляции теста, параллельного выполнения и настраиваемого форматирования отчета (форматы по умолчанию xml и txt).

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


Я удивлен, что никто не упомянул резак (http://cutter.sourceforge.net/) Вы можете протестировать C и C++, он легко интегрируется с autotools и имеет действительно хороший учебник.


проверка здравомыслия API - тестовая платформа для библиотек C / C++:

автоматический генератор базовых модульных тестов для общей библиотеки C и C++. Он способен генерировать разумные (в большинстве, но, к сожалению, не во всех случаях) входные данные для параметров и составлять простые ("здравомыслие" или "мелкое"качество) тестовые случаи для каждой функции в API посредством анализа объявлений в заголовочных файлах.

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

примеры:


Если вы нацелены на платформы Win32 или режим ядра NT, вы должны взглянуть на cfix.


Если вы все еще охотитесь за тестовыми фреймворками,CUnitWin32 является одним для платформы Win32/NT.

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