Session - Unit Test

Sung Jun Jin·2020년 5월 14일
0

위코드 세션 정리

목록 보기
11/12

Intro

시스템을 테스트 할때 크게 3가지의 방법으로 나눌 수 있다

  • UI Testing / E2E Testing
  • Integration Testing
  • Unit Testing

공수는 Unit Testing -> Integration Testing -> E2E Testing 순서로 많이 든다. 따라서 전체 테스트 coverage는 다음과 같은 비율로 구현하는것이 좋다

Unit Test 개념 & 용어

Unit Test: 함수, 메소드와 같은 가장 작은 단위를 테스트하는 코드를 작성해서 테스트 하는 것을 만한다.
Django의 unit test는 Python의 표준 모듈인 unittest를 사용한다. 이 모듈은 클래스에 기반한 테스팅 모듈이다.

TestCase: unittest 프레임 워크의 테스트 조직의 기본 단위
Fixture: 테스트를 진행할때 필요한 테스트용 데이터 혹은 설정 등을 이야기한다. 주로 테스트가 실행되기 전이나 후에 생긴다
assertion: unit test에서 테스트 하는 부분이 제대로 됬는지를 확인하는 부분. Assertion이 실패하면 테스트도 실패한다.

예제

다음과 같은 간단한 엔드포인트가 있다

import json

from django.views  import View
from django.http   import HttpResponse, JsonResponse

class JustView(View):
    def get(self, request):
        return JsonResponse({'message':'Just Do Python with >Wecode'}, status = 200)

이 엔드포인트를 테스트하는 코드를 작성해보자. 테스트 코드는 Django에서 기본적으로 제공하는 test.py에서 작성해준다.

from django.test import TestCase, Client

client = Client()
class JustTest(TestCase):
    def test_just_get_view(self):
        response = client.get('/just') 
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), {
            "message": "Just Do Python with >Wecode"
        })				

일반적으로 테스트 코드를 작성할때 일반적으로 다음과 같은 절차를 따른다.

  1. Client() 말 그대로 클라이언트로써 동작하는 객체이다. requests나 http와 비슷한 역할을 한다.

  2. TestCase 클래스를 상속하는 테스트 클래스를 만든다

  3. 내부에서 작성하는 테스트 함수명은 언제나 test_로 시작해야 한다.

  4. 테스트 메소드에서는 일반적으로 테스트하고자 하는 함수나 메소드를 호출하고 그 결과값을 .assert() 메소드를 사용하여 확인한다. 대표적인 self.assert() 메소드의 종류는 다음과 같다.

Python 공식 문서 unittest 참고

테스트를 실행해보자

python manage.py test

성공 메세지

----------------------------------------------------------------------
Ran 2 tests in 0.005s

OK
Destroying test database for alias 'default'...

실패 메세지 1 -> 기대되는 JSON Response가 일치하지 않을 때

======================================================================
FAIL: test_just_get_view (just.test.JustTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/sungjunjin/devel/unit_test/unittest_part01/just/test.py", line 9, in test_just_get_view
    self.assertEqual(response.json(), {
AssertionError: {'message': 'Just Do Python with >Wecode'} != {'message': 'Just Do Python with >Wecod'}
- {'message': 'Just Do Python with >Wecode'}
?                                        -

+ {'message': 'Just Do Python with >Wecod'}

실패 메세지2 -> 기대되는 http response 코드가 일치하지 않을 때

======================================================================
FAIL: test_just_get_view (just.test.JustTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/sungjunjin/devel/unit_test/unittest_part01/just/test.py", line 8, in test_just_get_view
    self.assertEqual(response.status_code, 400)
AssertionError: 200 != 400

Text Fixture

위와 같이 간단한 엔드포인트는 테스트 전에 테스트를 위한 사전 준비 작업을 할 필요가 없지만, 만약 테스트를 하기 전에 테스트에 필요한 리소스들을 세팅해야하는 경우에는 unnitest에서 제공하는 setUp() 메소드를 사용할 수 있다.

예를 들어 책의 저자를 확인하는 엔드포인트를 테스트해야 할 경우, 책이 있어야 하기때문에 setUp() 메소드 내에서 테스트를 위해 몇 개를 생성해줄수 있다.

class AuthorBookTest(TestCase):
	def setUp(self):
    	    print('excecuting setUp method')
            client = Client()
            Book.objects.create(
                id = 1,
                title = 'python'
            )

            Book.objects.create(
                id = 2,
                title = 'Javascript'
            )

테스트를 위해 'python', 'javascript'라는 이름의 책 두 권을 생성했다.

하지만 테스트가 끝나도 위에 책들은 데이터베이스에 남아있으므로 테스트가 끝나면 리소스들을 정리(clean up)을 해줘야 한다. 이를 위해 unittest에서 제공하는 tearDown() 메소드를 사용해준다.

def tearDown(self):
    print('executing tearDown method')
    Book.objects.all().delete()
profile
주니어 개발쟈🤦‍♂️

0개의 댓글