Click here to Skip to main content
15,896,502 members
Articles / Mobile Apps

Unit Testing Framework for eVC++ Applications

Rate me:
Please Sign up or sign in to vote.
4.63/5 (13 votes)
17 Oct 2004CPOL6 min read 85.4K   246   28  
A unit testing framework for eVC++ applications, and its usage.
/******************************************************************************
 * File Name:		WCEUnitDialog.cpp
 * Description:		This file contains the definition of methods of 
 *					CWCEUnitDialog class.
 * Date:			14/8/2004
 * Author:			AbdulMunaf Chhatra
 * E-Mail:			a.chhatra@popnet.co.in
 *
 * Warning:
 * This code is provided as is without any guarantee or warranty, implicit or 
 * explicit. If this code damages your system then the author is not 
 * responsible for it. This code is free to use with the permission of author. 
 * If you want to use this code then please send me an email at 
 * a.chhatra@popnet.co.in for permission, I will gladly give the permission. 
 * If you make any changes in this code, then feel free to add your name here, 
 * but this notice should appear in this code.
 ******************************************************************************
 * ------------------------------
 * Version History
 * ------------------------------
 * Version	:  1.0
 * Author	:  AbdulMunaf Chhatra
 * Date    	:  14/8/2004
 * Comment 	:  Initial release
 * ------------------------------
 *****************************************************************************/
 
#include "stdafx.h"
#include "resource.h"
#include "WCEUnitDialog.h"
#include "SelectTest.h"
#include "TestRunner.h"
#include "ResultDetail.h"
#include "About.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWCEUnitDialog dialog


CWCEUnitDialog::CWCEUnitDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CWCEUnitDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CWCEUnitDialog)
	m_chkMakeLog = FALSE;
	m_chkRunInitOnce = FALSE;
	//}}AFX_DATA_INIT
    m_TestSuiteList.RemoveAll();
}


void CWCEUnitDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CWCEUnitDialog)
	DDX_Control(pDX, IDC_MAIN_TEST_PROGRESS, m_prgsTestProgress);
	DDX_Control(pDX, IDC_MAIN_FAIL_LIST, m_lstResultList);
	DDX_Check(pDX, IDC_MAIN_MAKE_LOG, m_chkMakeLog);
	DDX_Check(pDX, IDC_MAIN_RUN_INIT_ONCE, m_chkRunInitOnce);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CWCEUnitDialog, CDialog)
	//{{AFX_MSG_MAP(CWCEUnitDialog)
	ON_BN_CLICKED(IDC_MAIN_RUN_TEST, OnMainRunTest)
	ON_BN_CLICKED(IDC_MAIN_SELECT_TEST, OnMainSelectTest)
	ON_NOTIFY(NM_CLICK, IDC_MAIN_FAIL_LIST, OnClickMainFailList)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_MAIN_RUN_INIT_ONCE, OnMainRunInitOnce)
	ON_BN_CLICKED(IDC_MAIN_MAKE_LOG, OnMainMakeLog)
	ON_BN_CLICKED(IDC_CMD_ABOUT, OnCmdAbout)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWCEUnitDialog message handlers


/********************************************************************
 * Purpose:       Initialize the list control. Called when the dialog 
 *                is created.
 *
 * Return value:  TRUE
 *
 * Date:          2004/02/21	
 ********************************************************************/
BOOL CWCEUnitDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
	m_lstResultList.InsertColumn(0, _T("Test"), LVCFMT_LEFT, 100);
	m_lstResultList.InsertColumn(1, _T("Result"), LVCFMT_LEFT, 60);
	m_lstResultList.InsertColumn(2, _T("Time"), LVCFMT_LEFT, 60);

    m_nTestSuiteIdx = -2;
    m_nTestCaseIdx  = -2;

    //Opening log file
    m_flLogFile.Open(_T("\\WCEUnitLog.txt"), CFile::modeCreate | CFile::modeWrite);
    CString strIntiLog;

    strIntiLog  = _T("\r\n*-----------------------------------------------------------*");
    strIntiLog += _T("\r\n*                   WCE Unit Log Start                      *");
    strIntiLog += _T("\r\n*-----------------------------------------------------------*");
    m_flLogFile.Write(strIntiLog, strIntiLog.GetLength() * 2);
    
	m_lstResultList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}


