E D R , A S I H C RSS

Py Unit

1. Python Unit Testing Framework PyUnit — ๋Œ€•„œ

  • ›๋ฌธ€ PyUnit— žˆ๋Š” ๋„๋จผŠธ ๋ฌธ„œž„„ ๋ฐ˜€๋‘ . ณต๋ถ€ฒธ 1ฐจ  •๋ฆฌ‘. ผ๋‹•„ ๋ฒˆ—ญž‘—…๋’ค  •๋ฆฌ•จ.
  • PyUnit๋Š” Python — ธฐ๋ณธ œผ๋กœ ฌ•จ๋˜–ดžˆ๋Š” UnitTest Framework libraryด๋‹ค. •˜ง€๋งŒ, UnitTestž‘„— ๋Œ€•œ ธฐ๋ณธ œ๋…๋“ค„ ‰ฝฒŒ ๋‹  žˆ๋‹  ƒฐ•˜—ฌ ณต๋ถ€‘. (†”งžˆ C++๋กœ UnitTest•  —„‘ •ˆ๋‚˜„œ. --; Pythonœผ๋กœ ๋จผ € ”„๋กœ† ƒ€ž…ด ๋˜๋Š” ๋ถ€๋ถ„„ ž‘„•˜ ‹ค๋ฅธ –ธ–ด๋กœ ฌŒ…•˜๋Š” ‹œผ๋กœ • นŒ ƒฐ‘)

2. ด€๋ ‚ฌŠธ

3. TestCase

unit testing ˜ ฐ€žฅ ธฐ๋ณธ ฝ”๋“œ ๋ธ”๋ก‹œ„. …‹Œ…ณผ ๋ชจ๋“ˆ œ๋Œ€๋กœ ๋Œ•„ฐ€๋Š”ง€๋ฅผ ฒดฌ•˜ธฐ œ„•œ •˜๋‚˜˜ ‹œ๋‚˜๋ฆฌ˜ฐ€ ๋œ‹ค.

PyUnit—„œ๋Š” TestCase๋Š” unittest๋ชจ๋“ˆ˜ TestCase ด๋ž˜Šค๋กœ„œ ‘œ˜„๋œ‹ค.testcase ด๋ž˜Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด unittest.TestCase๋ฅผ ƒ†๋ฐ›•„„œ ๋งŒ๋“ค๋ฉด ๋œ‹ค.

4. „‹•œ testcase ˜  œž‘. 'failure', 'error'

ฐ€žฅ „‹•œ ๋ฐฉ๋ฒ•€ runTest ๋ฉ”†Œ๋“œ๋ฅผ ˜ค๋ฒ„ด๋”ฉ •˜๋Š” ฒƒด๋‹ค.
~cpp 
import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
	def runTest(self):
	widget = Widget("The widget")
	assert widget.size() == (50,50), 'incorrect default size'
…ŒŠคŒ…„ •˜ธฐ œ„•ด Python˜ assert ตฌ๋ฌธ„ ‚ฌšฉ•œ‹ค. testcaseฐ€ ‹–‰๋ •Œ assertion„ ‹–‰•˜๋ฉด AssertionError ฐ€ –ด๋‚˜ , testing framework๋Š” ด testcase๋ฅผ 'failure' –ˆ๋‹   •˜•  ฒƒด๋‹ค. 'assert' ๋ฅผ ๋ช…‹œ œผ๋กœ จ๋†“ง€ •Š€ ๋ถ€๋ถ„—„œ˜ ˜ˆ™ธฐ€ ๋ฐœƒ•œ ฒƒ๋“ค€ testing framework —„œ๋Š” 'errors'๋กœ „ฃผ•œ‹ค.

testcase๋ฅผ ‹–‰•˜๋Š” ๋ฐฉ๋ฒ•€ ›„— „ค๋ช…•  ฒƒด๋‹ค. testcase ด๋ž˜Šค๋ฅผ ƒ„•˜ธฐ œ„•šฐ๋ฆฌ๋Š” ƒ„ž— •„๋ฌด ž —†˜œ•ฃผ๋ฉด ๋œ‹ค.
~cpp 
testCase = DefaultWidgetSizeTestCase ()

5. žฌ‚ฌšฉ•˜๋Š” set-up code : 'fixtures' ๋งŒ๋“คธฐ.

