【问题标题】:How do I run a single test with UnitTest++?如何使用 UnitTest++ 运行单个测试?
【发布时间】:2011-04-02 13:01:23
【问题描述】:

如何使用 UnitTest++ 运行单个测试?

我正在按原样运行 UnitTest++。我的main 函数看起来像:

int main()
{
   printf("diamond test v0.1 %s\n\n",TIMESTAMP);
   diamond::startup();
   UnitTest::RunAllTests();
   diamond::shutdown();
   printf("press any key to continue...");
   getc(stdin);
}

为了调试,我想写类似UnitTest::RunSingleTests("MyNewUnitTest"); 而不是UnitTest::RunAllTests();。 UnitTest++有没有提供这样的功能,如果有,语法是什么?

【问题讨论】:

  • 您需要告诉我们更多关于您的环境、您尝试过和失败的事情等。
  • 那么你已经知道如何运行两个测试了吗?
  • 我正在按原样运行 UnitTest++。我的主函数看起来像: int main() { printf("diamond test v0.1 %s\n\n",TIMESTAMP);钻石::启动(); UnitTest::RunAllTests();钻石::关机(); printf("按任意键继续...");获取(标准输入);为了调试我想写 UnitTest::RunSingleTests("MyNewUnitTest");而不是 UnitTest::RunAllTests(); .我想知道是否有这种类型的函数,如果有,语法是什么样的。
  • unittest-cpp.sourceforge.net/UnitTest++.html 通读一遍,或者你试过这个但失败了!!!!
  • hm 格式损坏

标签: c++ unittest++


【解决方案1】:

尝试将此作为您的 main() 用于 unittest(我实际上将其放在一个文件中并将其添加到 unittest 库中,以便在链接到库时可执行文件自动使用此 main()。非常方便。)

int main( int argc, char** argv )
{
  if( argc > 1 )
  {
      //if first arg is "suite", we search for suite names instead of test names
    const bool bSuite = strcmp( "suite", argv[ 1 ] ) == 0;

      //walk list of all tests, add those with a name that
      //matches one of the arguments  to a new TestList
    const TestList& allTests( Test::GetTestList() );
    TestList selectedTests;
    Test* p = allTests.GetHead();
    while( p )
    {
      for( int i = 1 ; i < argc ; ++i )
        if( strcmp( bSuite ? p->m_details.suiteName
                           : p->m_details.testName, argv[ i ] ) == 0 )
          selectedTests.Add( p );
      p = p->next;
    }

      //run selected test(s) only
    TestReporterStdout reporter;
    TestRunner runner( reporter );
    return runner.RunTestsIf( selectedTests, 0, True(), 0 );
  }
  else
  {
    return RunAllTests();
  }
}

使用参数调用以运行单个测试:

> myexe MyTestName

或单人套房

> myexe suite MySuite

【讨论】:

  • 这就是我要找的。非常感谢。我会马上试一试。
  • 完美运行!非常感谢!
【解决方案2】:

这几乎是正确的。 “测试”实际上是用作链表中的一个节点,因此当您将其添加到新列表时,您必须更正指针以避免包含超出预期的测试。

所以你需要更换

  p = p->next;

  Test* q = p;
  p = p->next;
  q->next = NULL;

杰弗里

【讨论】:

  • 谢谢杰弗里!!!这个附录确实是必须的。没有这个,stijn 解决方案就无法工作。
  • 此解决方案不能有效地取消链接 UniTest++ 测试列表。 UnitTest++ 是否使用其他方式进行清理?
【解决方案3】:

如果您告诉它名称,RunTestsIf 只能运行一个套件。

class MyTrue
{
    public:
        MyTrue(const std::string & suiteName, const std::string & testName)
                : suite(suiteName), test(testName) {}

        bool operator()(const UnitTest::Test* const testCase) const
        {
            return suite.compare(testCase->m_details.suiteName) == 0 && 
                         test.compare(testCase->m_details.testName) == 0;
        }
    private:
        std::string suite;
        std::string test;
};

int main (...) {
    bool isSuite = false;
    std::string suiteName = "suite01";
    std::string testName  = "test01";

    UnitTest::TestReporterStdout reporter;
    UnitTest::TestRunner runner(reporter);
    if (isSuite) {
        runner.RunTestsIf(UnitTest::Test::GetTestList(),
            NULL, MyTrue(suiteName, testName), 0);
    } else {
        runner.RunTestsIf(UnitTest::Test::GetTestList(),
            NULL, UnitTest::True(), 0);
    }
}

【讨论】:

  • 这应该是公认的答案。这应该在 UnitTest++ 的官方文档中与此类似。
【解决方案4】:

您可以使用RunTestsIfpredicate 参数来做到这一点:

TestReporterStdout reporter;
TestRunner runner(reporter);
return runner.RunTestsIf(Test::GetTestList(), "MySuite",
    [](Test* t) { 
        return strcmp(t->m_details.testName, "MyTest") == 0; 
    }, 0);

如果您没有套件,或者想要搜索所有套件,可以将"MySuite" 替换为NULL

【讨论】:

    【解决方案5】:

    @stijn 给出的答案在测试列表操作中存在错误,因此它通常会运行您未请求的其他测试。

    此示例使用谓词函子,并利用 RunTestsIf 提供的内置套件名称匹配。它是正确的,而且简单得多。

    #include "UnitTest++.h"
    #include "TestReporterStdout.h"
    #include <string.h>
    using namespace UnitTest;
    
    /// Predicate that is true for tests with matching name,
    /// or all tests if no names were given.
    class Predicate
    {
    public:
    
    Predicate(const char **tests, int nTests)
        : _tests(tests),
          _nTests(nTests)
    {
    }
    
    bool operator()(Test *test) const
    {
        bool match = (_nTests == 0);
        for (int i = 0; !match && i < _nTests; ++i) {
            if (!strcmp(test->m_details.testName, _tests[i])) {
                match = true;
            }
        }
        return match;
    }
    
    private:
        const char **_tests;
        int _nTests;
    };
    
    int main(int argc, const char** argv)
    {
        const char *suiteName = 0;
        int arg = 1;
    
        // Optional "suite" arg must be followed by a suite name.
        if (argc >=3 && strcmp("suite", argv[arg]) == 0) {
            suiteName = argv[++arg];
            ++arg;
        } 
    
        // Construct predicate that matches any tests given on command line.
        Predicate pred(argv + arg, argc - arg);
    
        // Run tests that match any given suite and tests.
        TestReporterStdout reporter;
        TestRunner runner(reporter);
        return runner.RunTestsIf(Test::GetTestList(), suiteName, pred, 0);
    }
    

    【讨论】:

    • 我同意 - 这是选择测试的更好方式(可能是预期方式?)。此外,上述解决方案(stjin 和 Geoffrey)似乎以一种可能不安全的方式取消了测试列表的链接。
    【解决方案6】:

    已接受答案中的解决方案对我不起作用。当套件的第一个测试加载到 p 中时,它不会跳转到下一个测试(不知道确切原因)。

    我正在使用 Xcode 和 UnitTest++ v1.4

    #include "UnitTest++.h"
    #include "TestReporterStdout.h"
    
    #define SUITE_NAME "ActionFeedback"
    
    using namespace UnitTest;
    
    int main( int argc, char** argv )
    {
    #ifdef SUITE_NAME
        TestReporterStdout reporter;
        TestRunner runner( reporter );
        return runner.RunTestsIf( Test::GetTestList() ,  SUITE_NAME , True(), 0 );
    #else
        return RunAllTests();
    #endif
    
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 1970-01-01
      • 2012-06-05
      • 2017-08-07
      相关资源
      最近更新 更多