Python에서는 대표적으로 unittest
와 pytest
라이브러리 테스트목적으로 이용됩니다. django에서는 기본적으로 unittest
를 이용하므로 unittest를 알아보겠습니다.
import unittest
# django에서는 이 모듈의 서브클래스인 django.test.Testcase가 존재합니다.
# 순수 django 목적이라면 위를 대신 이용하는게 좋겠습니다.
class TestClass(unittest.TestCase):
def setUp(self):
self.fixture = {'testkey':'testvalue'}
def test_func(self):
func_result = func(self.fixture['testkey'])
self.assertEqual(self.fixture['testkey'], 'normal result')
def tearDown(self):
self.fixture = None
테스트는 다음과 같은 과정으로 이루어집니다.
테스트는 독립적이어야 하므로 매 테스트에 초기 설정이 필요합니다. 이 단계가 초기 설정이 이루어지는 단계입니다. 이 초기 설정 혹은 데이터를 fixture라고 부릅니다. 모든 테스트 전에 실행됩니다.
실제 테스트가 진행되는 단계입니다. test_로 메소드 이름이 시작되어야 합니다. self.AssertTrue, self.AsserEqual, self.AsserRaises등 사전 정의된 테스트 메서드를 사용하여 테스트를 진행합니다. 사전 정의된 테스트 함수들은 여기에서 확인할 수 있습니다.
사전 정의된 fixture를 초기화하는 단계입니다. 모든 테스트 후에 실행됩니다.
기존의 assert 기반 테스트를 재사용할 수 있습니다. 그렇게 권장되는 방법은 아닙니다.
def test_function(value):
assert(value == 1, 'Test Message')
'''...'''
unittest.FUnctionTestCase(test_function,
setUp = setupfunc,
tearDown = teardownfunc)
두 가지 방법을 이용해 테스트를 스킵할 수 있습니다.
setUp, test 메소드 내부에서 skipTest를 호출하거나 skip 데코레이터를 활용하면 됩니다. skip 데코레이터는 skip, skipIf, skipUnless 세 종류가 있습니다.
def test_to_skip(self):
self.skipTest()
@unittest.skip
def test_to_skip2(self):
pass
@unittest.skipIf(sys.version_info >= (3, 8, 5)
def test_to_skip3(self):
pass
ExpectedFailure 데코레이터를 이용해 실패 혹은 에러를 성공으로, 성공을 실패로 처리할 수 있습니다.
@unittest.expectedFailure
def test_to_fail(self):
pass
with 구문을 통해 subTest 컨텍스트에 진입하여 서브테스트를 진행할 수 있습니다.
def test_func(self):
for i in range(6):
with self.subTest(i = i):
self.assertEqual(i % 2, 0)
이 외에도 여러 더 복잡한 활용이 있습니다. 공식문서를 참조하시면 좋을 것 같습니다.
django에서는 명령어를 통해 테스트를 실행할 수 있습니다. 테스트 대상으로는 테스트케이스 하나, 메서드 하나, 패키지 전부 가능합니다.
python manage.py test {테스트 대상}
또한 장고에서는 기본적으로 테스트 진행 시 임시 DB를 만들어 진행하고 기본적으로 테스트가 끝나면 삭제합니다. --keepdb
옵션을 통해 테스트가 끝나더라도 테스트 DB를 확인할 수 있습니다. 또한 Client 클래스를 통해 실제 경로의 뷰와 매치해서 테스트를 진행할 수 있습니다. django의 TestCase는 unittest의 TestCase를 상속하므로 기본적으로 같은 방법으로 진행할 수 있습니다.
from django.test import TestCase, Client
class SimpleTest(TestCase):
def setUp(self):
self.client = Client()
def test_view(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
self.assertTrue(response.has_header('User-Agent')
그 외 심화된 django의 test는 다음 링크들을 참조하면 좋을 것 같습니다.
https://docs.djangoproject.com/en/3.1/topics/testing/overview
https://docs.djangoproject.com/en/3.1/topics/testing/tools/
https://docs.djangoproject.com/en/3.1/topics/testing/advanced/
https://velog.io/@hj8853/Django-Unit-Test
https://docs.python.org/ko/3/library/unittest.html#assert-methods
https://www.bangseongbeom.com/unittest-vs-pytest.html
https://docs.djangoproject.com/en/3.1/topics/testing/overview
https://docs.djangoproject.com/en/3.1/topics/testing/tools/
https://docs.djangoproject.com/en/3.1/topics/testing/advanced/