๋งŒผ testcaseฐ€ ๋งŽ•„ง€๋ฉด ธ๋“ค˜ set-up ฝ”๋“œ๋“ค๋„ ‘๋ณต๋  ฒƒด๋‹ค. ๋งค๋ฒˆ Widget ด๋ž˜Šค๋ฅผ …ŒŠคŠธ•˜ธฐ œ„•ด๋ž˜Šค๋“ค๋งˆ๋‹ค widget Šค„Šค๋ฅผ ๋งŒ๋“œ๋Š” ฒƒ€ ๋ช…๋ฐฑ•œ ‘๋ณตด๋‹ค.
‹–‰Šค๋ŸฝฒŒ๋„ šฐ๋ฆฌ๋Š” setUp ๋ผ๋Š”, testing frameworkฐ€ …ŒŠคŒ…„ • •Œ ž๋™œผ๋กœ ˜œ•ฃผ๋Š” ๋ฉ”†Œ๋“œ๋ฅผ ตฌ˜„•œผ๋กœ„œ •ฒฐ•  ˆ˜ žˆ๋‹ค.

~cpp 
import unittest

class SimpleWidgetTestCase(unittest.TestCase):
	def setUp(self):
		self.widget = Widget("The widget")

class DefaultWidgetSizeTestCase(SimpleWidgetTestCase):
	def runTest(self):
		assert self.widget.size() == (50,50), 'incorrect default size'

class WidgetResizeTestCase(SimpleWidgetTestCase):
	def runTest(self):
		self.widget.resize(100,150)
		assert self.widget.size() == (100,150), \
		'wrong size after resize'

๋งŒผ setUp ๋ฉ”†Œ๋“œฐ€ …ŒŠคŠธ‘ ˜ˆ™ธ๋ฅผ ๋ฐœƒ•  ฒฝšฐ framework๋Š” …ŒŠคŠธ— error๋ฅผ ฐ€ง€  žˆ๋‹  ƒฐ•  ฒƒด๋‹ค. ธ๋ฆฌ  runTest ๋ฉ”†Œ๋“œฐ€ ‹–‰๋˜ง€ •Š„ ฒƒด๋‹ค.

‹ˆœžˆ, šฐ๋ฆฌ๋Š” tearDown ๋ฉ”†Œ๋“œ๋ฅผ  œณต•  ˆ˜ žˆ๋‹ค. runTestฐ€ ‹–‰๋˜  ๋‚œ ๋’ค˜ „ •ฒฐ•œ‹ค.
~cpp 
import unittest

class SimpleWidgetTestCase (unittest.TestCase):
	def setUp (self):
		self.widget = Widget ("The widget")
	def tearDown (self):
		self.widget.dispose ()
		self.widget = None
๋งŒผ setUp ๋ฉ”†Œ๋“œ ‹–‰„ณต๋˜๋ฉด, tearDown ๋ฉ”†Œ๋“œ๋Š” runTestฐ€ „ณต•˜ฑด •ˆ•˜ฑด ƒด€—†˜œ๋  ฒƒด๋‹ค.

ด๋Ÿฌ•œ testing code๋ฅผ œ„•œ ž‘—…™˜ฒฝ„ 'fixture' ๋  •œ‹ค.

6. —ฌ๋Ÿฌœ˜ test method๋ฅผ ฌ••œ TestCase classes


ข…ข…, ๋งŽ€ ž‘€ test case๋“คฐ™€ fixture๋ฅผ ‚ฌšฉ•˜ฒŒ ๋  ฒƒด๋‹ค. ด๋Ÿฌ•œ ฒฝšฐ, šฐ๋ฆฌ๋Š” DefaultWidgetSizeTestCase ฐ™€ ๋งŽ€ ž‘€ one-method class •ˆ— SimpleWidgetTestCase๋ฅผ „œ๋ธŒด๋ž˜‹•˜ฒŒ ๋œ‹ค. ฑด ‹œ„๋‚ญ๋น„ ,.. --a PyUnit๋Š” ๋” ๋‹ˆœ•œ ๋ฉ”ปค๋‹ˆ˜„  œณต•œ‹ค.
~cpp 
import unittest

