Click here to Skip to main content
Click here to Skip to main content

Unit Testing Framework for eVC++ Applications

By , 17 Oct 2004
 

Introduction

First of all, please forgive me for my bad English if it annoys you. Few months ago, I came to know about CPP Unit which is a unit testing framework for C++ application. I am a fresh guy out of college last year and was unaware about testing frameworks, so it was a very good experience for me to work with CPP Unit. As I was also programming on Windows CE, there was a need to write test cases for those applications also. But the problem with CPP Unit is that I was not able to compile for Windows CE as it used some features of C++ which are not supported by eVC++ compiler. I tried to search a similar test framework for Windows CE but I didn't find it. So after prolonged searching, I thought to write my own unit testing framework for Windows CE based applications. And this is what I came up with and I want to share with all.

This is a unit testing framework for applications written for Windows CE in particular. It provides GUI to select and run test cases, and to show results. It also stores the results of tests run to a file, if user wants.

Background

Programming in C++ for WinCE is very restrictive. It does not support templates, RTTI and other stuff of C++. CPP Unit uses templates and RTTI, but in eVC++ it's not available. That's why I have used lots of member function pointers and call backs to implement it.

Using the Frame Work

Compile the WCEUnit project to make WCEUnit.dll file for a particular platform. In order to use the testing framework, the test case project must be linked with the WCEUnit.dll. Write your test cases and link the project to WCEUnit.dll. Following topics discuss how to write test cases.

Writing Test Cases

When you write a test class, it should be derived from CTestSuite class defined in the framework. The CTestSuite class holds all the information about the test cases written for that particular suite. The individual test cases should be added to the test suite as show in the following example. The macros which are used in the following example are defined in the WCEMacros.h header file. These macros wrap the test case addition mechanism. The below code shows a test suite class written for testing CComplex class. The CComplex class is very simple, and does primary implementation of complex numbers, and I will not go into the details of that one.

//TestComplex.h

#ifndef __TEST_COMPLEX_INCLUDED__
#define __TEST_COMPLEX_INCLUDED__

#include "..\WCEUnit\TestSuite.h"
#include "..\WCEUnit\WCEUnitMacros.h"
#include "Complex.h"

class CTestComplex : public CTestSuite
{
public:
    //Pass the name of the test class as parameter.
    WCEUNIT_TESTSUITE_INIT(CTestComplex);
    //Pass the name of the test case function as parameter.
    WCEUNIT_ADD_TESTCASE(testAdd);
    WCEUNIT_ADD_TESTCASE(testEqual);
    WCEUNIT_ADD_TESTCASE_EXCEPTION(testExcp, CUserException);
    WCEUNIT_TESTSUITE_END();

public:
    /***********************************************************
    The signature of test case function should be void (func)();
    ***********************************************************/
    void testAdd();
    void testEqual();
    void testException();
    void CleanUpTest();
    void InitializeTest(); 
private:
    CComplex*        m_p1;
    Ccomples*        m_p2;
    CComplex*        m_p3;
};
#endif //__TEST_COMPLEX_INCLUDED__

Macro description

  • WCEUNIT_TESTSUITE_INIT(testSuite)

    Pass test suite class name to it. This function defines the starting of a CreateTestSuite() function. This function is defined as pure virtual in the CTestSuite class and is used to create the test case lists.

  • WCEUNIT_ADD_TESTCASE(testCase)

    This macro adds the code to the CreateTestSuite() function to add a test case function.

  • WCEUNIT_ADD_TESTCASE_EXCEPTION(testCase, testException)

    This macro is used to add a special type of test case function which should be tested for a particular type of exception. If the test case does not throw the exception then it is considered to fail.

  • WCEUNIT_TESTSUITE_END()

    This macro ends the CreteTestSuite() function.

You can see functions InitializeTest() and CleanUpTest() in the definition of the class. These functions are called before and after every test case execution. From the UI, you can select the behavior about these functions, i.e., whether you want those functions to be called for every test case or only once for all the test cases for a particular test suite class. You can specify your choice by checking or un-checking the Init Once check box on the main dialog.

Writing Test Conditions

