E D R , A S I H C RSS

Gui Testing With Mfc

CppUnit 을 μ΄μš©ν•œ MFC μ—μ„œμ˜ GuiTesting (μ‹œλ„μ€‘. κ²°κ³ΌλŠ”?)

Dialog Based μ—μ„œμ˜ ν…ŒμŠ€νŠΈ

Dialog Based 의 경우 Modal Dialog λ₯Ό μ΄μš©ν•˜κ²Œ λœλ‹€. 이 경우 Dialog λ‚΄μ—μ„œλ§Œ 메세지루프가 μž‘λ™ν•˜κ²Œ 되λ€λ‘œ, DoModal ν•¨μˆ˜λ‘œ λ‹€μ΄μ–Όλ‘œκ·Έλ₯Ό λ„μš΄ μ΄ν›„μ˜ μ½”λ“œλŠ” ν•΄λ‹Ή Dialog κ°€ λ‹«νžˆκΈ° μ „κΉŒμ§€λŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€. 고둜, CppUnit μ—μ„œμ˜ fixture λ₯Ό 미리 κ΅¬μ„±ν•˜μ—¬ μ“Έ 수 μ—†λ‹€.

κ·Έλž˜μ„œ, ν…ŒμŠ€νŠΈλ₯Ό μ‹œλ„ν• λ•Œ Modaless Dialog 둜 λ§Œλ“€κ³  μ‹€ν—˜μ„ ν•˜μ˜€λ‹€.


μ›ν•˜λŠ” μž‘λ™ λͺ¨μŠ΅μ€ 이렇닀.
  1. Editbox 에 아무 글을 λ„£κ³ 
  2. Add λ²„νŠΌμ„ λˆ„λ΄λ©΄
  3. List box 에 Editbox 에 μ“΄ 글이 μˆœμ„œλŒ€λ‘œ μ²˜μŒλΆ€ν„° μ±„μ›Œμ§€κ³ 
  4. List box μ—μ„œμ˜ μ»μ„œλŠ” μ±„μ›Œμ§„ 글에 μœ„μΉ˜ν•œλ‹€.
  5. List box 에 값이 μ±„μ›Œμ§€κ³  λ‚œ λ’€, Editbox 의 글은 μ§€μ›Œμ§„λ‹€.

1. GUI Runner Setting

μ΄λŠ” App 클래슀의 InitInstance ν•¨μˆ˜μ—μ„œ ν•΄μ€λ‹€.

~cpp 
#include "stdafx.h"
#include "GuiTestingOne.h"
#include "GuiTestingOneDlg.h"

#include "cppunit\ui\mfc\TestRunner.h"

#include "GuiTestCase.h"

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

BEGIN_MESSAGE_MAP(CGuiTestingOneApp, CWinApp)
	//{{AFX_MSG_MAP(CGuiTestingOneApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

CGuiTestingOneApp::CGuiTestingOneApp()
{
}

CGuiTestingOneApp theApp;

BOOL CGuiTestingOneApp::InitInstance()
{
	AfxEnableControlContainer();

	CppUnit::MfcUi::TestRunner runner;
	runner.addTest (GuiTestCase::suite());
	runner.run();

/* --- Test Runner 만 μ‹€ν–‰λ˜λ„λ‘, λ‹€μ΄μ–Όλ‘œκ·Έ λ„μš°λŠ” 뢀뢄을 일단 막아둔닀. λ§ˆμ§€λ§‰μ— μ‹€ν–‰ν• λ•Œ 이 λΆ€λΆ„μ˜ μ£Όμ„μ²˜λ¦¬ 된 뢀뢄을 ν’€μ–΄μ£Όλ©΄ λœλ‹€.
#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	CGuiTestingOneDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
	}
	else if (nResponse == IDCANCEL)
	{
	}
*/
	return FALSE;
}

2. Test Case 의 μž‘μ„±


1. μ—°μŠ΅