/********************************************************************
 * Purpose:       Runs the test which is selected in the combo box. 
 *                If a test suite is selected then runs all the tests
 *                of that suite.
 *
 * Return value:  none
 *
 * Date:          2004/02/21	
 ********************************************************************/
void CWCEUnitDialog::OnMainRunTest() 
{
	if(m_nTestCaseIdx == -2 || m_nTestSuiteIdx == -2)
    {
        return;
    }
    m_nCurProgressPos = 0;

    m_lstResultList.DeleteAllItems();
    this->SetDlgItemText(IDC_MAIN_ERROR_DESC, _T(""));
    
    this->GetDlgItem(IDC_MAIN_RUN_INIT_ONCE)->EnableWindow(FALSE);
    this->GetDlgItem(IDC_MAIN_MAKE_LOG)->EnableWindow(FALSE);
    
    m_trList.RemoveAll();
    
    m_pTestRunnerInstance->Run(m_nTestSuiteIdx, m_nTestCaseIdx, m_chkRunInitOnce);

	PopulateFailList();
	
    if(m_chkMakeLog)
    {
        MakeResultLog();
    }

    this->GetDlgItem(IDC_MAIN_RUN_INIT_ONCE)->EnableWindow(TRUE);
    this->GetDlgItem(IDC_MAIN_MAKE_LOG)->EnableWindow(TRUE);
}


/********************************************************************
 * Purpose:       Shows the test selection dialog box. Also stores 
 *                the selectes test case name in to member variables.
 *
 * Return value:  none
 *
 * Date:          2004/02/21	
 ********************************************************************/
void CWCEUnitDialog::OnMainSelectTest() 
{
    CSelectTest dlgSelectTest;
    int nListCount;
    POSITION pos;

    pos = m_TestSuiteList.GetHeadPosition();
    nListCount = m_TestSuiteList.GetCount();
    for(int i = 0 ; i < nListCount ; i++)
    {
        dlgSelectTest.SetTestSuiteList(m_TestSuiteList.GetNext(pos));
    }

	if(dlgSelectTest.DoModal() == IDCANCEL) //Show test select dialog.
    {
        return;
    }
    
    CString     strTestDispName;
    m_nTestSuiteIdx     = dlgSelectTest.GetSelSuiteIdx();
    m_nTestCaseIdx      = dlgSelectTest.GetSelTestCaseIdx();
    switch(m_nTestSuiteIdx) 
    {
    	case -2:
            return;
    		break;
    	case -1:
            strTestDispName = _T("All Test");
    		break;
    	default:
            POSITION pos = m_TestSuiteList.FindIndex(m_nTestSuiteIdx);
            strTestDispName = m_TestSuiteList.GetAt(pos)->GetTestSuiteName();
            strTestDispName += _T("::");
            if(m_nTestCaseIdx != -1)
            {
                strTestDispName += \
                m_TestSuiteList.GetAt(pos)->GetTestCaseName(m_nTestCaseIdx);
            }
    }
    
    SetDlgItemText(IDC_STC_TEST_NAME, strTestDispName);
	m_prgsTestProgress.SetPos(0);
}



/********************************************************************
 * Purpose:       Called on click event of result list. Displays the 
 *                result detail of the perticular test in new dialog.
 *
 * Return value:  none
 *
 * Date:          2004/02/24	
 ********************************************************************/

void CWCEUnitDialog::OnClickMainFailList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	int nCurSel = m_lstResultList.GetSelectionMark();
    if(CB_ERR == nCurSel)
        return;
	
    POSITION pos = m_trList.FindIndex(nCurSel);
    TEST_RESULT tr;
    tr = m_trList.GetAt(pos);
    
    CString strLog;
    strLog = FormatLogMessage(tr);

    CResultDetail dlgResultDetail;

    dlgResultDetail.SetResultDeatil(strLog);
    dlgResultDetail.DoModal();

	*pResult = 0;
}


/********************************************************************
 * Purpose:       Adds tail element to the test suite list.
 *
 * a_TestSuite:   Element to be added to the tail of the list.
 * Return value:  none
 *
 * Date:          2004/02/25	
 ********************************************************************/
void CWCEUnitDialog::SetTestSuiteList(CTestSuite *a_TestSuite)
{
    m_TestSuiteList.AddTail(a_TestSuite);
}