While writing test cases, use macros defined in the WCEUnitMacros.h for writing the test conditions. Following are the macros used to write test conditions:

  • WCEUNIT_ASSERT(condition)

    If the condition is evaluated to false then it asserts and marks the test as failed.

  • WCEUNIT_ASSERT_FAIL(condition)

    This is reverse of above macro. If you want that the condition must return false then use this macro to test the condition.

  • WCEUNIT_ASSERT_EQUALS(testValue, compValue)

    This macro asserts if the testValue and compValue are not equal. If the two values are not equal then it marks the test case as failed. If you are using some user defined class objects to compare then the class must have '==' operator overloaded.

  • WCEUNIT_DOUBLE_EQUALS(testValue, compValue)

    This macro is similar to the above one but it assumes that the testValue and compValue are convertible to a double value. It type casts the results into a double value and then compares.

  • WCEUNIT_DOUBLE_BETWEEN(testValue, minValue, maxValue)

    This macro tests weather the testValue is less than maxValue and greater than minValue. It is assumed that the three values of expressions are evaluated to double. The following code shows the usage of the above macros.

Following code shows the use of above macros in test cases for CComplex class.

void CTestComplex::testAdd()
{
    CComplex temp;
    temp = *m_p1 + *m_p2;
    WCEUNIT_ASSERT(CComplex(30, 70) == temp);
}

void CTestComplex::testEqual()
{
    CComplex temp2;            //Below test should fail.
    WCEUNIT_ASSERT_FAIL(temp2 == *m_p3);

    CComplex temp1;            //Below test should pass.
    temp1 = *m_p1 + *m_p2;
    WCEUNIT_ASSERT_EQUALS(temp1, *m_p3);

    //To check the equality of the real and imaginary members.
    WCEUNIT_DOUBLE_EQUALS(temp1.GetReal(), m_p3->GetReal());
    WCEUNIT_DOUBLE_EQUALS(temp1.GetImaginary(), m_p3->GetImaginary());
}

void CTestComplex::testException()
{
    //This fuction is only to demonstrate the exception test.
    //It throws CUserException. This test will fail as the expected exception
    //is CFileException.

    CUserException e;
    THROW(&e);
}

void CTestComplex::InitializeTest()
{
    m_p1 = new CComplex(10, 20);
    m_p2 = new CComplex(20, 50);
    m_p3 = new CComplex(30, 70);
}

void CTestComplex::CleanUpTest()
{
    delete m_p1;
    delete m_p2;
    delete m_p3;
}

Running Test Cases

The CTestRunner class is responsible for running the test cases and getting the test results. To run the test cases you have written, create an instance of CTestRunner class. Also create the instance of all the test suite classes, and pass the address of each in the AddTestSuite() function of CTestRunner class. Then call Start() function of CTestRunner. The following code shows how to run test cases:

BOOL CTestComplexApp::InitInstance()
{
    //Create the instance of CTestRunner class.
    CTestRunner obj;
    //Create the instance of CTestComplex test suite class.
    CTestComplex test1;

    //Pass the address of CTestComplex instance to the AddTestSuite() function.
    obj.AddTestSuite(&test1);

    //Sart the WCEUnit dialog to run the test cases.
    obj.Start();
    return FALSE;
}

The GUI

WCEUnit/wceunit.jpg

The above image shows the main dialog. To select a test case to run, click the Select button, a new dialog will appear with the tree view of the test cases written by you. You can either select single test case or a test suite or All Tests. If you want to run all the test cases for a particular test suite then select that test suite, or if you want to run all the test cases of all the test suites then select the root node All Tests. The check box Init once is given for the option when the InitializeTest() and CleanUpTest() will be called. If it is checked then for each test suite, the IntializeTest() and CleanUpTest() is called only once respectively, before and after all the test cases are executed. If it is unchecked then for each and every test case, these two functions are called. Click the Run button to run the selected test cases. The results are displayed in the list box. If you want to see more information then just click the result item, you will be shown the detailed result. If you want to store the test results in a text file then check the Make log check box, a file \\WCEUnitLog.txt is created with the detailed test result information.

Points of Interest

During the development of this project, I learned a lot about the pointer to member functions in C++. They are amazing things and do a lot more than what you can imagine. May be next time, I will try to post some thing about pointer to member functions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Abdul Munaf Chhatra
Web Developer
India India
Member
A person who like to know about new things, peolple and make frineds. I strarted programming in 2000 with fortran but my first love in programming is C++. Also programmed in VB, MFC and for Windows CE.
 