일단, μ œλŒ€λ‘œ μž‘λ™ν•˜λŠ”μ§€ μ•Œμ•„λ³΄κΈ° μœ„ν•΄ μ—°μŠ΅κ²Έ m_bFlag λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄μ„œ ν…ŒμŠ€νŠΈλ₯Ό ν–ˆλ‹€.

ν…ŒμŠ€νŠΈ ν†΅κ³Όμ‹œ μ˜ˆμƒλ˜λŠ” κ²°κ³Ό
test1One μ—°μŠ΅κ²Έ Assert Equals. 10 == 10
test2GuiOne λ²„νŠΌμ΄ λˆŒλŸ¬μ‘Œμ„ κ²½μš°μ— CGuiTestingOneDlg::m_bFlag κ°€ true μƒνƒœκ°€ λœλ‹€.

~cpp 
#include <cppunit/TestCase.h>
#include <cppunit/Extensions/HelperMacros.h>

#include "stdafx.h"                                  // resource, mfc λ₯Ό μ΄μš©ν•  수 μžˆλ‹€.
#include "GuiTestingOneDlg.h"                        // import GuiTestingOneDlg 

class GuiTestCase : public CppUnit::TestCase {
	CPPUNIT_TEST_SUITE(GuiTestCase);
	CPPUNIT_TEST ( test1One );
	CPPUNIT_TEST ( test2GuiOne );
	CPPUNIT_TEST ( test3ListAdd );
	CPPUNIT_TEST_SUITE_END();

public:
	CGuiTestingOneDlg* pDlg;
	void setUp () {
		pDlg = new CGuiTestingOneDlg();
		pDlg->Create(IDD_GUITESTINGONE_DIALOG);
	}

	void tearDown () {
		delete pDlg;
	}

public:
	void test1One () {
		CPPUNIT_ASSERT_EQUAL (10, 10);
	}

	void test2GuiOne () {

		pDlg->OnButtonadd();
		CPPUNIT_ASSERT_EQUAL (true, pDlg->m_bFlag);
	}
};

μ½”λ“œ μΆ”κ°€
~cpp 
void CGuiTestingOneDlg::OnButtonadd() 
{
	// TODO: Add your control notification handler code here
	m_bFlag = true;
}

2. ν…μŠ€νŠΈ μΆ”κ°€

ν…ŒμŠ€νŠΈ ν†΅κ³Όμ‹œ μ˜ˆμƒλ˜λŠ” κ²°κ³Ό
test1One μ—°μŠ΅κ²Έ Assert Equals. 10 == 10
test2GuiOne λ²„νŠΌμ΄ λˆŒλŸ¬μ‘Œμ„ κ²½μš°μ— CGuiTestingOneDlg::m_bFlag κ°€ true μƒνƒœκ°€ λœλ‹€.
test3ListAdd Editbox 에 "Testing..." 을 μ…‹νŒ…. λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 1κ°œμž„μ„ 확인
. Listbox 의 첫번째 item 의 슀트링이 "Testing..." μž„μ„ 확인

~cpp 
	void test3ListAdd () {
		pDlg->m_ctlEdit.SetWindowText("Testing...");
		pDlg->OnButtonadd();
		CPPUNIT_ASSERT_EQUAL (1, pDlg->m_ctlList.GetCount());
		CString str;

		pDlg->m_ctlList.GetText(0, str);
		CPPUNIT_ASSERT ( isSameString(str, "Testing..."));
	}

	bool isSameString (CString& str1, PSTR str2) {
		return str1.Compare(str2) == 0;
	}
};

μ½”λ“œ μΆ”κ°€
~cpp 
void CGuiTestingOneDlg::OnButtonadd() 
{
	// TODO: Add your control notification handler code here
	m_bFlag = true;
	CString str;
	m_ctlEdit.GetWindowText(str);
	m_ctlList.AddString(str);
}

3. more...