/********************************************************************
 * Purpose:       Called when the dialog is destroyed. Contains 
 *                clean up code.
 *
 * Return value:  none
 *
 * Date:          2004/02/25	
 ********************************************************************/
void CWCEUnitDialog::OnDestroy() 
{
	CDialog::OnDestroy();
	
	m_TestSuiteList.RemoveAll();
    m_trList.RemoveAll();

    CString     strEndLog;
    strEndLog  = _T("\r\n*-----------------------------------------------------------*");
    strEndLog += _T("\r\n*                     WCE Unit Log End                      *");
    strEndLog += _T("\r\n*-----------------------------------------------------------*\r\n\r\n");
    m_flLogFile.Write(strEndLog, strEndLog.GetLength() * 2);

    m_flLogFile.Close();
}


/********************************************************************
 * Purpose:       Event handler for selection change in the combo box.
 *                Set the member variables to test suite and case name.
 *
 * Return value:  none
 *
 * Date:          2004/02/25	
 ********************************************************************/
/*void CWCEUnitDialog::OnSelchangeMainChooseTest() 
{
	// TODO: Add your control notification handler code here
	int     nCurSelction;
    CString strItemText;

    nCurSelction = m_cmbChooseTest.GetCurSel();
    m_cmbChooseTest.GetLBText(nCurSelction, strItemText);
    CString strCurTestSuite;
    CString strCurTestCase;

    nCurSelction = strItemText.Find(_T("::"));
    if(nCurSelction == -1)
    {
        m_nTestCaseIdx      = -1;
        m_nTestSuiteIdx     = -1;
        return;
    }
    strCurTestSuite = strItemText.Left(nCurSelction);
    strCurTestCase  = strItemText.Mid(nCurSelction + 2);

    POSITION pos = m_TestSuiteList.GetHeadPosition();
    int     nLen = m_TestSuiteList.GetCount();

    for(int i = 0 ; i < nLen ; i++)
    {
        CString strTemp;
        strTemp = m_TestSuiteList.GetNext(pos)->GetTestSuiteName();

        if(strTemp == strCurTestSuite)
            break;
    }
    m_nTestSuiteIdx = i;
    pos = m_TestSuiteList.FindIndex(i);
    m_nTestCaseIdx = m_TestSuiteList.GetAt(pos)->GetTestCaseIdx(m_nTestSuiteIdx);

}
*/

/********************************************************************
 * Purpose:       Changes the state of run init variable. 
 *                Called when the check box is clicked.
 *
 * Return value:  none
 *
 * Date:          2004/02/21	
 ********************************************************************/
void CWCEUnitDialog::OnMainRunInitOnce() 
{
	// TODO: Add your control notification handler code here
	m_chkRunInitOnce = !m_chkRunInitOnce;
}



/********************************************************************
 * Purpose:       Changes the state of make log variable. 
 *                Called when the check box is clicked.
 *
 * Return value:  none
 *
 * Date:          2004/02/21	
 ********************************************************************/
void CWCEUnitDialog::OnMainMakeLog() 
{
	// TODO: Add your control notification handler code here
	m_chkMakeLog = !m_chkMakeLog;
}


/******************************************************************************
 * Purpose:       Sets the pointer to the TestRunner object
 *
 * Return value:  none
 *
 * Date:          2004/04/08	
 *****************************************************************************/
void CWCEUnitDialog::SetTestRunnerPointer(CTestRunner *pTestRunner)
{
    m_pTestRunnerInstance = pTestRunner;
}


/******************************************************************************
 * Purpose:       Adds the test result to the tail of the test result list
 *
 * Return value:  none
 *
 * Date:          2004/04/08	
 *****************************************************************************/
void CWCEUnitDialog::AddTestResult(TEST_RESULT &trCurTest)
{
    m_trList.AddTail(trCurTest);
    
    m_prgsTestProgress.SetPos(++m_nCurProgressPos);
}


/******************************************************************************
 * Purpose:       Sets the maximum range of progress bar
 *
 * Return value:  none
 *
 * Date:          2004/04/08	
 *****************************************************************************/
void CWCEUnitDialog::SetMaxProgressRange(int nMaxRange)
{
    m_prgsTestProgress.SetRange(0, nMaxRange);
}