Graduated in Physics and done masteres in Computer application. Physics and astronomy are my area of intrest. Karate is also one of my hobbies, BTW I am a Black Belt in Karate.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGPIOmemberasdfgh12345asdfgh24 Mar '10 - 10:30 
Can you write me a simple programm?
QuestionHow to link the DLL?memberdurgakul18 Jun '09 - 8:54 
How to link the DLL in visual studio 2008?
AnswerRe: How to link the DLL?memberAbdul Munaf Chhatra23 Jun '09 - 21:35 
I build this project long back with Visual Studio 6, and never tried it with any newer version.
 
Currently I am not working on this project, but will try to make it work with VS 2005 (that's what I have Smile | :) ) and will let you know.
 
This is native (unmanaged) dll, I think it would we fairly easy to build and link it VS 2008, but not sure of it. Please give it a try, and if you are able to do it, please let me know.
 
Cheers!!!
GeneralRe: How to link the DLL?memberdurgakul30 Jun '09 - 4:03 
Please let me know if you could build with VC 2005.
thanks
-Durga
GeneralRe: How to link the DLL?memberAbdul Munaf Chhatra2 Jul '09 - 5:14 
I was able to compile the project on VS 2005. Though I have not tested it yet.
 
Open the old project in VS 2005 and convert it to new one, and it will work fine. Please let me know about your progress. If you are not able to convert it I will try to send the code to you.
GeneralRe: How to link the DLL?memberdurgakul2 Jul '09 - 8:19 
hi
 
I will try to port the code to VS2008. The other question I have is:
 
My code which I want to test generates a .exe. How do I create a test code? will it be a separate project? If yes, how will I call functions in my code from my test code? Also how about testing the private and protected functions?
 
Thanks
-Durga
GeneralRe: How to link the DLL?memberAbdul Munaf Chhatra2 Jul '09 - 21:40 
It depends upon you how you want to test your application.
 
This code will generate WCEUnit.dll file, which you should link with your executable in order to use it.
 
You could add test case classes to your project itself. Also using pre-processor directive to exclude or include them from project. If you still find difficulty drop me an email at abdulmunaf.chhatra@gmail.com.
GeneralRe: How to link the DLL?memberdurgakul9 Jul '09 - 12:38 
I could compile and build your demo code in VS2008. Could you run your program on Pocket PC 2003 Emulator in VS2005?
I am not able to do that in VS 2008.
QuestionDoes this framework support VS2005 ?memberbigo103014 Jul '08 - 20:53 
i can build and run succeed , but can't run correctly on Windows Mobile 6
Class Emulator , test case can't load correctly.
Does this framework how to support VS2005 ?
Thx for your help..
AnswerRe: Does this framework support VS2005 ?memberAbdul Munaf Chhatra15 Jul '08 - 18:42 
Hi,
 
I have not tested this framework on VS2005. It would be great if you could point out the exact error, I would be able to help you out.
 
Regards,
 
AbdulMunaf Chhatra
Software Architect,
C-Sam Solutions Pvt. Ltd.
Phone : +91-265-2324018/19
Email : abdulmunaf.chhatra@c-sam.co.in

GeneralRe: Does this framework support VS2005 ?memberbigo103015 Jul '08 - 21:43 
hi ,
Thanks for your reply , i had send E-Mail for you with the error , but i can't post the snapshot for you .
BTW , you can see the snapshot as below :
http://picasaweb.google.com/bigotsai/WinCEUnit/photo#5223513141389740018
GeneralRe: Does this framework support VS2005 ?memberAbdul Munaf Chhatra16 Jul '08 - 2:35 
Hi,
 
I am afraid that I did not received your email. Can you send it to munaf_chhatra80@yahoo.co.in.
 
Also I dont see any error on the snapshot. I think if you can debug into the code and try to figure out why its not running the test case. Just put a break point in the handler of "OK" button, and try to step into TestRunner's run() method. Let me know your findings. I dont have VS2005 installed on my machine so I am afraid I am not able to see the problem my self.
 
Regards
 
AbdulMunaf Chhatra
Software Architect,
Catalytic Software Ltd.
Phone : +91 9966966616
Email : munaf_chhatra80@yahoo.co.in

GeneralRe: Does this framework support VS2005 ?memberbigo103016 Jul '08 - 7:47 
hi,
I had send email again on your new mail address:munaf_chhatra80@yahoo.co.in
 
BTW , let me show what issue i meet :
http://picasaweb.google.com/bigotsai/WinCEUnit/photo#5223663712489938162
 
Hint: you can use the magnifier (on the right-up side) to see the default size snapshot (more clearly)Smile | :)
 
