일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Jupyter
- openpyxl
- ssh
- appium
- Jupyter Notebook
- ftp
- insert
- postgres
- nohup
- GoCD
- sshpass
- 28015
- nGrinder
- STF
- 실행권한
- postgresql
- SWIFT
- nmap
- PYTHON
- mysql
- rethinkdb
- appium server
- kitura
- perfect
- STF_PortForwarding
- port forwarding
- create table
- Materials
- centos
- ubuntu
- Today
- Total
don't stop believing
Python Unittest 살펴보기 본문
Python에서 method, property등의 검증을 위해 사용된다.
[https://docs.python.org/3/library/unittest.html]
간단하게 알아봅시다.
우선 코드부터 바로 들어갑니다.
import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('Foo'.isupper()) def test_split(self): s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # check that s.split fails when the separator is not a string with self.assertRaises(TypeError): s.split(2) if __name__ == '__main__': unittest.main()
unittest를 사용할 class는 unittest.TestCase를 상속해야 합니다.
그리고 각각의 method들의 이름은 test_로 시작되어야 합니다.
위 코드를 실행하면 아래와 같이 출력됩니다.
$ python basic_example_1.py ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
좀더 자세한 결과를 보고 싶다면 -v 옵션을 추가 합니다.
$ python basic_example_1.py -v test_isupper (__main__.TestStringMethods) ... ok test_split (__main__.TestStringMethods) ... ok test_upper (__main__.TestStringMethods) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
unittest.TestCase를 상속한 class의 구조는 setUp(), 'test_'로 시작하는 method들 그리고 tearDown()으로 되어 있습니다.
setUp()은 testcase가 시작할때의 property 할당 등의 설정을 할 수 있으며 가장 먼저 호출됩니다.
'test_'로 시작하는 method들은 각각의 테스트 항목이고 tearDown()은 testcase를 마칠때 호출됩니다.
import unittest class Widget(): def __init__(self, name): self.name = name self.width = 0 self.high = 0 def size(self): return (self.width, self.high) def resize(self, width, high): self.width = width # high는 100을 넘을 수 없다. if high > 100: self.high = 100 else: self.high = high return (self.width, self.high) def dispose(self): self.name = "" self.width = 0 self.high = 0 return True class WidgetTestCase(unittest.TestCase): def setUp(self): self.widget = Widget('The widget') def test_default_widget_size(self): self.assertEqual(self.widget.size(), (50,50), 'incorrect default size') def test_widget_resize(self): self.widget.resize(100,150) self.assertEqual(self.widget.size(), (100,150), 'wrong size after resize') def tearDown(self): self.widget.dispose() if __name__ == '__main__': unittest.main()
Widget이라는 클래스를 unittest로 확인하는 코드입니다.
위 코드에서 test_default_widget_size()와 test_widget_resize()는 모두 Fail될 것입니다.
이걸 실행하면 Fail에 대한 내용이 출력됩니다.
$ python basic_example_1.py -v test_default_widget_size (__main__.WidgetTestCase) ... FAIL test_widget_resize (__main__.WidgetTestCase) ... FAIL ====================================================================== FAIL: test_default_widget_size (__main__.WidgetTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "basic_example_1.py", line 36, in test_default_widget_size self.assertEqual(self.widget.size(), (50,50), 'incorrect default size') AssertionError: Tuples differ: (0, 0) != (50, 50) First differing element 0: 0 50 - (0, 0) + (50, 50) ? + + : incorrect default size ====================================================================== FAIL: test_widget_resize (__main__.WidgetTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "basic_example_1.py", line 40, in test_widget_resize self.assertEqual(self.widget.size(), (100,150), 'wrong size after resize') AssertionError: Tuples differ: (100, 100) != (100, 150) First differing element 1: 100 150 - (100, 100) ? ^ + (100, 150) ? ^ : wrong size after resize ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=2)
unittest의 test method 중 Fail이 확실하거나 예상되어 Skip해야 한다면 @unittest.skip() 등의 decorator을 사용할 수 있다.
@unittest.skip(reason)
해당 테스트에 대해 무조건 skip 합니다. skip 이유를 작성할 수 있습니다.
@unittest.skipIf(condition, reason)
조건이 True라면 skip 합니다.
@unittest.skipUnless(condition, reason)
조건이 True가 아니라면 skip 합니다.
@unittest.expectedFailure
fail이 예상될때 사용합니다. 예상대로 fail이라면 count하지 않습니다.
import unittest class Widget(): def __init__(self, name): self.name = name self.width = 0 self.high = 0 def size(self): return (self.width, self.high) def resize(self, width, high): self.width = width # high는 100을 넘을 수 없다. if high > 100: self.high = 100 else: self.high = high return (self.width, self.high) def dispose(self): self.name = "" self.width = 0 self.high = 0 return True class WidgetTestCase(unittest.TestCase): def setUp(self): self.widget = Widget('The widget') @unittest.skip("demonstrating skipping") def test_default_widget_size(self): self.assertEqual(self.widget.size(), (50,50), 'incorrect default size') @unittest.expectedFailure def test_widget_resize(self): self.widget.resize(100,150) self.assertEqual(self.widget.size(), (100,150), 'wrong size after resize') def tearDown(self): self.widget.dispose() if __name__ == '__main__': unittest.main()
실행하면 skipped로 표시됩니다.
$ python basic_example_1.py -v test_default_widget_size (__main__.WidgetTestCase) ... skipped 'demonstrating skipping' test_widget_resize (__main__.WidgetTestCase) ... expected failure ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK (skipped=1, expected failures=1)
실제 (리턴)값과 기대값을 확인하는 assert method들은 아래 표와 같습니다.
Method |
Checks that |
assertEqual(a, b) |
a == b |
assertNotEqual(a, b) |
a != b |
assertTrue(x) |
bool(x) is True |
assertFalse(x) |
bool(x) is False |
assertIs(a, b) |
a is b |
assertIsNot(a, b) |
a is not b |
assertIsNone(x) |
x is None |
assertIsNotNone(x) |
x is not None |
assertIn(a, b) |
a in b |
assertNotIn(a, b) |
a not in b |
assertIsInstance(a, b) |
isinstance(a, b) |
assertNotIsInstance(a, b) |
not isinstance(a, b) |
assertRaises(exc, fun, *args, **kwds) |
fun(*args, **kwds) raises exc |
assertRaisesRegex(exc, r, fun, *args, **kwds) |
fun(*args, **kwds) raises exc and the message matches regex r |
assertWarns(warn, fun, *args, **kwds) |
fun(*args, **kwds) raises warn |
assertWarnsRegex(warn, r, fun, *args, **kwds) |
fun(*args, **kwds) raises warn and the message matches regex r |
assertLogs(logger, level) |
The with block logs on logger with minimum level |
assertAlmostEqual(a, b) |
round(a-b, 7) == 0 |
assertNotAlmostEqual(a, b) |
round(a-b, 7) != 0 |
assertGreater(a, b) |
a > b |
assertGreaterEqual(a, b) |
a >= b |
assertLess(a, b) |
a < b |
assertLessEqual(a, b) |
a <= b |
assertRegex(s, r) |
r.search(s) |
assertNotRegex(s, r) |
not r.search(s) |
assertCountEqual(a, b) |
a and b have the same elements in the same number, regardless of their order |
assertMultiLineEqual(a, b) |
strings |
assertSequenceEqual(a, b) |
sequences |
assertListEqual(a, b) |
lists |
assertTupleEqual(a, b) |
tuples |
assertSetEqual(a, b) |
sets or frozensets |
assertDictEqual(a, b) |
dicts |
'Python > unittest' 카테고리의 다른 글
unittest 결과를 html report로 뽑아봅시다. (HtmlTestRunner) (0) | 2018.11.30 |
---|---|
unittest assert 함수 살펴보기 (0) | 2018.03.27 |