class WidgetTestCase (unittest.TestCase):
	def setUp (self):
		self.widget = Widget ("The widget")
	def tearDown (self):
		self.widget.dispose ()
		self.widget = None
	def testDefaultSize (self):
		assert self.widget.size() == (50,50), 'incorrect default size'
	def testResize (self):
		self.widget.resize (100,150)
		assert self.wdiget.size() == (100,150), 'wrong size after resize'
—ฌธฐ—๋Š” runTest ๋ฉ”†Œ๋“œฐ€ —†๋Š”๋Œ€‹ , ๋‘œ˜‹ค๋ฅธ test ๋ฉ”†Œ๋“œ๋ฅผ ฐ€ง€  žˆ๋‹ค. ด๋ž˜Šค Šค„Šค๋Š”  œ ฐฐ self.widget „ ƒ—•˜  ฐ Šค„Šค— ๋Œ€•ด ๋”ฐ๋กœ †Œ๋ฉธ๋˜๋ฉด„œ ฐฐ˜ test method๋ฅผ ‹–‰•œ‹ค.

Šค„Šค๋ฅผ ƒ„• •Œ šฐ๋ฆฌ๋Š” …ŒŠคŠธ Šค„Šคฐ€ ˆ˜–‰•  …ŒŠคŠธ ๋ฉ”†Œ๋“œ๋ฅผ ตฌฒด œผ๋กœ ๋ช…‹œ•ฃผ–ด••œ‹ค. € constructor— ๋ฉ”†Œ๋“œ ด๋ฆ„„  –ดฃผ๋ฉด ๋œ‹ค.

~cpp 
defaultSizeTestCase = WidgetTestCase ("testDefaultSize")
resizeTestCase = WidgetTestCase ("testResize")

7. TestSuite : testcase๋“ค˜ ‘•ฒด

Test case Šค„Šค๋“ค€ ธ๋“ค…ŒŠคŠธ•˜ ค๋Š” ฒƒ๋“ค— ๋”ฐ๋•˜ ธ๋ฃน™”๋œ‹ค. PyUnit๋Š” ด๋ฅผ œ„•œ 'Test Suite' ๋ฉ”ปค๋‹ˆ˜„  œณต•œ‹ค. Test Suite๋Š” unittest ๋ชจ๋“ˆ˜ TestSuite class๋กœ ‘œ˜„๋œ‹ค.
~cpp 
widgetTestSuite = unittest.TestSuite ()
widgetTestSuite.addTest (WidgetTestCase ("testDefaultSize"))
widgetTestSuite.addTest (WidgetTestCase ("testResize"))

ฐฐ˜ …ŒŠคŠธ ˆ˜–‰„ œ„•ด (šฐ๋ฆฌ๋Š” ๋‚˜‘— ๋‹‹œ ๋ณด ง€๋งŒ), ฐฐ˜ …ŒŠคŠธ ๋ชจ๋“ˆ„ '˜œ•  ˆ˜ žˆ๋Š”' test suite ฒด๋ฅผ  œณต•˜๋Š” ฒƒ‹‹ค.
~cpp 
def suite ():
	suite = unittest.TestSuite ()
	suite.addTest (WidgetTestCase ("testDefaultSize"))
	suite.addTest (WidgetTestCase ("testResize"))
	return suite
˜๋Š”
~cpp 
class WidgetTestSuite (unittest.TestSuite):
	def __init__(self):
		unittest.TestSuite.__init__(self, map(WdigetTestCase, "testDefaultSize", "testResize")))
unittest ๋ชจ๋“ˆ—๋Š” makeSuite ๋ผ๋Š” Žธ๋ฆฌ•œ •ˆ˜ฐ€ žˆ๋‹ค. •ˆ˜๋Š” test case class •ˆ˜ ๋ชจ๋“  test case๋ฅผ ฌ••˜๋Š” test suite๋ฅผ ๋งŒ๋“ค–ดค€๋‹ค. (™€šฐ!!)
~cpp 
suite = unittest.makeSuite (WidgetTestCase, 'test')
makeSuite •ˆ˜๋ฅผ ‚ฌšฉ• •Œ testcase๋“ค€ cmp •ˆ˜๋ฅผ ‚ฌšฉ•˜—ฌ †ŒŠธ•œ ˆœ„œ๋˜๋กœ ‹–‰๋œ‹ค.

8. test suite๋“ค˜ ‘•ฉ. ๋ชจ๋“  …ŒŠคŠธ๋“ค„ •œ๋ฒˆ—~

