代码之家  ›  专栏  ›  技术社区  ›  Luc Touraille

单元测试类是否不可复制,以及其他编译时属性

  •  16
  • Luc Touraille  · 技术社区  · 17 年前

    有没有一种方法可以测试编译时错误,但不实际生成错误?例如,如果我创建了一个不可复制的类,我想测试一个事实,即尝试复制它将生成一个编译器错误,但我仍然想执行其他运行时测试。

    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.
    

    我想这不可能这么简单,但是有没有一种惯用的方法来做到这一点,或者我应该推出自己的解决方案(可能使用脚本编译单独的测试文件并测试结果?)?

    注:我选择不可复制只是为了说明我的观点,所以我对使用boost::noncopyable之类的答案不感兴趣。

    5 回复  |  直到 8 年前
        1
  •  12
  •   Dushara    17 年前

    你可以用make来做。每个测试都是一个代码片段。下面是一个VC++的2个测试的工作示例。(我使用了两个批处理文件进行通过测试和失败测试)。我在这里使用GNU make。

    生成文件:

    
    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
    
    

    必须通过但失败。cpp

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

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

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

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

    通过测试

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

    失败测试

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

    请注意,cl.exe(即Visual Studio编译器)必须位于您的路径中,才能“正常工作”

    另外,我怀疑这会让我出名:——)

        2
  •  6
  •   Alexander Poluektov    16 年前

    顺便说一句,我所知道的唯一允许这种开箱即用测试的构建系统是Boost。构建:

    检查这里“ 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 目录

        3
  •  1
  •   Robert Gould    17 年前

    不幸的是,没有一种简单的方法可以按照您希望的方式测试编译错误,我以前也希望这样做。

    无论如何,如果您的测试足够小,您可以编写简短的不可编译代码,如您的示例,并使用脚本验证生成的错误是否正确(同样,您刚刚说过)。

    这类事情的一个例子是Unix的配置脚本,在我见过的多个脚本中,他们试图编译一些小示例来验证编译器的版本/功能,以正确配置makefile。

    所以至少你可以知道你并不孤单。现在,如果您为这类事情编写了一个成功的测试框架,您可能会出名:)

    编辑: 您也可以使用#define来尝试或不编译不可编译的代码,如下所示:

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

    请注意,这是我刚刚想到的,这种模式可能有很多问题,但它可能会成为一些更好想法的种子。