Модульный тест, что класс не копируемый, и другие свойства времени компиляции - PullRequest
16 голосов
/ 03 марта 2009

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

struct Foo {
    int value_;
    Foo(int value) : value_(value) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};

int main()
{
    Foo f(12);
    assert(f.value_ == 12);
    assert(IS_COMPILER_ERROR(Foo copy(f);));
} // Would like this to compile and run fine.

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

N.B .: Я взял не копируемый только для иллюстрации своей точки зрения, поэтому мне не интересны ответы об использовании boost :: noncopyable и тому подобное.

Ответы [ 5 ]

12 голосов
/ 04 марта 2009

Вы можете сделать это, используя make. Каждый тест будет фрагментом кода. Вот рабочий пример с двумя тестами для VC ++. (Я использовал 2 командных файла для прохождения теста и провала теста). Я использую GNU make здесь.

Makefile:


FAILTEST = .\failtest.bat
PASSTEST = .\passtest.bat

tests: must_fail_but_passes \
    must_pass_but_fails

must_fail_but_passes:
    @$(FAILTEST) $@.cpp

must_pass_but_fails:
    @$(PASSTEST) $@.cpp

must_pass_but_fails.cpp

<code>
struct Foo {
    int value_;
    Foo(void) : value_(0) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};</p>

<p>int main()
{
    Foo f(12);
    return 0;
}

must_fail_but_passes.cpp

<code>
struct Foo {
    int value_;
    Foo(int value) : value_(value) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};</p>

<p>int main()
{
    Foo f(12);
    return 0;
}

passtest.bat

<code>
@echo off
cl /nologo %1 >NUL
if %errorlevel% == 0 goto pass
@echo %1 FAILED
:pass

failtest.bat

<code>
@echo off
cl /nologo %1 >NUL
if not %errorlevel% == 0 goto pass
@echo %1 FAILED
:pass

Обратите внимание, что cl.exe (то есть компилятор Visual Studio) должен быть на вашем пути, чтобы он "просто работал"

Веселись!

P.S. Я сомневаюсь, что это сделало бы меня знаменитым, хотя: -)

6 голосов
/ 18 февраля 2010

Кстати, единственная система сборки, которую я знаю, которая позволяет проводить такой тест из коробки - Boost.Build:*1001

Проверьте здесь "http://beta.boost.org/boost-build2/doc/html/bbv2/builtins/testing.html

Например,

# in your Jamfile
compile-fail crappy.cpp ;

.

int main()
{
  my crappy cpp file
}

Для большего количества примеров просто grep -R compile-fail в каталоге BOOST_TOP_DIR\libs.

1 голос
/ 03 марта 2009

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

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

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

Так что, по крайней мере, вы можете знать, что вы не одиноки. Теперь, если вы написали успешный тестовый фреймворк для такого рода вещей, вы, вероятно, станете знаменитым:)

Редактировать: Возможно, вы также можете использовать #define, который либо пытается, либо не компилирует некомпилируемый код, например,

#ifdef _COMPILETEST
#define TRY_COMPILE(...) (__VA_ARG__)
#else
#define TRY_COMPILE(...)
#end

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

0 голосов
/ 21 мая 2013

Эта статья, которую я написал некоторое время назад, может представлять интерес http://petebarber.blogspot.co.uk/2012/04/unit-testing-when-success-case-is.html

0 голосов
/ 04 марта 2009

boost.type_traits , кажется, имеет то, что вы ищете.

...