ν…ŒμŠ€νŠΈ ν†΅κ³Όμ‹œ μ˜ˆμƒλ˜λŠ” κ²°κ³Ό
test1One μ—°μŠ΅κ²Έ Assert Equals. 10 == 10
test2GuiOne λ²„νŠΌμ΄ λˆŒλŸ¬μ‘Œμ„ κ²½μš°μ— CGuiTestingOneDlg::m_bFlag κ°€ true μƒνƒœκ°€ λœλ‹€.
test3ListAdd Editbox 에 "Testing..." 을 μ…‹νŒ…. λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 1κ°œμž„μ„ 확인
. Listbox 의 첫번째 item 의 λ¬Έμžμ—΄μ΄ "Testing..." μž„μ„ 확인
test4ListAddMore test3 에 μΆ”κ°€λœ ν˜•νƒœ. Editbox 에 λ‹€μ‹œ "Testing2..." λ₯Ό μ…‹νŒ…ν•˜κ³ , λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 2κ°œμž„μ„ 확인
. Listbox 의 λ‘λ²ˆμ§Έ item 의 λ¬Έμžμ—΄μ΄ "Testing2..." μž„μ„ 확인

~cpp 
	void test4ListAddMore () {
		test3ListAdd();
		CString str;

		pDlg->m_ctlEdit.SetWindowText("Testing2...");
		pDlg->OnButtonadd();
		CPPUNIT_ASSERT_EQUAL (2, pDlg->m_ctlList.GetCount());
		pDlg->m_ctlList.GetText(1, str);
		CPPUNIT_ASSERT ( isSameString(str, "Testing2..."));
	}

4. 'List box μ—μ„œμ˜ μ»μ„œλŠ” μ±„μ›Œμ§„ 글에 μœ„μΉ˜ν•œλ‹€' 에 λŒ€ν•œ ν…ŒμŠ€νŠΈ

ν…ŒμŠ€νŠΈ ν†΅κ³Όμ‹œ μ˜ˆμƒλ˜λŠ” κ²°κ³Ό
test1One μ—°μŠ΅κ²Έ Assert Equals. 10 == 10
test2GuiOne λ²„νŠΌμ΄ λˆŒλŸ¬μ‘Œμ„ κ²½μš°μ— CGuiTestingOneDlg::m_bFlag κ°€ true μƒνƒœκ°€ λœλ‹€.
test3ListAdd Editbox 에 "Testing..." 을 μ…‹νŒ…. λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 1κ°œμž„μ„ 확인
. Listbox 의 첫번째 item 의 λ¬Έμžμ—΄μ΄ "Testing..." μž„μ„ 확인
test4ListAddMore test3 에 μΆ”κ°€λœ ν˜•νƒœ. Editbox 에 λ‹€μ‹œ "Testing2..." λ₯Ό μ…‹νŒ…ν•˜κ³ , λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 2κ°œμž„μ„ 확인
. Listbox 의 λ‘λ²ˆμ§Έ item 의 λ¬Έμžμ—΄μ΄ "Testing2..." μž„μ„ 확인
test5ListCursorOne test3 μ§„ν–‰μ‹œ μ„ νƒλœ Item 이 0 번째 μž„μ„ 확인
test6ListCursorTwo test4 μ§„ν–‰μ‹œ μ„ νƒλœ Item 이 1 번째 μž„μ„ 확인

~cpp 
	void test5ListCursorOne () {
		test3ListAdd();
		CPPUNIT_ASSERT_EQUAL(0, pDlg->m_ctlList.GetCurSel());
	}

	void test6ListCursorTwo () {
		test4ListAddMore();
		CPPUNIT_ASSERT_EQUAL(1, pDlg->m_ctlList.GetCurSel());
	}


μ½”λ“œ μΆ”κ°€
~cpp 
void CGuiTestingOneDlg::OnButtonadd() 
{
	// TODO: Add your control notification handler code here
	CString str;
	m_ctlEdit.GetWindowText(str);
	m_ctlList.AddString(str);
	m_ctlList.SetCurSel(m_ctlList.GetCount()-1);
	m_bFlag = true;
}


