轻量级测试框架TUT

原创 2011年07月07日 20:08:01

单元测试框架

在开发实践中,我目前常用的单元测试框架主要是两个:GTest与TUT。关于GTest我会在其他文章中详细介绍,本文将主要介绍TUT框架的特点及简单的使用方法。

TUT(Template Unit Tests)

TUT的官方主页:http://tut-framework.sourceforge.net/index.html

TUT的SVN地址:http://tut-framework.svn.sourceforge.net/svnroot/tut-framework/trunk

TUT的用户手册:http://tut-framework.sourceforge.net/doxygen/index.html

TUT是一个使用C++编写的单元测试框架,正如名称所示,它是一套C++模板库。下载代码后我们可以发现:它的全部核心是由一系列的.hpp文件组成,不包含任何源文件(example除外),因此,我们在进行单元测试时只需要包含tut的文件即可,无需对TUT进行编译或者链接,像使用STL一样轻松自由,这也是我喜欢它的原因。

 

TUT使用方法

既然是一个轻量级测试框架,我们应该在半个小时内上手,行了,废话少说,假定我们开发了下面的一个类库:

COperator.h

#include <stdio.h>
class COperator
{
private:
    int m_value;
public:
    COperator(int value)
    {
        m_value = value;
    }
    
    int add(int value)
    {
           return  m_value += value;
    }
    
    int  sub(int value)
    {
           return  m_value -= value;
    }
};


我们希望对COperator的每个接口进行单元测试,则可以针对COperator类定义一个TestGroup,然后在这个TestGroup编写多个TestCase,每个TestCase对一个或几个接口进行测试,测试代码如下:

test_COperator.cpp

#include <stdio.h> 
#include <tut/tut.hpp> 

namespace tut
{
     // 每个测试组都必须基于一个测试数据的类型才能创建,可以在这个数据结构中放一些可能被该组中多个测试用例使用的数据或者方法,
     // 如果没有,也可以什么都不填。最好不要通过此结构的成员在不同测验用例间传递数据。
     struct COperatorTestData
     {
            int GetTestNum()
            {
                    static const int  TestNums[] = { 1, 3, 5, 7, 9 };
                    static int i = 0;
                    static const int num = sizeof(TestNums) / sizeof(int);
                    return  TestNums[ i++  %  num];            
            }
     };
     
     // 创建一个test_group对象时,在构造函数中用一个字符串指明该test group的名称;
     // 当存在多个test group时,每个group的名称应该不同,这样可以在启动时单独指定某个test group进行测试;
     // 缺省情况下,一个test_group最多50个test case,如果希望更多case,可以在定义时指明上限,如:
     // test_group   testgroup("COperator",1000);
     static  test_group   testgroup("COperator");
     
     template<>
     template<>
     void test_group::object::test<1>()   // 编写第一个测试用例
     {
            set_test_name("Test COperatorTestData::add");
            int  src = GetTestNum();
            COperator  op(src) ;
            ensure("Test COperatorTestData::Add Failed",   op.add(1) == src + 1);
     }
      
    template<>
    template<>
    void test_group::object::test<2>()        // 编写第二个测试用例
    {
           set_test_name("Test COperatorTestData::sub");
           int  src = GetTestNum();
           COperator  op(src) ;
           ensure("Test COperatorTestData::Sub Failed",   op.sub(2) == src - 2);
    }
    
    template<>
    template<>
    void test_group::object::test<3>()        // 没事找茬,写个错误case看看
    {
           set_test_name("Test Tut::ensure");
           int  src = GetTestNum();
           COperator  op(src) ;
           ensure("Test COperatorTestData::Sub Failed",   op.sub(2) == src - 1);
    }
}

 

如果还需要测试其他类,我也可以在编写如test_*.cpp等一系列单元测试用例,最终通过main函数将用例综合起来: test_main.cpp

#include <tut/tut.hpp> 
#include <tut/tut_console_reporter.hpp> 
#include <tut/tut_main.hpp> 
#include <iostream> 

static tut::test_runner_singleton runner;

int main(int argc, const char* argv[])
{
    tut::console_reporter reporter;
    tut::runner.get().set_callback(&reporter);

    try
    {
        if(tut::tut_main(argc, argv))
        {
            if(reporter.all_ok())
            {
                return 0;
            }
            else
            {
                std::cerr << "/nFAILURE and EXCEPTION in these tests are FAKE ;)" << std::endl;
            }
        }
    }
    catch(const tut::no_such_group &ex)
    {
        std::cerr << "No such group: " << ex.what() << std::endl;
    }
    catch(const tut::no_such_test &ex)
    {
        std::cerr << "No such test: " << ex.what() << std::endl;
    }
    catch(const tut::tut_error &ex)
    {
        std::cout << "General error: " << ex.what() << std::endl;
    }
    return 0;
}


我们只需要将test_*.cpp连起来编译即可,假如生成一个test.exe文件,我们可以用
test.exe --help                     查看帮助
test.exe                                 运行所有TestGroup
test.exe "COperator"         运行名称为"COperator"的TestGroup
test.exe "COperator"   1    运行名称为"COperator"的TestGroup的第一个测试用例。

TUT的输出

TUT目前支持三种报告的输出方式:console_reporter, xml_reporter,cppunit_reporter。另外,也可以自己继承tut::callback,编写自己的输出方式。下面,以xml方式输出为例,可以如下修改test_main.cpp:

...
//#include <tut/tut_console_reporter.hpp> 
#include <tut/tut_xml_reporter.hpp> 
...

int main(int argc, const char* argv[])
{
    tut::xml_reporter reporter(std::cout);    // 将xml输出到stdio,也可以选择输出到某个字符串中
    tut::runner.get().set_callback(&reporter);
    ...
}


