赞
踩
前面文章单元测试之CppTest测试框架中讲述利用宏ADD_SUITE将测试用例自动增加到测试框架中。但在使用中发现一个问题,就是通过宏ADD_SUITE增加多个测试Suite时,每次运行时都是所有测试Suite都运行,有的Suite运行比较慢,这对边写测试用例边编译运行时效率很低。于是就在原来测试框架下作出修改,即默认运行所有测试用例,不过可以通过命令指定测试用例来运行。
修改后新的类图如下:
修改说明:
类定义如下:
#ifndef TESTAPP_H
#define TESTAPP_H
#include <cpptest/cpptest.h>
#include <map>
#include <memory>
class TestApp
{
typedef std::map<std::string, std::unique_ptr<Test::Suite>> Suites;
Test::Suite mainSuite_;
Suites suites_;
TestApp();
public:
static TestApp& Instance();
void addSuite(const char* name, Test::Suite * suite);
int run(int argc, char *argv[]);
};
#define theTestApp TestApp::Instance()
template<typename Suite>
struct AutoAddSuite
{
AutoAddSuite(const char* Name) { theTestApp.addSuite(Name, new Suite()); }
};
#define ADD_SUITE(Type) AutoAddSuite<Type> add##Type(#Type);
说明:
#include "testapp.h"
#include <iostream>
#include <tuple>
#include <cstring>
#include <cstdio>
namespace
{
void usage()
{
std::cout << "usage: test [MODE] [Suite]\n"
<< "where MODE may be one of:\n"
<< " --compiler\n"
<< " --html\n"
<< " --text-terse (default)\n"
<< " --text-verbose\n";
}
std::tuple<std::string, std::unique_ptr<Test::Output>>
cmdline(int argc, char* argv[])
{
Test::Output* output = 0;
std::string name;
if (argc == 1)
output = new Test::TextOutput(Test::TextOutput::Verbose);
if(argc > 1)
{
const char* arg = argv[1];
if (strcmp(arg, "--compiler") == 0)
output = new Test::CompilerOutput;
else if (strcmp(arg, "--html") == 0)
output = new Test::HtmlOutput;
else if (strcmp(arg, "--text-terse") == 0)
output = new Test::TextOutput(Test::TextOutput::Terse);
else if (strcmp(arg, "--text-verbose") == 0)
output = new Test::TextOutput(Test::TextOutput::Verbose);
else if(strcmp(arg, "--help") == 0)
std::tuple<std::string, std::unique_ptr<Test::Output>>("help", output);
else
std::cout << "invalid commandline argument: " << arg << std::endl;
}
if(argc > 2)
name = argv[2];
return std::tuple<std::string, std::unique_ptr<Test::Output>>(name, output);
}
}
TestApp & TestApp::Instance()
{
static TestApp theApp;
return theApp;
}
TestApp::TestApp()
{}
void TestApp::addSuite(const char* name, Test::Suite * suite)
{
suites_.emplace(name, std::unique_ptr<Test::Suite>(suite));
}
int TestApp::run(int argc, char *argv[])
{
try
{
auto params = cmdline(argc, argv);
std::string name(std::move(std::get<0>(params)));
std::unique_ptr<Test::Output> output(std::move(std::get<1>(params)));
if(name == "help" || !output)
{
usage();
std::cout << "where Suite may be one of(default - all):\n";
for(auto & suite: suites_)
std::cout << " " << suite.first << "\n";
return 0;
}
for(auto & suite: suites_)
{
if(name.empty())
mainSuite_.add(std::move(suite.second));
else if(name == suite.first)
{
mainSuite_.add(std::move(suite.second));
break;
}
}
mainSuite_.run(*output, true);
Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());
if (html)
html->generate(std::cout, true, argv[0]);
}
catch (...)
{
std::cout << "unexpected exception encountered\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
说明:
#include "testapp.h"
int main(int argc, char *argv[])
{
try
{
theTestApp.run(argc, argv);
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
return 0;
}
主函数很简单,变化。
这里假定程序名称concurrent,显示用法:
$ ./concurrent --help
usage: test [MODE] [Suite]
where MODE may be one of:
--compiler
--html
--text-terse (default)
--text-verbose
where Suite may be one of(default - all):
AtomicSuite
BlockQueueSuite
ConditionVariableSuite
FutureSuite
LocksSuite
MutexSuite
RingQueueSuite
ThreadSuite
TimedMutexSuite
运行测试用例BlockQueueSuite:
$ ./concurrent --text-terse BlockQueueSuite
BlockQueueSuite: 0/2
I get a Apple pie
I get a Banana pie
I get a Pear pie
I get a Plum pie
I get a Pineapple pie
I get a Apple pie
I get a Banana pie
I get a Pear pie
I get a Plum pie
I get a Pineapple pie
I get a Apple
I get a Banana
I get a Pear
I get a Plum
I get a Pineapple
BlockQueueSuite: 1/2
I get a Apple pie in thread(3)
I get a Banana pie in thread(4)
I get a Pear pie in thread(0)
I get a Plum pie in thread(2)
I get a Pineapple pie in thread(1)
I get a Apple pie in thread(0)
I get a Banana pie in thread(2)
I get a Pear pie in thread(3)
I get a Plum pie in thread(1)
I get a Pineapple pie in thread(4)
I get a Apple in thread(1)
I get a Banana in thread(0)
I get a Pear in thread(2)
I get a Plum in thread(3)
I get a Pineapple in thread(4)
BlockQueueSuite: 2/2, 100% correct in 0.021808 seconds
Total: 2 tests, 100% correct in 0.021808 seconds
说明:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。