5. edit box 의 λ‚΄μš©μ΄ 데이터 μΆ”κ°€ν›„ μ΄ˆκΈ°ν™” λ˜λŠ”μ§€ 확인

ν…ŒμŠ€νŠΈ ν†΅κ³Όμ‹œ μ˜ˆμƒλ˜λŠ” κ²°κ³Ό
test1One μ—°μŠ΅κ²Έ Assert Equals. 10 == 10
test2GuiOne λ²„νŠΌμ΄ λˆŒλŸ¬μ‘Œμ„ κ²½μš°μ— CGuiTestingOneDlg::m_bFlag κ°€ true μƒνƒœκ°€ λœλ‹€.
test3ListAdd Editbox 에 "Testing..." 을 μ…‹νŒ…. λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 1κ°œμž„μ„ 확인
. Listbox 의 첫번째 item 의 λ¬Έμžμ—΄μ΄ "Testing..." μž„μ„ 확인
test4ListAddMore test3 에 μΆ”κ°€λœ ν˜•νƒœ. Editbox 에 λ‹€μ‹œ "Testing2..." λ₯Ό μ…‹νŒ…ν•˜κ³ , λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ Listbox 의 item κ°―μˆ˜κ°€ 2κ°œμž„μ„ 확인
. Listbox 의 λ‘λ²ˆμ§Έ item 의 λ¬Έμžμ—΄μ΄ "Testing2..." μž„μ„ 확인
test5ListCursorOne test3 μ§„ν–‰μ‹œ μ„ νƒλœ Item 이 0 번째 μž„μ„ 확인
test6ListCursorTwo test4 μ§„ν–‰μ‹œ μ„ νƒλœ Item 이 1 번째 μž„μ„ 확인
test7EmptyEditbox test3 μ§„ν–‰μ‹œ Editbox 의 슀트링이 λΉ„μ—ˆλŠ”μ§€ 확인

~cpp 
	void test7EmptyEditbox () {
		test3ListAdd();
		CString str;

		pDlg->m_ctlEdit.GetWindowText(str);
		CPPUNIT_ASSERT (str.IsEmpty());
	}

μ½”λ“œ μΆ”κ°€
~cpp 
void CGuiTestingOneDlg::OnButtonadd() 
{
	// TODO: Add your control notification handler code here
	CString str;
	m_ctlEdit.GetWindowText(str);
	m_ctlList.AddString(str);
	m_ctlList.SetCurSel(m_ctlList.GetCount()-1);
	m_ctlEdit.SetWindowText("");
	m_bFlag = true;
}

μ—¬κΈ°κΉŒμ§€λ‘œ 생각해놓은 ν…ŒμŠ€νŠΈλ“€μ΄ μ „λΆ€ μ™„λ£Œ. μ•žμ— InitInstance 에 써 넣은 주석을 ν’€κ³ , μ‹€μ œλ‘œ μ‹€ν–‰ν•΄λ³΄μž.
~cpp 
BOOL CGuiTestingOneApp::InitInstance()
{
	AfxEnableControlContainer();

	CppUnit::MfcUi::TestRunner runner;
	runner.addTest (GuiTestCase::suite());
	runner.run();

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	CGuiTestingOneDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
	}
	else if (nResponse == IDCANCEL)
	{
	}

	return FALSE;
}


문제점

  • λͺ¨λ‹¬λ¦¬μŠ€ λ‹€μ΄μ–Όλ‘œκ·ΈμΈ κ΄€κ³„λ‘œ, ν…ŒμŠ€νŠΈλ₯Ό run 으둜 μ‹€ν–‰ν•  λ•Œ λ§ˆλ‹€ Dialog κ°€ μΌœμ‘Œλ‹€ κΊΌμ‘Œλ‹€ ν•œλ‹€. 이에 λ”°λ₯Έ μ†λ„μ˜ μ§€μ—°μ˜ 문제. -> CDialog::ShowWindow(SH_HIDE); 둜 ν•΄κ²° κ°€λŠ₯


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:20
Processing time 0.0259 sec