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

发布于 2024-09-15 17:38:27 字数 463 浏览 3 评论 0原文

如何使用 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++ 是否提供这样的函数,如果有,语法是什么?

How do I run a single test with UnitTest++ ?

I am running UnitTest++ out of the box as is. My main function looks like:

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);
}

For debugging I would like to write something like UnitTest::RunSingleTests("MyNewUnitTest"); instead of UnitTest::RunAllTests();. Does UnitTest++ provide such a function and if so, what is the syntax?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

心在旅行 2024-09-22 17:38:27

尝试将其作为unittest的main()(我实际上将其放入一个文件中并将其添加到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

try this as your main() for unittest (I actually put this in a file and added that to the unittest library, so that when linking to the library the executable automatically uses this main(). very convenient.)

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();
  }
}

invoke with arguments to run a single test:

> myexe MyTestName

or single suite

> myexe suite MySuite
尴尬癌患者 2024-09-22 17:38:27

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

所以你需要

  p = p->next;

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

杰弗里代替

This is almost correct. "Test" actually is purposed as a node in a linked list, so when you add it to a new list, you have to correct the pointer to avoid including more tests than you intended.

So you need to replace

  p = p->next;

with

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

Geoffrey

我恋#小黄人 2024-09-22 17:38:27

如果您告诉 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);
    }
}

RunTestsIf can only run one suite if you tell it the name.

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);
    }
}
心病无药医 2024-09-22 17:38:27

您可以通过使用 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

You could do this by using the predicate parameter of RunTestsIf:

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

If you do not have suites, or you want to search all of them, you can replace "MySuite" with NULL.

夜吻♂芭芘 2024-09-22 17:38:27

@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);
}

The answer given by @stijn has a bug in the test list manipulation, and therefore it usually runs additional tests that you did not request.

This example uses a predicate functor and also exploits the built-in suite name matching provided by RunTestsIf. It is correct and much simpler.

#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);
}
淡笑忘祈一世凡恋 2024-09-22 17:38:27

已接受答案中的解决方案对我不起作用。当套件的第一个测试加载到 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

}

The solution in the accepted answer is not working for me. When the first test of the suite is loaded into p it just won't jump to the next test (don't know exactly why).

I'm using Xcode and 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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文