ข…ข… testcase๋“ค„ •˜ ๋ฌถ€ suites๋“ค˜ ธ๋ฃน„ ›• •Œฐ€ žˆ๋‹ค. ธ๋ ‡ฒŒ •œผ๋กœ„œ •œ๋ฒˆ— ๋ชจ๋“  ‹œŠค…œ˜ test๋ฅผ ˆ˜–‰•  ˆ˜ žˆ๋‹ค. TestSuite๋“ค€ TestSuite — ฌ•จ๋  ˆ˜ žˆธฐ ๋•Œ๋ฌธ— ๋งคšฐ „‹•˜‹ค.
~cpp 
suite1 = module1.TheTestSuite ()
suite2 = module2.TheTestSuite ()
alltests = unittest.TestSuite ((suite1, suite2))

9. –ด๋””— …ŒŠคŠธฝ”๋“œ๋ฅผ ๋‘˜นŒ?

testcode๋Š” 'widgettests.py' ˜๋Ÿผ ๋”ฐ๋กœ …ŒŠคŠธฝ”๋“œ๋“ค— ๋Œ€•œ ๋ชจ๋“ˆ„‘๋Š” ฒƒ—ฌ๋Ÿฌฐ€ง€๋ฉด—„œ žฅ „ ง€๋‹Œ๋‹ค.
  • command line—„œ test module๋ฅผ ๋‹จ๋… œผ๋กœ ‹–‰•  ˆ˜ žˆ๋‹ค.
  • ฝ”๋“œ™€ testcodeฐ€ ‰ฝฒŒ ๋ถ„๋ฆฌ๋œ‹ค.
  • Šน๋ณ„•œ œ —†ด testcode๋ฅผ test๋ฐ›„ code— ๋งžถ”๋ ค๋Š” œ ˜„ ๋œ ˆ˜ žˆ๋‹ค.
  • …ŒŠคŠธ ๋œ ฝ”๋“œ๋ฅผ refactoring •˜ธฐ ๋” šฉ•„‹ค.
  • …ŒŠคŒ…  „๋žตด ๋ฐ”๋€Œ–ด๋„, source code๋ฅผ    •„š”ฐ€ —†–ด„‹ค.

10. Test˜ ‹–‰

PyUnit test framework๋Š” …ŒŠคŠธ๋ฅผ ˆ˜–‰•˜ธฐ œ„•ด 'TestRunner' ด๋ž˜Šค๋ฅผ ‚ฌšฉ•œ‹ค. ฐ€žฅ ผ๋ฐ˜ TestRunner๋Š” TextTestRunnerด๋‹ค.
~cpp 
runner = unittest.TextTestRunner ()
runner.run (widget.TestSuite)
ธฐ๋ณธ œผ๋กœ TextTestRunner๋Š” sys.stderr— œ •œ‹ค. TextTestrunner ฐ™€ ด๋ž˜Šค๋Š” Python interpreter sessionณผ ƒ˜ž‘šฉ•˜๋ฉด„œ test๋“ค„ ‹–‰‹œœ๋ณผ ˆ˜ žˆ๋Š” ƒ ธ ๋ฐฉ๋ฒ•ด๋‹ค.

11. Test กฐฑด๋“ค— ๋Œ€•„œ

test ฝ”๋“œ๋Š” ฐฐ˜ testกฐฑด— ๋งžถฐ ๋ฌธ œ๋ฐœƒ‹œ fail ๋“ฑ„ ๋ฐœƒ‹œ‚จ๋‹ค.

11.1. assert

~cpp 
def runTest(self):
	self.assert_(self.widget.size() == (100,100), "size is wrong")

11.2. failif

~cpp 
def runTest(self):
	self.failIf(self.widget.size() <> (100,100))

11.3. fail, failUnless

~cpp 
def runTest(self):
...
	if not hasattr(something, "blah"):
	self.fail("blah missing")
	# or just 'self.fail()'

11.4. assertEqual

~cpp 
def testSomething(self):
	self.widget.resize(100,100)
	self.assertEqual(self.widget.size, (100,100))

11.5. exception

~cpp 
def runTest(self):
	try:
		self.widget.resize(-1,-1)
	except ValueError:
		pass
	else:
		fail("expected a ValueError")


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:08
Processing time 0.0266 sec