Как записать модульные тесты в плоскости C?

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

Но как Вы могли сделать модульные тесты на процедурном языке? Или это требует для программирования OO в C?

20
задан Peter Mortensen 26 February 2010 в 19:50
поделиться

6 ответов

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

Также возможно более сложное тестирование, такое как использование имитаторов или заглушек, но это не так просто, как в более динамических языках или даже просто в объектно-ориентированных языках, таких как C ++. Один из способов приблизиться к этому - использовать #defines. Одним из примеров этого является статья Модульное тестирование приложений OpenGL , в которой показано, как имитировать вызовы OpenGL. Это позволяет вам проверить правильность последовательности вызовов OpenGL.

Другой вариант - воспользоваться слабыми символами. Например, все функции API MPI являются слабыми символами, поэтому, если вы определяете тот же символ в своем собственном приложении, ваша реализация переопределяет слабую реализацию в библиотеке. Если бы символы в библиотеке не были слабыми, вы бы получили повторяющиеся ошибки символов во время компоновки. Затем вы можете реализовать то, что фактически является имитацией всего API MPI C, что позволяет гарантировать, что вызовы согласованы должным образом и что нет никаких дополнительных вызовов, которые могут вызвать взаимоблокировки.Также можно загрузить слабые символы библиотеки с помощью dlopen () и dlsym () и передать вызов при необходимости. MPI на самом деле предоставляет символы PMPI, которые являются сильными, поэтому нет необходимости использовать dlopen () и другие.

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

20
ответ дан 29 November 2019 в 23:14
поделиться

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

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

Я бы дал вам несколько примеров кода, но я очень устарел с C. Я уверен, что есть некоторые фреймворки, которые бы тоже сделали это немного проще.

13
ответ дан 29 November 2019 в 23:14
поделиться

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

int main(int argc, char **argv){

   // call some function
   int x = foo();

   assert(x > 1);

   // and so on....

}

Надеюсь, это поможет, С уважением, Том.

3
ответ дан 29 November 2019 в 23:14
поделиться

В JavaScript нет такого события браузера, и даже если оно было, вы не можете доверять браузеру пользователя, чтобы обеспечить вам безопасность.

Для создания уникального URL-адреса для каждой загрузки лучше использовать GUID. Тогда можно, например,

  • разрешить использование URL-адреса только в течение определенного периода времени
  • разрешить передачу только с определенного IP-адреса, связанного с уникальным URL-адресом
  • , чтобы ваш серверный код мог обнаружить, когда содержимое для уникального URL-адреса было полностью передано, а затем аннулировать URL-адрес.

Позвольте мне уточнить последнюю пулю. Скажем, вы используете Java - вы будете in.read (буфер) и out.write (буфер) в цикле до EOF. Если клиент отключится, вы получите IOException во время out.write () и сможете сообщить об успешной загрузке из прерванного. На других платформах, я уверен, есть способы сказать, было ли соединение потеряно или нет.

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

-121--2151596-

Используйте опцию -verbose: gc JVM, чтобы легко проверить, вызвано ли замедление трэшем GC.

-121--4716171-

Я использую утверждение. Но на самом деле это не рамки.

1
ответ дан 29 November 2019 в 23:14
поделиться

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

Если вы в отчаянии, и вам придется впасть в отчаяние, я скомбинировал небольшой препроцессор C и фреймворк на основе gmake. Он начинался как игрушка и так и не вырос, но я использовал для разработки и тестирования пары проектов среднего размера (более 10 000 строк).

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

Это также пример того, почему интенсивное использование препроцессора сложно безопасно.

4
ответ дан 29 November 2019 в 23:14
поделиться

С C это должно идти дальше, чем просто внедрение фреймворка поверх существующего кода.

Одна вещь, которую я всегда делал, это создание модуля тестирования (с main), из которого вы можете запускать небольшие тесты для проверки вашего кода. Это позволяет вам делать очень маленькие приращения между циклами кода и тестирования.

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

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

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

.
1
ответ дан 29 November 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: