Contents
- 1. Python Unit Testing Framework PyUnit μ λν΄μ
- 2. κ΄λ ¨ μ¬μ΄νΈ
- 3. TestCase
- 4. κ°λ¨ν testcase μ μ μ. 'failure', 'error'
- 5. μ¬μ¬μ©νλ set-up code : 'fixtures' λ§λ€κΈ°.
- 6. μ¬λ¬κ°μ test methodλ₯Ό ν¬ν¨ν TestCase classes
- 7. TestSuite : testcaseλ€μ μ§ν©μ²΄
- 8. test suiteλ€μ μ§ν©. λͺ¨λ ν μ€νΈλ€μ νλ²μ~
- 9. μ΄λμ ν μ€νΈμ½λλ₯Ό λκΉ?
- 10. Testμ μ€ν
- 11. Test 쑰건λ€μ λν΄μ
1. Python Unit Testing Framework PyUnit μ λν΄μ ¶
- μλ¬Έμ PyUnitμ μλ λνλ¨ΌνΈ λ¬Έμμμ λ°νλ . 곡λΆκ²Έ 1μ°¨ μ 리μ€. μΌλ¨ μ½κ° λ²μμμ
λ€ μ 리ν¨.
- PyUnitλ Python μ κΈ°λ³Έμ μΌλ‘ ν¬ν¨λμ΄μλ UnitTest Framework libraryμ΄λ€. νμ§λ§, UnitTestμμ±μ λν κΈ°λ³Έμ μΈ κ°λ
λ€μ μ½κ² λ΄κ³ μλ€κ³ μκ°νμ¬ κ³΅λΆμ€. (μμ§ν C++λ‘ UnitTestν μλ μλμ. --; PythonμΌλ‘ λ¨Όμ νλ‘ν νμ
μ΄ λλ λΆλΆμ μμ±νκ³ λ€λ₯Έ μΈμ΄λ‘ ν¬ν
νλ μμΌλ‘ ν κΉ μκ°μ€)
2. κ΄λ ¨ μ¬μ΄νΈ ¶
- http://c2.com/cgi/wiki?PythonUnit - μμ§ μμ½μ΄λ΄μ. --; ν½νκ³ μ κΈ΄ λνμ§λ§. --a
- http://pyunit.sourceforge.net
- http://junit.org - Java Unit Test Framework λͺ¨λ.
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κ° ν μ€ν μ ν λ μλμΌλ‘ νΈμΆν΄μ£Όλ λ©μλλ₯Ό ꡬνν¨μΌλ‘μ ν΄κ²°ν μ μλ€.
λ€νμ€λ½κ²λ μ°λ¦¬λ 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.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))