Regards
 
Eagle Tsai
Email:bigotsai@gmail.com
Generala simple program in EMPmembersireeshakolluri7 Apr '08 - 22:09 
hi all, i am a newcomer to EMP,i have been working on it for only 2weeks.I have a idea of hierarchy of a simple "hello world" program.GUI->Display Mgmt->CCanvas->ICanvas->DrawText.But unable to do coding,so please give an example for it so that i can have a clear view of EMP.Please someone help me out.Confused | :confused:
GeneralThe code does not work ...membernathan_jing24 Oct '06 - 13:43 
The code does not work ...
QuestionHow to get the WCEUnit.dll ?memberhoward200625 Aug '06 - 4:48 
mhhh, this dll is not released with EVC tools kits or WinCE simulation.I read the comment on the top of WCEUnit.h,which shows it's a third party component, How did you find it?
 
coolman

AnswerRe: How to get the WCEUnit.dll ?memberAbdul Munaf Chhatra14 Nov '06 - 22:27 
Hi,
 
I saw your questing on my article on codeproject. I have not seen the article since long, so was not aware about your qestion.
 
The WCEUnit.dll is developed by me, so surly you can not find it in EVC package Smile | :) . Check the download link on the article page. You can download the dll from there.
 
If you have any specific query then please let me know on abdulmunaf.chhatra@c-sam.co.in.
 
And ya, thanks for reading the article Wink | ;-) .
 
Regards,
 
AbdulMunaf Chhatra
Software Architect,
C-Sam Solutions Pvt. Ltd.
Phone : +91-265-2324018/19
Email : abdulmunaf.chhatra@c-sam.co.in

GeneralMember function pointersmemberDon Clugston27 Oct '04 - 13:33 
To avoid duplicated effort, please have a look at my tutorial on member function pointers before you write an article.
 
http://www.codeproject.com/cpp/FastDelegate.asp
 
I tried to make it a comprehensive tutorial, but it doesn't have a whole lot of usage examples. Maybe you have some good techniques to share.
 
BTW, your English is great!
GeneralRe: Member function pointersmemberAbdul Munaf Chhatra2 Nov '04 - 23:21 
Hi,
 
thanks for compliments about my english. I read ur aritcle about function pointers its greate. I learn a lot from it.
 
Thanks once again.
 
AbdulMunaf
 
AbdulMunaf Chhatra
Software Engineer,
Popnet Infotech India Pvt. Ltd.
(a 100 % Subsidiary of C-Sam Inc.)
 
Phone : +91-265-2324018/19
Email : a.chhatra@popnet.co.in
GeneraleVC 3 and templatessussAndy Oliver26 Oct '04 - 22:32 
Hi AbdulMunaf
Nice article, I have been unit testing eVC classes as much as I can using Win32 console apps on Windows 2000, but this is a better approach.
One thing jumped out at me, templates are supported by the eVC 3.0 compiler. It is RTTI, C++ exceptions and streams that are missing. I use STLPort in my Pocket PC projects and that makes extensive use of templates.
Regards
Andy Oliver
 

 

GeneraleVC4 is supposed to support STL and RTTImemberJim Crafton18 Oct '04 - 8:26 
You do know that the newer version (it's been out for at least a year) of eVC++ does support both templates, STL and RTTI?
 
It's free on the MSDN website.
 
¡El diablo está en mis pantalones! ¡Mire, mire!
 
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
 
SELECT * FROM User WHERE Clue > 0
0 rows returned

GeneralRe: eVC4 is supposed to support STL and RTTImemberjan.vorlicek20 Oct '04 - 3:55 
That's true, it does support these features, but you cannot use it for compiling applications for PocketPC 2002 or SmartPhone 2002.
 
Jan
GeneralRe: eVC4 is supposed to support STL and RTTImemberJim Crafton20 Oct '04 - 14:56 
Doh! Smile | :)
My bad, I didn't realize that.
 
¡El diablo está en mis pantalones! ¡Mire, mire!
 
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
 
SELECT * FROM User WHERE Clue > 0
0 rows returned

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 18 Oct 2004
Article Copyright 2004 by Abdul Munaf Chhatra
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid