使用Symbian OS Unit 单元测试框架
 

2009-03-19 作者:程凯 来源:ckasj.vicp.net

 

关于单元测试的概念请参考其他资料,此单元测试框架和junit,cppunit类似。如果你熟悉这两个开源的单元测试工具上手起来应该比较快。 这里我只是介绍基于symbian系统的一个开源单元测试框架的使用。作为目前Symbian项目开发的一个培训资料。更详细的信息请访问:http://www.symbianosunit.co.uk/

将单元测试框架加入你的项目

假设你已经安装配置好了Symbian开发的基本环境,包括IDE(vs.net or carbide C++),SDK,ACTIVE PERL等。另外你需要下载SymbianOSUnit源码包,目前最新的版本是1.02

假设我们的项目所在目录为UnitTestExp,项目路径为UnitTestExp\HelloUnitTest。 按照以下步骤设置操作

  • 解压symbianosunit07112006_v1.02.zip 到 your_path\SymbianOSUnit07112006_v1.02
  • 拷贝your_path\SymbianOSUnit07112006_v1.02\Haystacks\CopyToYourProject\内的所有内容到UnitTestExp\HelloUnitTest(覆盖拷贝)
  • 拷贝your_path\SymbianOSUnit07112006_v1.02\Haystacks\SymbianOSUnit到UnitTestExp\SymbianOSUnit

此时你的项目目录结构应该如下图所示:

UnitTestExp
├─HelloUnitTest
│  ├─aif
│  ├─data
│  ├─group
│  ├─inc
│  ├─sis
│  ├─src
│  └─test
└─SymbianOSUnit
    ├─cxxtest
    ├─Doc
    └─SymbianOSUnitApp
        ├─Aif
        ├─data
        │  ├─S60
        │  ├─S60_3RD
        │  ├─S80
        │  ├─UIQ
        │  └─uiq3
        ├─group
        │  ├─S60
        │  ├─S60_3RD
        │  ├─S80
        │  ├─UIQ
        │  └─UIQ3
        ├─inc
        ├─install
        │  ├─S60
        │  ├─S60_3RD
        │  ├─S80
        │  ├─uiq
        │  └─UIQ3
        └─src

在这里我以一个简单的应用程序示例演示symbianUnitTest测试框架的使用。本示范文档是使用Carbide.c++作为IDE进行测试,其他的IDE应该区别不大。

配置单元测试框架的项目定义文件

Carbide.C++

首先需要对单元测试框架的项目定义文件进行简单的配置,确认SymbianOSUnit.mmp已经拷贝到HelloUnitTest/group/目录下。编辑SymbianOSUnit.mmp文件

/*
* ============================================================================
*  Name     : SymbianOSUnit.mmp
*  Part of  : SymbianOSUnit
*  Created  : 19/10/2006 by vm,sj
*  Description:
*     This is the project specification file for sample project.
*     Initial content was generated by Series 60 AppWizard.
*    
*  Version  :
*  Copyright: Penrillian. All rights reserved.
*  Web : www.penrillian.com
* ============================================================================
*/

 
//单元测试TestSuit
SOURCEPATH ..\test
SOURCE      TestSource.cpp
USERINCLUDE ..\test
 
//需要测试的项目目标源文件
SOURCEPATH   ..\src
USERINCLUDE  ..\inc 
SOURCE      StackClass.cpp
 
//include SymbianOSUnit mmp file from proper directory depending on relative path and target platform
 
#ifdef EKA2
#include "..\..\SymbianOSUnit\SymbianOSUnitApp\group\s60_3rd\SymbianOSUnit.source"
#else
#include "..\..\SymbianOSUnit\SymbianOSUnitApp\group\s60\SymbianOSUnit.source"
#endif

Vs2003.net

这里假设你已经配置好了Vs2003.net的Symbian的开发环境(Vs2003+Carbide.net). 首先你需要打开UnitTestExp\SymbianOSUnit\SymbianOSUnitApp\group\S601)。 另存SymbianOSUnit.source为SymbianOSUnit-with-HelloUnit.mmp 。编辑SymbianOSUnit-with-HelloUnit.mmp 文件加入以下配置用来指定测试用例的源文件和头文件。

SOURCEPATH ..\..\..\..\HelloUnitTest\src
SOURCE StackClass.cpp

SOURCEPATH ..\..\..\..\HelloUnitTest\test
SOURCE TestSource.cpp


USERINCLUDE ..\..\..\..\HelloUnitTest\inc
USERINCLUDE ..\..\..\..\HelloUnitTest\test

导入单元测试项目文件

接下来我们可以通过IDE的向导导入我们配置好的项目文件。

Carbide.C++ 导入 UnitTestExp\HelloUnitTest\group\SymbianOSUnit.mmp

Vs2003 导入 UnitTestExp\SymbianOSUnit\SymbianOSUnitApp\group\S60\SymbianOSUnit-with-HelloUnit.mmp

HelloUnitTest 示例工程介绍

HelloUnitTest 是一个简单的Symbian UI应用程序,此程序使用了一个简单的堆栈类,并且在图形界面中演示了堆栈PUSH,POP的动作。在这里我们要通过单元测试框架对我们这个项目中的CStack类进行单元测试。下图显示了HelloUnitTest的运行界面。

写我们的第一个测试用例

现在我们来写一个测试用例来检查CStack类,我们把一系列功能测试叫做Test suites . 依据规范每个TestSuite必须继承自 CxxTest::TestSuite。所有的测试方法必须以小写的'test'开头如;void CTest::testDummyTest() 。我们应该避免在项目里有以test开头的方法或函数避免产生冲突。

一个TestSuit的代码

#include "TestHeader.h"
#include "TestDriver.h"
#include "Logger.h"
 
void CTest::setUp()
{
}
 
void CTest::tearDown()
{
}
 
 
void CTest::testDummyTest()
{
  TS_ASSERT(ETrue);
}

添加一个新的测试用例

编辑TestHeader.h 加入一个测试用例的声明

public:
	void testMyFirstTest();

编辑TestSource.cpp加入我们的测试用例实现

void CTest::testMyFirstTest() {
	TS_ASSERT(ETrue);
}

运行testgen脚本生成测试TestDriver.h

TestDriver.h是一个测试框架使用的描述测试任务的头文件,我们每添加一个测试用例或TestSuite需要使用testgen脚本生成或更新TestDriver.h

D:\project\symbian\UnitTestExp\HelloUnitTest\test>testgen
D:\project\symbian\UnitTestExp\HelloUnitTest\test>rem Copyright (c) Penrillian L
td 2003-2006. All rights reserved.
D:\project\symbian\UnitTestExp\HelloUnitTest\test>rem Web: www.penrillian.com
D:\project\symbian\UnitTestExp\HelloUnitTest\test>perl -S ..\..\SymbianOSUnit\cx
xtestgen.pl -o TestDriver.h TestHeader.h
请按任意键继续. . .
D:\project\symbian\UnitTestExp\HelloUnitTest\test>

编译测试框架并且运行

添加了一个新的测试用例我们需要重新编译测试框架。然后运行测试框架,其结果如下图。

单元测试框架的运行界面

准备运行单元测试框架

运行结果

添加一个TestSuite

有时候一个TestSuite装载的测试用例过多(TestCase)对TestSuite运行的时候会比较慢,或者我们希望把功能模块相近的测试用例放在一起。在这种情况下我们可以考虑创建多个TestSuit,选择每个TestSuit进行单独运行而不是运行所有的TestSuit。接下来我们为我们的CStack类写一个新的TestSuite.

添加一个新的TestSuite声明

添加新TestSuite定义到TestHeader.h中

class CNewTestSuite : public CxxTest::TestSuite
{
public:
CNewTestSuite(const TDesC8& aSuiteName):CxxTest::TestSuite(aSuiteName){}
 
public:
 
void testAfterCreationL();       
        void testPushAndPopL();
        void testPopEmptyL();
 
private:
void setUp();
void tearDown();
 
private:
CStack *iStack;
};

添加测试用例实现

在TestSource.cpp中添加以下代码

void CNewTestSuite::setUp()
{
iStack=new(ELeave)CStack;
}
 
void CNewTestSuite::tearDown()
{
delete iStack;
}
 
void CNewTestSuite::testAfterCreationL()
{
TS_ASSERT_EQUALS(iStack->CurrentSize(), 0);
}
 
void CNewTestSuite::testPushAndPopL()
{
iStack->push(1234);
TS_ASSERT_EQUALS(iStack->CurrentSize(), 1);
TS_ASSERT_EQUALS(iStack->pop(), 1234);
TS_ASSERT_EQUALS(iStack->CurrentSize(), 0);
}
 
void CNewTestSuite::testPopEmptyL()
{
TS_ASSERT_THROWS_ANYTHING(iStack->pop());
}

更新TestDriver.h

运行your_project/testgen.bat 更新TestDriver.h

运行单元测试框架

编译测试框架并且运行,你会看到选项菜单多出一个TestSuite。我们可以选择运行所有的TestSuite也可以选择单独的TestSuite运行。

如果你希望添加新的TestSuite在自己定义的头文件中和源文件中(如TestNewSuite.h TestNewSuite.cpp)你必须更新your_project/test/testgen.bat.为其添加新的头文件名称

perl -S ..\..\cxxtestgen.pl -o TestDriver.h TestHeader.h TestNewSuite.h

然后你还要修改your_project\group\ExtraTestBuildTasks.bldmake 文件添加如下内容

$(INCDIR)\testdriver.h: $(INCDIR)\TestHeader.h:$(INCDIR)\TestNewSuite.h

检测内存泄漏

单元测试框架会自动检测每个测试用例的内存泄漏问题,如果测试用例存在内存泄漏将导致测试失败。以下代码将会因为内存泄漏而导致测试失败

CStack::CStack()
{
iSize=0;
User::Alloc(1);
}

测试用例运行结果

查看用例测试日志

单元测试框架会把测试用例结果同时输出到系统日志文件中,输出目录为目标设备的c:\log .文件名称是SOSUnit.log 。确保你的目标设备c:\log目录存在,否则Symbian系统不会自动创建。如果你使用模拟器,文件将输出在模拟环境的目标设备中 (SDK_HOME\Epoc32\winscw\c\logs) 。

模拟器环境日志输出地址

C:\Symbian\8.0a\S60_2nd_FP2_CW\Epoc32\winscw\c\logs

测试用例日志文件内容

unning 5 tests ....
CNewTestSuite:TestSource.cpp:54: Expected (iStack->pop()) to throw (...) but it threw nothing
Failed 1 of 5 test(s)
Success rate: 80%

用户输出日志

用户可以再测试用例中通过引入写自己的日志信息

#include "Logger.h"
...

Logger::Log(_L("Test information"));

确认存在c:\logs\SOSUnit 目录,如果没有存在需手工建立一个


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织