참고 :
https://docs.python.org/3/library/unittest.html
unittest — Unit testing framework — Python 3.10.7 documentation
unittest — Unit testing framework Source code: Lib/unittest/__init__.py (If you are already familiar with the basic concepts of testing, you might want to skip to the list of assert methods.) The unittest unit testing framework was originally inspired by
docs.python.org
https://academy.realm.io/kr/posts/ios-tdd-test-driven-development/
iOS에서 TDD(Test-Driven Development)하기
저는 92년생 학생으로 I/O라는 회사에서 1년 넘게 iOS를 개발하고 있습니다. 현재 Switcher라는 앱을 개발하고 있습니다. 오늘은 TDD가 뭔지, 왜 해야 하는지와 제 TDD 경험을 말씀드리고 Xcode에서 iOS TDD
academy.realm.io
방법론 4개
test fixture
A test fixture represents the preparation needed to perform one or more tests, and any associated cleanup actions. This may involve, for example, creating temporary or proxy databases, directories, or starting a server process.
test case
A test case is the individual unit of testing. It checks for a specific response to a particular set of inputs. unittest provides a base class, TestCase, which may be used to create new test cases.
test suite
A test suite is a collection of test cases, test suites, or both. It is used to aggregate tests that should be executed together.
test runner
A test runner is a component which orchestrates the execution of tests and provides the outcome to the user. The runner may use a graphical interface, a textual interface, or return a special value to indicate the results of executing the tests.
시험 기구 ( test fixture )
테스트 고정장치는 하나 이상의 테스트와 관련된 청소 작업을 수행하는 데 필요한 준비를 나타냅니다. 예를 들어, 임시 또는 프록시 데이터베이스, 디렉토리를 작성하거나 서버 프로세스를 시작할 수 있습니다.
ex ) setUp(), tearDown(), __init__() 같은 일급함수 개념 ( 테스트를 위한 실행 환경을 테스터 픽스쳐 라고 부름 )
테스트 케이스 ( test case )
테스트 케이스는 테스트의 개별 단위입니다.( 유닛에 대한 testing을 지원한다 라는 의미인듯 ) 특정 입력 집합에 대한 특정 응답을 확인합니다. unittest는 기본 클래스인 TestCase를 제공하며, 이 클래스를 사용하여 새 테스트 케이스를 만들 수 있습니다.
ex ) "unittest.TestCase(methodName='runTest')" , "unittest.IsolatedAsyncioTestCase(methodName='runTest')"
테스트 스위트 ( test suite )
테스트 제품군은 테스트 사례, 테스트 제품군 또는 둘 모두의 모음입니다. 함께 실행해야 하는 테스트를 집계하는 데 사용됩니다.
ex) "unittest.TestSuite(tests=())"
테스트 러너 ( test runner )
테스트 러너는 테스트 실행을 조정하고 사용자에게 결과를 제공하는 구성 요소입니다. 러너는 그래픽 인터페이스, 텍스트 인터페이스를 사용하거나 테스트 실행 결과를 나타내는 특별한 값을 반환할 수 있다.
ex) unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)
PS >
Third-party unittest framework with a lighter-weight syntax for writing tests. For example, assert func(10) == 42.
unittest 보다 훨씬 light 한 테스터 인듯
https://docs.pytest.org/en/7.1.x/
pytest: helps you write better programs — pytest documentation
pytest: helps you write better programs The pytest framework makes it easy to write small, readable tests, and can scale to support complex functional testing for applications and libraries. pytest requires: Python 3.7+ or PyPy3. PyPI package name: pytest
docs.pytest.org
TestCase 의 기본 조건 :
TestCase 인스턴스의 테스트 코드는 완전히 독립적으로 되어 있어야 합니다, 그래야지 이것을 각각 단독으로 실행하거나 다른 여러 테스트 케이스와 함께 임의의 조합으로 실행할 수 있습니다.
여러 기능
1.
setUp()이란 메서드를 작성하여 사전 설정 코드를 밖으로 분리해낼 수 있습니다. 테스트 프레임워크가 1개의 테스트마다 매번 자동으로 이것을 호출합니다. ( setUp() == __enter__() 같은 )
2.
마찬가지로 테스트 메서드가 실행되고 나서 정리하기 위해 tearDown() 메서드를 제공합니다: ( tearDown() == __exit__() 같은 ) // 만약 setUp()이 성공했다면, 테스트가 성공했든 실패했든 상관없이 tearDown()이 실행될 것입니다.
3.
테스트 건너뛰기는 단순히 skip() 데코레이터나 그것의 조건 변형 중 하나를 사용하거나, setUp()이나 테스트 메서드 안에서 TestCase.skipTest()를 호출하거나, SkipTest를 직접 발생시키면 됩니다.
python -m unittest unittest_1.TestStringMethods.test_upper
"python -m unittest 파일명.class명.함수명" 으로 유닛별로 실행가능함.
이걸 이용해서
1. assert 함수에 실패하는 함수를 작성한다. (최대한 심플하게) -> RED CODE
ex)
2. test(assert함수)를 통과하는 함수를 작성한다. -> GREEN CODE
3. GREEN CODE 를 refactory 한다. ( 변수 네이밍 + 중복제거 + 로직을 완성 등등 ) -> REFACTOR
예제_1 :
import unittest
class TestStringMethods(unittest.TestCase):
def setUp(self) -> None:
self.same_function_with_init = 'setUp 멤버변수'
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
print('test_upper')
print(self.same_function_with_init)
return 0
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
print('test_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
print('test_split')
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
print('main start')
unittest.main()
print('main end')
"""
python -m unittest unittest_1.TestStringMethods.test_upper # test_upper 함수만 실행
python -m unittest unittest_1.TestStringMethods.test_isupper unittest_1.TestStringMethods.test_upper
"""
예제_2 :
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
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')
"""
python -m unittest unittest_1.TestStringMethods.test_default_widget_size # test_upper 함수만 실행
"""
예제_3 :
import unittest
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# test code that depends on the external resource
pass
if __name__ == '__main__':
print('main start')
unittest.main()
print('main end')
"""
python -m unittest unittest_1.TestStringMethods.test_nothing # test_upper 함수만 실행
python -m unittest -V unittest_1.TestStringMethods.test_windows_support
"""
unittest.TestCase API 소개
class unittest.TestCase(methodName='runTest')
TestCase 클래스의 인스턴스는 unittest 세계에서 논리적인 테스트 단위에 해당합니다. 이 클래스는 베이스 클래스로 사용되며, 특정 테스트는 구상 클래스로 구현됩니다. 이 클래스는 테스트 실행자가 테스트를 실행할 수 있는 인터페이스를 구현하고 테스트 코드가 검사하고 다양한 실패를 보고할 수 있는 메서드를 구현합니다.
TestCase의 각 인스턴스는 하나의 베이스 메서드: methodName이 지정하는 이름의 메서드를 실행할 것입니다. 대부분의 TestCase 사용에서, 당신은 methodName을 바꾸거나 기본 runTest() 메서드를 재구현하지 않을 것입니다.
버전 3.2에서 변경: methodName 제공 없이도 TestCase를 성공적으로 인스턴스화할 수 있습니다. 이것은 대화형 인터프리터에서 TestCase로 쉽게 실험을 할 수 있게 합니다.
TestCase 인스턴스는 3가지 메서드 그룹을 제공합니다: 한 그룹은 테스트를 실행하는 데 사용되고, 다른 한 그룹은 조건을 확인하고 실패를 보고하는 테스트 구현으로 사용되고, 몇몇 조회 메서드는 테스트 자체에 관한 정보를 수집할 수 있게 해줍니다.
첫 번째 그룹(테스트 실행) 안에 메서드는:
setUp()
테스트 픽스쳐를 준비하기 위해 호출되는 메서드입니다. 이 메서드는 테스트 메서드를 호출하기 바로 직전에 호출됩니다; AssertionError 또는 SkipTest이외의 이 메서드에서 발생한 모든 예외는 테스트 실패가 아닌 오류로 간주합니다. 기본 구현은 아무것도 하지 않습니다.
tearDown()
테스트 메서드가 불리고 결과가 기록되고 나서 바로 다음에 호출되는 메서드입니다. 테스트 메서드가 예외를 발생했더라도 이 메서드는 불립니다, 따라서 서브 클래스의 구현은 내부 상태를 확인하는 데 특별히 주의를 기울여야 합니다. AssertionError 또는 SkipTest이외의 이 메서드에서 발생하는 모든 예외는 테스트 실패가 아닌 오류로 간주합니다(따라서 보고된 오류의 총 숫자가 증가합니다). 이 메서드는 테스트 메서드의 결과물에 영향받지 않고 setUp()이 성공했을 때만 불립니다. 기본 구현은 아무것도 하지 않습니다.
setUpClass()
개별 클래스의 테스트들이 실행되기 전에 불리는 클래스 메서드입니다. setUpClass는 클래스만 인자로 받아 호출되고 classmethod()로 데코레이트해야 합니다:
@classmethod
def setUpClass(cls):
...
더 자세한 것은 클래스와 모듈 픽스쳐를 보십시오.
버전 3.2에 추가.
tearDownClass()
개별 클래스의 테스트들이 실행되고 난 뒤에 불리는 클래스 메서드입니다. tearDownClass는 클래스만 인자로 받아 호출되고 classmethod()로 데코레이트해야 합니다:
@classmethod
def tearDownClass(cls):
...
더 자세한 것은 클래스와 모듈 픽스쳐를 보십시오.
버전 3.2에 추가.
run(result=None)
테스트를 실행하고, result 인자로 전달된 TestResult에 결과를 수집합니다. 만약 result 인자가 전달 안 되거나 None이라면 임시 결과 객체를 (defaultTestResult() 메서드를 불러서) 생성하여 사용합니다. run() 호출자에게 결과 객체를 반환합니다.
단순히 TestCase 인스턴스를 호출하는 것으로 같은 효과를 볼 수 있습니다.
버전 3.3에서 변경: 기존 버전의 run은 결과를 반환하지 않았습니다. 인스턴스 호출 또한 그렇지 않았습니다.
skipTest(reason)
테스트 메서드나 setUp()에서 이것을 호출하면 현재 테스트를 건너뜁니다. 자세한 정보는 테스트 건너뛰기와 예상된 실패를 보십시오.
버전 3.1에 추가.
subTest(msg=None, **params)
둘러싼 코드 블록을 부분 테스트로서 실행하는 컨텍스트 관리자를 반환합니다. msg 및 params는 선택 사항이며 부분 테스트가 실패 할 때마다 표시되는 임의의 값으로 당신이 명확하게 알아보게 해줍니다.
테스트 케이스는 여러 개의 부분 테스트 선언을 포함할 수 있고, 그것들은 자유롭게 중첩될 수 있습니다.
자세한 정보는 부분 테스트(subtest)를 사용하여 테스트 반복 구별 짓기를 보십시오.
버전 3.4에 추가.
debug()
결과를 수집하지 않고 테스트를 실행합니다. 이것은 테스트에서 발생한 예외가 호출자로 전파될 수 있게 해서, 디버거 환경에서 테스트를 실행할 때 사용될 수 있습니다.
TestCase 클래스는 값을 검사하고 실패를 보고하기 위해 몇 개의 assert 메서드를 제공합니다. 다음 표는 보통 많이 사용되는 메서드들입니다(더 많은 assert 메서드는 표 아래를 보십시오):
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 | 3.1 |
assertIsNot(a, b) | a is not b | 3.1 |
assertIsNone(x) | x is None | 3.1 |
assertIsNotNone(x) | x is not None | 3.1 |
assertIn(a, b) | a in b | 3.1 |
assertNotIn(a, b) | a not in b | 3.1 |
assertIsInstance(a, b) | isinstance(a, b) | 3.2 |
assertNotIsInstance(a, b) | not isinstance(a, b) | 3.2 |
모든 assert 메서드는 msg 인자를 받을 수 있습니다, 만약 그것이 전달된다면 실패 시 에러 메시지로 사용됩니다(longMessage 도 참고하십시오). assertRaises(), assertRaisesRegex(), assertWarns(), assertWarnsRegex()는 컨텍스트 관리자로서 사용될 때만 그들에게 msg 키워드 인자를 전달할 수 있다는 점을 주의하십시오.
assertEqual(first, second, msg=None)
first와 second가 같은지 테스트합니다. 비교한 값이 같지 않으면 테스트는 실패할 것입니다.
추가로, 만약 first와 second가 정확히 같은 형(type)이고 list, tuple, dict, set, frozenset, str 이거나 addTypeEqualityFunc()에 등록된 서브 클래스 형 중 하나일 경우 더 유용한 기본 에러 메시지를 생성하기 위해 형-특화(type-specific) 동등성 함수가 불릴 것입니다(형-특화 메서드 목록을 참고하십시오).
버전 3.1에서 변경: 형-특화 동등성 함수가 자동으로 불리도록 추가
버전 3.2에서 변경: 문자열 비교를 위해서 assertMultiLineEqual()를 기본 형-특화 동등성 함수에 추가
assertNotEqual(first, second, msg=None)
first와 second가 같지 않은지 테스트합니다, 비교한 값이 같으면 테스트는 실패할 것입니다.
assertTrue(expr, msg=None)assertFalse(expr, msg=None)
expr이 참(또는 거짓)인지 테스트합니다.
이것은 bool(expr) is True와 동등하고 expr is True와 동등하지 않다는 것에 주의하십시오(후자를 위해선 assertIs(expr, True)를 사용하십시오). 더 구체적인 메서드를 사용할 수 있을 때는 이 메서드를 지양해야 합니다(예, assertTrue(a == b) 대신에 assertEqual(a, b)), 왜냐하면 실패의 경우에 구체적인 메서드가 더 나은 에러 메시지를 제공하기 때문입니다.
assertIs(first, second, msg=None)assertIsNot(first, second, msg=None)
first와 second가 같은 객체인지 (혹은 아닌지) 테스트합니다.
버전 3.1에 추가.
assertIsNone(expr, msg=None)assertIsNotNone(expr, msg=None)
expr이 None 인지(아닌지) 테스트합니다.
버전 3.1에 추가.
assertIn(member, container, msg=None)assertNotIn(member, container, msg=None)
member가 container 안에 있는지(아닌지) 테스트합니다.
버전 3.1에 추가.
assertIsInstance(obj, cls, msg=None)assertNotIsInstance(obj, cls, msg=None)
obj가 cls(isinstance()가 지원하는 것처럼 클래스 또는 클래스의 튜플)의 인스턴스인지(아닌지) 테스트합니다. 정확한 형 검사를 위해서는 assertIs(type(obj), cls)를 사용하십시오.
버전 3.2에 추가.
다음의 메서드를 사용하여 예외, 경고, 로그 메시지의 발생을 검사할 수 있습니다:
assertRaises(exc, fun, *args, **kwds) | fun(*args, **kwds)가 exc를 발생 | |
assertRaisesRegex(exc, r, fun, *args, **kwds) | fun(*args, **kwds)가 exc를 발생하고 메시지가 정규식 r에 일치 | 3.1 |
assertWarns(warn, fun, *args, **kwds) | fun(*args, **kwds)가 warn을 발생 | 3.2 |
assertWarnsRegex(warn, r, fun, *args, **kwds) | fun(*args, **kwds)가 warn을 발생하고 메시지가 정규식 r에 일치 | 3.2 |
assertLogs(logger, level) | with 블록이 최소 level로 logger에 로그를 남김 | 3.4 |
assertNoLogs(logger, level) | The with block does not log onlogger with minimum level | 3.10 |
assertRaises(exception, callable, *args, **kwds)assertRaises(exception, *, msg=None)
assertRaises()에 전달된 어떤 위치 또는 키워드 인자와 함께 callable이 호출되었을 때 예외가 발생하는지 테스트합니다. exception이 발생하면 테스트를 통과하고, 다른 예외가 발생하면 에러이고, 아무 예외도 발생하지 않으면 실패입니다. 여러 예외 모음을 잡기 위해서 예외 클래스를 포함한 튜플을 exception으로 전달해도 좋습니다.
만약 선택적인 msg와 함께 오직 exception 인자만 전달된다면, 테스트할 코드를 함수가 아닌 인라인으로 작성할 수 있도록 컨텍스트 관리자를 반환합니다:
with self.assertRaises(SomeException):
do_something()
컨텍스트 관리자로 사용되면, assertRaises()는 추가적인 키워드 인자인 msg를 받을 수 있습니다.
컨텍스트 관리자는 잡은 예외 객체를 exception 어트리뷰트에 저장할 것입니다. 이것은 발생한 예외에 대해서 추가적인 검사를 수행하려는 경우에 유용할 수 있습니다:
with self.assertRaises(SomeException) as cm:
do_something()
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
버전 3.1에서 변경: assertRaises()를 컨텍스트 관리자로 사용할 수 있도록 기능 추가.
버전 3.2에서 변경: exception 어트리뷰트 추가.
버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.
assertRaisesRegex(exception, regex, callable, *args, **kwds)assertRaisesRegex(exception, regex, *, msg=None)
assertRaises()와 비슷하지만 발생한 예외의 문자열 표현이 regex에 일치하는지 테스트합니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다. 예:
self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
int, 'XYZ')
또는:
with self.assertRaisesRegex(ValueError, 'literal'):
int('XYZ')
버전 3.1에 추가: assertRaisesRegexp 라는 이름으로 추가되었습니다.
버전 3.2에서 변경: assertRaisesRegex()으로 이름 변경.
버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.
assertWarns(warning, callable, *args, **kwds)assertWarns(warning, *, msg=None)
assertWarns()에 전달된 어떤 위치 또는 키워드 인자와 함께 callable이 호출되었을 때 경고(warning)가 발생하는지 테스트합니다. warning이 발생하면 테스트를 통과하고, 그렇지 않으면 실패입니다. 예외가 발생하면 에러입니다. 여러 경고 모음을 잡기 위해서 경고 클래스를 포함한 튜플을 warnings로 전달해도 좋습니다.
만약 선택적인 msg와 함께 오직 warning 인자만 전달된다면, 테스트할 코드를 함수가 아닌 인라인으로 작성할 수 있도록 컨텍스트 관리자를 반환합니다:
with self.assertWarns(SomeWarning):
do_something()
컨텍스트 관리자로 사용되면, assertWarns()는 추가적인 키워드 인자인 msg를 받을 수 있습니다.
컨텍스트 관리자는 잡은 경고 객체를 warning 어트리뷰트에 저장하고, 경고를 발생한 소스코드 줄을 filename과 lineno에 저장할 것입니다. 이것은 발생한 경고에 대해서 추가적인 검사를 수행하려는 경우에 유용할 수 있습니다:
with self.assertWarns(SomeWarning) as cm:
do_something()
self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)
이 메서드는 호출될 때 적용될 경고 필터와 관계없이 작동합니다.
버전 3.2에 추가.
버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.
assertWarnsRegex(warning, regex, callable, *args, **kwds)assertWarnsRegex(warning, regex, *, msg=None)
assertWarns()와 비슷하지만 발생한 경고의 메시지가 regex에 일치하는지 테스트합니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다. 예:
self.assertWarnsRegex(DeprecationWarning,
r'legacy_function\(\) is deprecated',
legacy_function, 'XYZ')
또는:
with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
frobnicate('/etc/passwd')
버전 3.2에 추가.
버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.
assertLogs(logger=None, level=None)
최소한 level로 logger나 그 자식들에 최소한 1개의 메시지가 기록되는지 테스트하는 컨텍스트 관리자입니다.
logger가 주어졌다면, logging.Logger 객체이거나 로거의 이름인 str이어야 합니다. 기본값은 전파하지 않는 하위 로거에 의해 차단되지 않은 모든 메시지를 잡을 루트 로거입니다.
level이 주어졌다면, 로그 수준의 숫자 값이거나 그에 대응하는 문자열이어야 합니다(예를 들어 "ERROR"이거나 logging.ERROR). 기본값은 logging.INFO입니다.
만약 with 블록 안에서 logger와 level 조건을 만족하는 최소한 1개의 메시지가 나왔다면 테스트는 성공하고, 그렇지 않으면 실패합니다.
컨텍스트 관리자에 의해 반환되는 객체는 조건에 일치하는 로그 메시지를 추적하기 위한 기록 도우미입니다. 이것은 2개의 어트리뷰트를 가지고 있습니다:
records
조건에 일치하는 메시지의 logging.LogRecord 객체 목록.
output
조건에 일치하는 메시지의 포맷 출력인 str 객체 목록.
예:
with self.assertLogs('foo', level='INFO') as cm:
logging.getLogger('foo').info('first message')
logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
'ERROR:foo.bar:second message'])
버전 3.4에 추가.
assertNoLogs(logger=None, level=None)
A context manager to test that no messages are logged on the logger or one of its children, with at least the given level.
If given, logger should be a logging.Logger object or a str giving the name of a logger. The default is the root logger, which will catch all messages.
level이 주어졌다면, 로그 수준의 숫자 값이거나 그에 대응하는 문자열이어야 합니다(예를 들어 "ERROR"이거나 logging.ERROR). 기본값은 logging.INFO입니다.
Unlike assertLogs(), nothing will be returned by the context manager.
버전 3.10에 추가.
더 구체적인 검사를 수행하기 위한 또 다른 메서드가 있습니다, 아래와 같이:
assertAlmostEqual(a, b) | round(a-b, 7) == 0 | |
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 | |
assertGreater(a, b) | a > b | 3.1 |
assertGreaterEqual(a, b) | a >= b | 3.1 |
assertLess(a, b) | a < b | 3.1 |
assertLessEqual(a, b) | a <= b | 3.1 |
assertRegex(s, r) | r.search(s) | 3.1 |
assertNotRegex(s, r) | not r.search(s) | 3.2 |
assertCountEqual(a, b) | 순서와 상관없이 a와 b가 같은 개수의 같은 요소를 가졌는지. | 3.2 |
assertAlmostEqual(first, second, places=7, msg=None, delta=None)assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)
first와 second가 근사하게 같은지(또는 근사하게 같지 않은지) 테스트합니다. 이는 값 차이를 계산하고, 주어진 소수 자릿(places)수(기본값 7)로 반올림한 뒤, 0과 비교하는 것으로 이루어집니다. 이 메서드는 값을 유효 숫자 자릿수(significant digits)가 아닌 주어진 소수 자릿수(decimal places)(즉, round() 함수와 같이)로 반올림합니다.
만약 places 대신에 delta가 주어진다면 first와 second의 값 차이는 반드시 delta보다 작거나 같아야(또는 커야) 합니다.
delta와 places가 동시에 주어지면 TypeError가 발생합니다.
버전 3.2에서 변경: assertAlmostEqual()은 같다고 비교되는 거의 동등한 객체를 자동으로 고려합니다. assertNotAlmostEqual()은 객체가 같다고 비교되면 자동으로 실패합니다. delta 키워드 인자를 추가.
assertGreater(first, second, msg=None)assertGreaterEqual(first, second, msg=None)assertLess(first, second, msg=None)assertLessEqual(first, second, msg=None)
first를 second와 비교해서 각각 메서드 이름에 해당하는 >, >=, <, <= 인지 테스트합니다. 그렇지 않으면 테스트는 실패합니다:
>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"
버전 3.1에 추가.
assertRegex(text, regex, msg=None)assertNotRegex(text, regex, msg=None)
regex 검색이 text에 일치하는지(아닌지) 테스트합니다. 실패의 경우, 에러 메시지는 패턴과 text(또는 패턴과 예상과 달리 일치한 text의 부분)를 포함할 것입니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다.
버전 3.1에 추가: assertRegexpMatches 라는 이름으로 추가되었습니다.
버전 3.2에서 변경: assertRegexpMatches() 메서드가 assertRegex()로 이름 변경되었습니다.
버전 3.2에 추가: assertNotRegex().
버전 3.5에 추가: assertNotRegexpMatches이름은 assertNotRegex()의 폐지된 에일리어스입니다.
assertCountEqual(first, second, msg=None)
first 시퀀스가 순서에 상관없이 second와 같은 요소를 포함하는지 테스트합니다. 그렇지 않은 경우, 시퀀스들의 차이를 나열한 에러 메시지가 생성됩니다.
first와 second를 비교할 때 중복된 요소는 무시하지 않습니다. 두 개의 시퀀스에 각 요소가 같은 수 만큼 있는 것을 확인합니다. assertEqual(Counter(list(first)), Counter(list(second)))와 같지만 해시 불가능한(unhashable) 시퀀스에도 작동합니다.
버전 3.2에 추가.
assertEqual() 메서드는 같은 형의 객체의 동등성 검사를 다른 형-특화 메서드에게로 보냅니다. 이러한 메서드들은 대부분의 내장 형에 대해서 이미 구현되어 있지만, addTypeEqualityFunc()을 사용하여 새로운 메서드를 등록하는 것도 가능합니다:
addTypeEqualityFunc(typeobj, function)
정확히 같은 (서브 클래스가 아닌) typeobj 형의 두 객체가 같은지 비교 검사하기 위해 assertEqual()한테 불리는 형-특화 메서드를 등록합니다. function은 반드시 2개의 위치 인자를 받아야 하고 assertEqual()이 그러한 것처럼 msg=None 키워드 인자를 세 번째로 받아야 합니다. 이것은 처음 2개의 매개변수가 같지 않은 것이 확인될 경우 self.failureException(msg)을 반드시 발생시켜야 합니다 – 에러 메시지에 유용한 정보를 제공하고 비동등성을 자세히 설명할 수 있을 것입니다.
버전 3.1에 추가.
assertEqual()에서 자동으로 사용하는 형-특화 메서드 목록은 다음 표에 정리되어 있습니다. 보통은 이 메서드를 직접 부를 필요가 없다는 것을 기억하십시오.
assertMultiLineEqual(a, b) | 문자열 | 3.1 |
assertSequenceEqual(a, b) | 시퀀스 | 3.1 |
assertListEqual(a, b) | 리스트 | 3.1 |
assertTupleEqual(a, b) | 튜플 | 3.1 |
assertSetEqual(a, b) | 집합 또는 불변 집합 | 3.1 |
assertDictEqual(a, b) | 딕셔너리 | 3.1 |
assertMultiLineEqual(first, second, msg=None)
여러 줄 문자열인 first와 second가 같은지 테스트합니다. 같지 않을 경우 에러 메시지에 다른 부분이 강조된 두 문자열의 차이가 포함됩니다. 이 메서드는 assertEqual()에서 문자열을 비교할 때 기본적으로 사용됩니다.
버전 3.1에 추가.
assertSequenceEqual(first, second, msg=None, seq_type=None)
2개의 시퀀스가 같은지 테스트합니다. seq_type이 전달된 경우, first와 second 둘 다 seq_type의 인스턴스이어야 하고 그렇지 않은 경우 실패가 발생합니다. 시퀀스가 다른 경우, 에러 메시지는 2개 사이의 차이점을 보여주게 됩니다.
이 메서드는 assertEqual()에서 직접 호출되진 않지만, assertListEqual()와 assertTupleEqual()을 구현할 때 사용됩니다.
버전 3.1에 추가.
assertListEqual(first, second, msg=None)assertTupleEqual(first, second, msg=None)
2개의 리스트나 튜플이 같은지 테스트합니다. 만약 같지 않다면 에러 메시지는 2개 사이의 차이점만 보여주게 됩니다. 매개변수 중 하나가 잘못된 형인 경우 에러가 발생합니다. 이 메서드는 assertEqual()에서 리스트와 튜플을 비교할 때 기본적으로 사용됩니다.
버전 3.1에 추가.
assertSetEqual(first, second, msg=None)
2개의 집합이 같은지 테스트합니다. 같지 않은 경우 에러 메시지는 집합 사이의 차이를 나열하게 됩니다. 이 메서드는 assertEqual()에서 집합이나 불변 집합을 비교할 때 기본적으로 사용됩니다.
first와 second 중 하나가 set.difference() 메서드를 가지고 있지 않으면 실패합니다.
버전 3.1에 추가.
assertDictEqual(first, second, msg=None)
2개의 딕셔너리가 같은지 테스트합니다. 같지 않은 경우 에러 메시지는 딕셔너리 사이의 차이를 보여주게 됩니다. 이 메서드는 assertEqual()에서 딕셔너리를 비교할 때 기본적으로 사용될 것입니다.
버전 3.1에 추가.
마지막으로 TestCase가 다음의 메서드와 어트리뷰트를 제공합니다:
fail(msg=None)
무조건 테스트 실패 신호를 보냅니다, 에러 메시지를 위해 msg나 None을 전달합니다.
failureException
이 클래스 어트리뷰트는 테스트 메서드에서 발생한 예외를 줍니다. 만약 테스트 프레임워크가 추가 정보를 전달하기 위해 특수한 예외를 사용할 필요가 있다면, 프레임워크와 “공정하게 행동하기” 위해서 이 예외를 서브 클래스해야 합니다. 이 어트리뷰트의 초깃값은 AssertionError 입니다.
longMessage
이 클래스 어트리뷰트는 실패한 assertXYY 호출에 msg 인자로 전달된 사용자 정의 실패 메시지가 어떻게 동작하는지를 결정합니다. True가 기본값입니다. 이 경우, 사용자 정의 메시지가 표준 실패 메시지 끝에 추가됩니다. False로 설정할 경우 사용자 정의 메시지가 표준 메시지를 대체합니다.
이 클래스 설정은 인스턴스 어트리뷰트를 설정하여 개별 테스트 메서드에 의해 재정의될 수 있습니다, assert 메서드를 호출하기 전에 self.longMessage를 True 또는 False로 설정하는 것입니다.
이 클래스 설정은 각 테스트 호출 전에 재설정됩니다.
버전 3.1에 추가.
maxDiff
이 어트리뷰트는 실패 시 diff를 보고하는 assert 메서드의 최대 diff 출력 길이를 설정합니다. 기본값은 80*8 문자입니다. 이 어트리뷰트에 영향을 받는 assert 메서드는 assertSequenceEqual()(이것에 위임하는 모든 시퀀스 비교 메서드를 포함), assertDictEqual(), assertMultiLineEqual() 입니다.
maxDiff를 None으로 설정하면 diff의 최대 길이 제한이 없어지는 것을 뜻합니다.
버전 3.2에 추가.
테스트 프레임워크는 테스트에 관한 정보를 수집하기 위해 다음의 메서드를 사용할 수 있습니다:
countTestCases()
이 테스트 객체에 해당하는 테스트 개수를 반환합니다. TestCase 인스턴스에 대해서는 이것은 항상 1입니다.
defaultTestResult()
이 테스트 케이스 클래스를 위해서 사용되는 테스트 결과 클래스의 인스턴스를 반환합니다(run() 메서드에 다른 결과 인스턴스가 전달되지 않은 경우에).
TestCase 인스턴스에 대해서는 이것은 항상 TestResult의 인스턴스입니다; TestCase의 서브 클래스는 이것을 필요에 따라 재정의해야 합니다.
id()
특정 테스트 케이스를 식별하는 문자열을 반환합니다. 이것은 보통 모듈과 클래스 이름을 포함한 테스트 메서드의 완전한 이름(full name)입니다.
shortDescription()
테스트의 설명을 반환하거나 설명이 제공되지 않았으면 None을 반환합니다. 이 메서드의 기본 구현은 가능하다면 테스트 메서드의 독스트링의 첫 번째 줄을 반환하고 그렇지 않으면 None을 반환합니다.
버전 3.1에서 변경: 3.1 버전에서 docstring이 있는 경우에도 짧은 설명에 테스트 이름을 추가하도록 변경되었습니다. 이것은 unittest 확장과 호환성 문제를 일으켰고 테스트 이름 추가는 파이썬 3.2에서 TextTestResult로 옮겨졌습니다.
addCleanup(function, /, *args, **kwargs)
테스트 중에 사용된 자원을 정리하기 위해 tearDown() 이후에 불리는 함수를 추가합니다. 함수들은 추가된 순서의 반대 순서대로 불리게 됩니다(LIFO). 함수가 추가될 때 addCleanup()에 같이 전달된 위치 인자나 키워드 인자와 함께 호출됩니다.
만약 setUp()이 실패한다면, 즉 tearDown()이 불리지 않더라도, 정리 함수들은 여전히 불리게 될 것입니다.
버전 3.1에 추가.
doCleanups()
이 메서드는 tearDown() 이후나, setUp()이 예외를 발생시키면 setUp()이후에 조건 없이 호출됩니다.
addCleanup()에서 추가된 모든 정리 함수들을 호출하는 책임이 있습니다. 만약 정리 함수를 tearDown() 이전에 불러야 할 필요가 있다면 doCleanups()를 직접 부를 수 있습니다.
doCleanups()는 한 번에 하나씩 정리 함수 스택에서 메서드를 꺼내기 때문에 언제든지 호출될 수 있습니다.
버전 3.1에 추가.
classmethod addClassCleanup(function, /, *args, **kwargs)
테스트 클래스 중에 사용된 자원을 정리하기 위해 tearDownClass() 이후에 불리는 함수를 추가합니다. 함수들은 추가된 순서의 반대 순서대로 불리게 됩니다(LIFO). 함수가 추가될 때 addClassCleanup()에 같이 전달된 위치 인자나 키워드 인자와 함께 호출됩니다.
만약 setUpClass()가 실패한다면, 즉 tearDownClass()가 불리지 않더라도, 정리 함수들은 여전히 불리게 될 것입니다.
버전 3.8에 추가.
classmethod doClassCleanups()
이 메서드는 tearDownClass() 이후나, setUpClass()이 예외를 발생시키면 setUpClass()이후에 조건 없이 호출됩니다.
addClassCleanup()에서 추가된 모든 정리 함수들을 호출하는 책임이 있습니다. 만약 정리 함수를 tearDownClass() 이전에 호출해야 할 필요가 있다면 doClassCleanups()를 직접 호출할 수 있습니다.
doClassCleanups()는 한 번에 하나씩 정리 함수 스택에서 메서드를 꺼내기 때문에 언제든지 호출될 수 있습니다.
버전 3.8에 추가.
unittest.IsolatedAsyncioTestCase API 소개
이 클래스는 TestCase와 유사한 API를 제공하며 코루틴을 테스트 함수로 받아들입니다.
버전 3.8에 추가.
coroutine asyncSetUp()
테스트 픽스쳐를 준비하기 위해 호출되는 메서드입니다. 이 메서드는 setUp()이후에 호출됩니다. 이 메서드는 테스트 메서드를 호출하기 바로 직전에 호출됩니다; AssertionError 또는 SkipTest이외의 이 메서드에서 발생한 모든 예외는 테스트 실패가 아닌 오류로 간주합니다. 기본 구현은 아무것도 하지 않습니다.
coroutine asyncTearDown()
테스트 메서드가 불리고 결과가 기록되고 나서 바로 다음에 호출되는 메서드입니다. 이 메서드는 tearDown()전에 호출됩니다. 테스트 메서드가 예외를 발생했더라도 이 메서드는 불립니다, 따라서 서브 클래스의 구현은 내부 상태를 확인하는 데 특별히 주의를 기울여야 합니다. AssertionError 또는 SkipTest이외의 이 메서드에서 발생하는 모든 예외는 테스트 실패가 아닌 오류로 간주합니다(따라서 보고된 오류의 총 숫자가 증가합니다). 이 메서드는 테스트 메서드의 결과물에 영향받지 않고 asyncSetUp()이 성공했을 때만 불립니다. 기본 구현은 아무것도 하지 않습니다.
addAsyncCleanup(function, /, *args, **kwargs)
이 메서드는 정리 함수로 사용할 수 있는 코루틴을 받아들입니다.
run(result=None)
테스트를 실행하기 위한 새 이벤트 루프를 설정하고, result 인자로 전달된 TestResult에 결과를 수집합니다. 만약 result 인자가 전달 안 되거나 None이라면 임시 결과 객체를 (defaultTestResult() 메서드를 불러서) 생성하여 사용합니다. run() 호출자에게 결과 객체를 반환합니다. 테스트의 끝에서 이벤트 루프의 모든 태스크는 취소됩니다.
순서를 보여주는 예:
from unittest import IsolatedAsyncioTestCase
events = []
class Test(IsolatedAsyncioTestCase):
def setUp(self):
events.append("setUp")
async def asyncSetUp(self):
self._async_connection = await AsyncConnection()
events.append("asyncSetUp")
async def test_response(self):
events.append("test_response")
response = await self._async_connection.get("https://example.com")
self.assertEqual(response.status_code, 200)
self.addAsyncCleanup(self.on_cleanup)
def tearDown(self):
events.append("tearDown")
async def asyncTearDown(self):
await self._async_connection.close()
events.append("asyncTearDown")
async def on_cleanup(self):
events.append("cleanup")
if __name__ == "__main__":
unittest.main()
테스트를 실행한 후, events에는 ["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]가 포함됩니다.
class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
이 클래스는 테스트 실행자가 테스트를 수행할 수 있게 TestCase 인터페이스 일부를 구현합니다, 하지만 테스트 코드가 검사하거나 에러를 보고하는 데 사용하는 메서드를 제공하지는 않습니다. 이것은 레거시 테스트 코드를 사용하여 테스트 케이스를 생성할 때 사용할 수 있습니다, 이것은 레거시 테스트 코드가 unittest-기반 테스트 프레임워크에 통합될 수 있게 해줍니다.
폐지된 에일리어스
역사적인 이유로 인해 TestCase 메서드의 일부는 지금은 폐지된 에일리어스를 1개 또는 그 이상 가졌습니다. 다음 표는 폐지된 에일리어스과 그에 맞는 올바른 이름을 나열합니다:
메서드 이름폐지된 에일리어스폐지된 에일리어스
assertEqual() failUnlessEqual assertEquals assertNotEqual() failIfEqual assertNotEquals assertTrue() failUnless assert_ assertFalse() failIf assertRaises() failUnlessRaises assertAlmostEqual() failUnlessAlmostEqual assertAlmostEquals assertNotAlmostEqual() failIfAlmostEqual assertNotAlmostEquals assertRegex() assertRegexpMatches assertNotRegex() assertNotRegexpMatches assertRaisesRegex() assertRaisesRegexp 버전 3.1부터 폐지: 두 번째 열에 나열된 fail* 에일리어스는 폐지되었습니다.
버전 3.2부터 폐지: 세 번째 열에 나열된 assert* 에일리어스는 폐지되었습니다.
버전 3.2부터 폐지: assertRegexpMatches와 assertRaisesRegexp는 assertRegex()와 assertRaisesRegex()로 이름이 변경되었습니다.
버전 3.5부터 폐지: assertNotRegexpMatches 이름은 폐지되고 assertNotRegex()으로 대체합니다.
'언어 정리 > python_lib,일급함수' 카테고리의 다른 글
json_to_X, X_to_json (0) | 2022.10.25 |
---|---|
with 함수 ( __enter__, __exit__ ) (0) | 2022.09.19 |
import contextvars 설명 (2) | 2022.08.28 |
functools.partial() 정리 (0) | 2022.08.17 |
PIL , 출력문 저장 lib(write,print,sys.out) (0) | 2022.08.04 |
댓글