Юнит-тест: проверка некомпилируемости
От: tarkil Россия http://5209.copi.ru/
Дата: 14.02.05 09:04
Оценка:
Приветствую!

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

Но при разработке библиотеки есть ещё одно важное требование: чтобы некоторые конструкции не компилировались или выдавали предупреждение компиляции (защита от неправильного использования). Есть идеи как это проверить?

Язык C++, но приветствуются любые соображения.

18.02.05 12:19: Перенесено из 'Управление проектами'
--
wbr, Peter Taran
Re: Юнит-тест: проверка некомпилируемости
От: bkat  
Дата: 14.02.05 09:17
Оценка: 4 (1)
Здравствуйте, tarkil, Вы писали:

T>Приветствую!


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


T>Но при разработке библиотеки есть ещё одно важное требование: чтобы некоторые конструкции не компилировались или выдавали предупреждение компиляции (защита от неправильного использования). Есть идеи как это проверить?


T>Язык C++, но приветствуются любые соображения.


Первое что приходит в голову — это следующее.
Unit test может генерить тестовый файл (cpp?) и запускать компиляцию файла.
Затем можно проверять, что компиляция прошла с ожидаемой тобой ошибкой компиляции.

Тестовые файлы, которые не должны компилироваться,
можно вообще подготовить заранее и расматривать их
просто как входные данные для твоих тестов.
Re[2]: Юнит-тест: проверка некомпилируемости
От: tarkil Россия http://5209.copi.ru/
Дата: 14.02.05 10:13
Оценка:
Здравствуйте, bkat, Вы писали:

B>Первое что приходит в голову — это следующее.

B>Unit test может генерить тестовый файл (cpp?) и запускать компиляцию файла.
B>Затем можно проверять, что компиляция прошла с ожидаемой тобой ошибкой компиляции.

Генерить по cpp на каждый отдельный тест, запускать на компиляцию, парсить вывод компилятора и смотреть, были ли там ошибки/предупреждения? А что, вполне рабочая схема нарисоваться может. Тем более, что парсить там можно простыми рег. выражениями.

B>Тестовые файлы, которые не должны компилироваться,

B>можно вообще подготовить заранее и расматривать их
B>просто как входные данные для твоих тестов.

Ну да, можно. Только много их получится очень, лучше генерить автоматически. Написать

TEST_COMPILE_ERROR(
  CVerySmartPtr p = &l;
)

TEST_COMPILE_WARNING(
  CVerySmartPtr p = new Obj;
)

И по каждому из макросов сгеренить cpp, закомпилировать, отловить...
--
wbr, Peter Taran
Re[3]: Юнит-тест: проверка некомпилируемости
От: bkat  
Дата: 14.02.05 10:17
Оценка:
Здравствуйте, tarkil, Вы писали:

T>Здравствуйте, bkat, Вы писали:


B>>Первое что приходит в голову — это следующее.

B>>Unit test может генерить тестовый файл (cpp?) и запускать компиляцию файла.
B>>Затем можно проверять, что компиляция прошла с ожидаемой тобой ошибкой компиляции.

T>Генерить по cpp на каждый отдельный тест, запускать на компиляцию, парсить вывод компилятора и смотреть, были ли там ошибки/предупреждения? А что, вполне рабочая схема нарисоваться может. Тем более, что парсить там можно простыми рег. выражениями.


Ага, именно это я и имел ввиду.

B>>Тестовые файлы, которые не должны компилироваться,

B>>можно вообще подготовить заранее и расматривать их
B>>просто как входные данные для твоих тестов.

T>Ну да, можно. Только много их получится очень, лучше генерить автоматически. Написать


Заранее подготовленные файлы удобны тем,
что тесты можно готовить не занимаясь программированием тестов.
Новый набор тестов можно подготовить без перекомпилирования юнит тестов.
Ну тут тебе виднее, как оно удобнее.
Re[4]: Юнит-тест: проверка некомпилируемости
От: tarkil Россия http://5209.copi.ru/
Дата: 14.02.05 10:28
Оценка: +1
Здравствуйте, bkat, Вы писали:

B>Заранее подготовленные файлы удобны тем,

B>что тесты можно готовить не занимаясь программированием тестов.
B>Новый набор тестов можно подготовить без перекомпилирования юнит тестов.
B>Ну тут тебе виднее, как оно удобнее.

Так перекомпилировать их так или иначе придётся — там же и проверки на результат, которые только исполнением кода можно сделать. Не, пусть одна схема будет. Проще.

Ещё милая фенька — в post-build step тестового проекта писать запуск на выполнение и выдавать ошибки юнит-теста в стиле компилятора. Тогда прогон теста является по сути компиляцией Да и на строчку можно спозиционироваться сразу.
--
wbr, Peter Taran
Re: Юнит-тест: проверка некомпилируемости
От: Alny Украина  
Дата: 15.02.05 09:04
Оценка:
Здравствуйте, tarkil, Вы писали:

T>Но при разработке библиотеки есть ещё одно важное требование: чтобы некоторые конструкции не компилировались или выдавали предупреждение компиляции (защита от неправильного использования). Есть идеи как это проверить?


Настоятельно рекомендую посмотреть как это тестирование реализовано в Boost::Test. Вкратце — идея построена на том, что код формируется в зависимости от define-ов


#ifdef TEST1
vector<int> tst1 //компилиться
#endif

#ifdef TEST2
vector<int, int, int, int, int> tst1 //Не должно компилиться
#endif
Re[2]: Юнит-тест: проверка некомпилируемости
От: tarkil Россия http://5209.copi.ru/
Дата: 15.02.05 11:11
Оценка: +1
Здравствуйте, Alny, Вы писали:

A>Настоятельно рекомендую посмотреть как это тестирование реализовано в Boost::Test. Вкратце — идея построена на том, что код формируется в зависимости от define-ов


A>
A>#ifdef TEST1
A>vector<int> tst1 //компилиться
A>#endif

A>#ifdef TEST2
A>vector<int, int, int, int, int> tst1 //Не должно компилиться
A>#endif
A>


И как этим пользоваться? Задача стоит такая: запустить некий проект на компиляцию или исполнение и чтоб он выдал на stdout все найденные ошибки. Ручное включение/выключение макросов не канает, всё должно быть автоматическим.
--
wbr, Peter Taran
Re[3]: Юнит-тест: проверка некомпилируемости
От: Alny Украина  
Дата: 15.02.05 16:14
Оценка:
Здравствуйте, tarkil, Вы писали:

A>>
A>>#ifdef TEST1
A>>vector<int> tst1 //компилиться
A>>#endif

A>>#ifdef TEST2
A>>vector<int, int, int, int, int> tst1 //Не должно компилиться
A>>#endif
A>>


T>И как этим пользоваться? Задача стоит такая: запустить некий проект на компиляцию или исполнение и чтоб он выдал на stdout все найденные ошибки. Ручное включение/выключение макросов не канает, всё должно быть автоматическим.


А кто говорит про ручное включение — выключение? Если используется Visual C++ — то предлагаю следующий вариант — создается солюшн, в который включается столько проектов, сколько define-ов в тестируемом коде. Этот тестируемый код строится таким образом, что любой из установленых define-ов приводит к ошибке (смотри предложеный выше вариант с TEST2).
В каждом из проектов определяем по одному define-у TEST1, TEST2 ... TESTN (Configuration->C/C++->Preprocessor->Preprocessor Difinitions).
При тестировании открываем солюшн, делаем Build->Build Solutuion, ждем, и наблюдаем заветную надпись

Build: 0 succeeded, N failed, 0 skipped
... << RSDN@Home 1.1.4 beta 4 rev. 302>>
Re[4]: Юнит-тест: проверка некомпилируемости
От: bkat  
Дата: 15.02.05 16:41
Оценка:
Это в целом то же самое, что я предлагал.
Только тесты немного иначе организованы.
Те же заранее приготовленные файлы, которые запускаем
на компиляцию и проверяем, что успех/неуспех компиляции именно тот,
какой ожидается.
Впрочем что-то принципиально иное видимо сложно предложить.
Re[4]: Юнит-тест: проверка некомпилируемости
От: tarkil Россия http://5209.copi.ru/
Дата: 16.02.05 04:34
Оценка:
Здравствуйте, Alny, Вы писали:

A>А кто говорит про ручное включение — выключение? Если используется Visual C++ — то предлагаю следующий вариант — создается солюшн, в который включается столько проектов, сколько define-ов в тестируемом коде. Этот тестируемый код строится таким образом, что любой из установленых define-ов приводит к ошибке (смотри предложеный выше вариант с TEST2).

A>В каждом из проектов определяем по одному define-у TEST1, TEST2 ... TESTN (Configuration->C/C++->Preprocessor->Preprocessor Difinitions).
A>При тестировании открываем солюшн, делаем Build->Build Solutuion, ждем, и наблюдаем заветную надпись

Ну... Я запомню идею. Но смущают две вещи.

1. Оверхед при компиляции будет просто дикий — объём промежуточных файлов превысит сотню мегабайт, если проверок всего-то будет десятка два-три.

2. Сложно создавать новые проверки. Кроме того, что напиши саму проверку, так ещё и проект под неё сделай (или отдельную конфигурацию в существующем проекте... впрочем фичи build all configurations, кажется, нету).

Я всё ж попробую с автогенерацией кода и ручным запуском компилятора что-нибудь нарисовать.
--
wbr, Peter Taran
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.