/******************************************************************************
 * Purpose:       Generates a formated string for the particular test result.
 *
 * tr :           Test result structure for which the formated string is made.
 * Return value:  Formated string
 *
 * Date:          2004/04/08	
 *****************************************************************************/
CString CWCEUnitDialog::FormatLogMessage(TEST_RESULT &tr)
{
    CString 	strLog;
	CString 	strReturn = _T("\r\n");
	CString		strTemp;
	
	strLog.Empty();
	
	strLog = _T("Test case name: ") + tr.strTestCaseName + strReturn;
	
	if(tr.bSuccess)
	{
		float	fTime = ((float)tr.dExecutionTime) / 1000;
		strTemp.Format(_T("%.3f\r\n"), fTime);
		
		strLog += _T("Status: SUCCESS\r\nExecution time: ") + strTemp + strReturn;
		return strLog;
	}
	
	strLog += _T("Status: FAILED\r\n") ;
	
	if(tr.bException)
	{
		if(tr.strExceptionName.GetLength() <= 0)
		{
			strLog += _T("Exception: No exception caught\r\n");
		}
		else
		{
			strLog += _T("Exception: ") + tr.strExceptionName + strReturn;
			
		}
		return strLog;
	}
	else
    {
        if(tr.strExceptionName.GetLength() > 0)
        {
            strLog += _T("Exception: ") + tr.strExceptionName + strReturn;
			return strLog;
        }
    }

	strTemp.Format(_T("%d\r\n"), tr.dLineNumber);
	strLog += _T("File name: ") + tr.strFileName + strReturn;
	strLog += _T("Line Number: ") + strTemp;
	strLog += _T("Expression: ") + tr.strExpression + strReturn;
	return strLog;
}


/******************************************************************************
 * Purpose:       Logs the formated result in to the log file.
 *
 * Return value:  
 *
 * Date:          2004/04/08	
 *****************************************************************************/
void CWCEUnitDialog::MakeResultLog()
{
    POSITION pos = m_trList.GetHeadPosition();
    int   nCount = m_trList.GetCount();
    TEST_RESULT trTemp;
    CString     strLog;
    strLog  = _T("\r\n*--------//--------//--------//--------//--------//---------*\r\n");
    m_flLogFile.Write(strLog, strLog.GetLength() * 2);

    for(int i = 0 ; i < nCount ; i++)
    {
        trTemp = m_trList.GetNext(pos);

        strLog = FormatLogMessage(trTemp);
        strLog += _T("*-----------------------------------------------------------*\r\n\r\n");

        m_flLogFile.Write(strLog, strLog.GetLength() * 2);
    }
}

/******************************************************************************
 * Description:		Populates the list box with the test results.
 * 
 * Parameters:
 * 
 * 
 * Return Value:	none.
 *****************************************************************************/
BOOL CWCEUnitDialog::PopulateFailList()
{
	int nCount = m_trList.GetCount();
	POSITION	pos = m_trList.GetHeadPosition();
	TEST_RESULT	trCurTest;

	for(int i = 0 ; i < nCount ; i++)
	{
		CString strTemp;
		int nItemIdx = m_lstResultList.GetItemCount();
		m_lstResultList.InsertItem(nItemIdx,_T(""));
        
		trCurTest = m_trList.GetNext(pos);

		m_lstResultList.SetItemText(nItemIdx, 0, trCurTest.strTestCaseName);
		if(trCurTest.bSuccess == TRUE)
		{
			float fTime;
			fTime = (float)(trCurTest.dExecutionTime) / 1000;
			strTemp.Format(_T("%.3f"), fTime);;
			m_lstResultList.SetItemText(nItemIdx, 1, _T("SUCCESS"));
			m_lstResultList.SetItemText(nItemIdx, 2, strTemp);
		}
		else
		{
			m_lstResultList.SetItemText(nItemIdx, 1, _T("FAILED"));
		}

	}
	return TRUE;
}

/******************************************************************************
 * Description:		Click event handler of About button.
 * 
 * Parameters:
 * 
 * 
 * Return Value:	none.
 *****************************************************************************/
void CWCEUnitDialog::OnCmdAbout() 
{
	CAbout objAbout;
	
	objAbout.DoModal();	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Web Developer
India India
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.

Comments and Discussions