执行所有用例,输出结果如下:

<xml version="1.0" encoding="utf-8" standalone="yes"?>
<testsuites>
  <testsuite errors="0" failures="1" tests="3" name="COperator">
    <testcase classname="COperator" name="Test COperatorTestData::add"/>
    <testcase classname="COperator" name="Test COperatorTestData::sub"/>
    <testcase classname="COperator" name="Test Tut::ensure">
      <failure message="Test COperatorTestData::Sub Failed" type="Assertion">Test COperatorTestData::Sub Failed</failure>
    <testcase>
  <testsuite>
<testsuites>


TUT的断言

TUT支持一系列ensure开头的断言函数,一旦断言失败则该case不再继续执行,转而执行下一个case,下面介绍几种常用的断言,其余的建议自己参考tut_assert.hpp与tut_posix.hpp

// 断言某个条件为真
void ensure(bool cond);


// 断言某个条件为假
void ensure_not(bool cond);

// 断言某个条件为真,否则输出msg
template <typename M>
void ensure(const M& msg, bool cond);

// 与ensure类似,不过在posix系统中会在msg后输出errno
template<typename M>
void ensure_errno(const M& msg, bool cond);

// 断言某个条件假,否则输出msg  
template <typename M>
void ensure_not(const M& msg, bool cond);

// 断言两个值相等
template <typename LHS, typename RHS>
void ensure_equals(const LHS& actual, const RHS& expected);

// 断言两个值相等,否则输出msg  
template <typename M, typename LHS, typename RHS>
void ensure_equals(const M& msg, const LHS& actual, const RHS& expected);

// 断言两个浮点数相差不超过某个限定值,否则输出msg
template<typename M>
void ensure_equals(const M& msg, const double& actual, const double& expected, const double& epsilon);

// 断言两个集合相等,否则输出msg
template<typename LhsIterator, typename RhsIterator>
void ensure_equals(const std::string &msg,
                   const LhsIterator &lhs_begin, const LhsIterator &lhs_end,
                   const RhsIterator &rhs_begin, const RhsIterator &rhs_end);
// 断言两个值距离小于distance,否则输出msg
template <typename M, class T>
void ensure_distance(const M& msg, const T& actual, const T& expected, const T& distance);

// 相当于直接断言错误,并输出msg
void fail(const char* msg = "");

// 跳过某个测试用例剩余的代码(不视为断言错误),并打印msg
void skip(const char* msg = "");

TUT的断言
作者:icefireelf

出处:http://blog.csdn.net/icefireelf/article/details/6363126

QTP自动化测试框架系列一【目前的框架种类】

Ø  TestScript Modularity(脚本模块化框架)   Ø  TestLibrary Architecture(测试库结构框架)   Ø  Data-DrivenTesting...
  • flm2003
  • flm2003
  • 2012年03月01日 10:25
  • 1318

为什么开源C/C++单元测试框架极昂贵?

用开源C/C++单元测试框架做C/C++单元测试,费钱、费力、误事,极其昂贵,为什么?...
  • dellfox
  • dellfox
  • 2014年04月22日 09:05
  • 6396

轻量级自动化测试框架 UFT 初学者 学习编写

从基础讲解功能测试自动化框架的原理,框架的设计思想,最终使用关键字驱动的思想编写自动化框架,提供详细的编写手册,可以根据自己工作的需要进行源码修改,使之形成自己的一套自动化测试框架,也适合初学者通过学...
  • wyz_testing
  • wyz_testing
  • 2016年07月23日 16:45
  • 5075

简单分享一个轻量级自动化测试框架目录结构设计

很多人在做自动化测试的过程中会遇到一个瓶颈,就是能够写脚本,但是不知道怎么去组织代码,怎么搭建测试框架,今天博主就放点干货,分享一个轻量级的自动化测试框架的目录结构,如下图:分层如下: config层...
  • huilan_same
  • huilan_same
  • 2016年08月25日 23:30
  • 6465

Go语言 单元测试

Go语言提供了完善的单元测试支持,开发人员可以方便的编写测试代码,保证自己代码的质量。在目前的例子中,一般看到都是普通函数的例子。下面我将通过类方法的单元测试例子来展示一下Go语言的魅力。 首先是代...
  • abv123456789
  • abv123456789
  • 2014年04月20日 15:20
  • 1401

hdu-1543 Paint the Wall

Paint the Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...
  • acm_cxq
  • acm_cxq
  • 2016年03月22日 00:01
  • 418

UFT自动化测试框架

使用VBS的Function代替脚本中的Action。 UFT工具自带Call action的方法进行脚本复用,但本框架使用Function的方法代替Call action,每个Function执行...
  • yuntan2015
  • yuntan2015
  • 2015年10月18日 22:36
  • 949

Java测试框架Junit

一、JUnit4是JUnit框架有史以来的最大改进,其主要目标便是利用Java5的Annotation特性简化测试用例的编写。 二、先简单解释一下什么是Annotation,这个单词一般是翻译成元数据...
  • renpingqing
  • renpingqing
  • 2013年08月05日 21:57
  • 2073

GOOGLE的开源测试框架

GOOGLE的开源测试框架 library地址:http://code.google.com/p/googletest/下面内容转自:http://www.cnblogs.com/coderzh/ar...
  • byxdaz
  • byxdaz
  • 2011年10月27日 20:47
  • 1546

轻量级数据库sqlite的使用

本文不涉及一些概念性的东西,请大家多多原谅 这个就是Android sqlite的简单框架。 使用sqlite 大概分为3步 第一步:创建自己的sqliteopenhel...
  • u012938203
  • u012938203
  • 2015年06月04日 20:55
  • 856
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:轻量级测试框架TUT
举报原因:
原因补充:

(最多只允许输入30个字)