Django에서 Test하기

maintain·2020년 12월 13일
0

Python에서는 대표적으로 unittestpytest라이브러리 테스트목적으로 이용됩니다. django에서는 기본적으로 unittest를 이용하므로 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

테스트는 다음과 같은 과정으로 이루어집니다.

1. setUp

테스트는 독립적이어야 하므로 매 테스트에 초기 설정이 필요합니다. 이 단계가 초기 설정이 이루어지는 단계입니다. 이 초기 설정 혹은 데이터를 fixture라고 부릅니다. 모든 테스트 전에 실행됩니다.

2. test

실제 테스트가 진행되는 단계입니다. test_로 메소드 이름이 시작되어야 합니다. self.AssertTrue, self.AsserEqual, self.AsserRaises등 사전 정의된 테스트 메서드를 사용하여 테스트를 진행합니다. 사전 정의된 테스트 함수들은 여기에서 확인할 수 있습니다.

3. tearDown

사전 정의된 fixture를 초기화하는 단계입니다. 모든 테스트 후에 실행됩니다.

조금 더 복잡한 활용

1. FunctionTestCase

기존의 assert 기반 테스트를 재사용할 수 있습니다. 그렇게 권장되는 방법은 아닙니다.

def test_function(value):
    assert(value == 1, 'Test Message')
    '''...'''
unittest.FUnctionTestCase(test_function,
    setUp = setupfunc, 
    tearDown = teardownfunc)

2. Skip

두 가지 방법을 이용해 테스트를 스킵할 수 있습니다.
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

3. ExpectedFailure

ExpectedFailure 데코레이터를 이용해 실패 혹은 에러를 성공으로, 성공을 실패로 처리할 수 있습니다.

@unittest.expectedFailure
def test_to_fail(self):
   pass

4. subTest

with 구문을 통해 subTest 컨텍스트에 진입하여 서브테스트를 진행할 수 있습니다.

def test_func(self):
    for i in range(6):
    	with self.subTest(i = i):
       	    self.assertEqual(i % 2, 0)

이 외에도 여러 더 복잡한 활용이 있습니다. 공식문서를 참조하시면 좋을 것 같습니다.

django에서

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/

0개의 댓글