Programming/Python

(Python) Pytest로 Unit-test 구현하기

armyost 2021. 5. 31. 23:18
728x90

소스 다운로드 : https://github.com/armyost/miniterWithPytest.git

 

armyost/miniterWithPytest

This is frame of twitter back-end. Sign-up, Login with JWT, Follow, Unfollow, tweet. And it has pytest also(/test). MVC model project - armyost/miniterWithPytest

github.com

 

unit test는 UI test 나 integration test처럼 시스템을 실제로 실행하여 테스트를 진행하는 방식과는 많이 다르다. unit test는 코드를 테스트하는 개념이다. 

 

우선 가상환경에서 pip로 pytest 모듈을 설치하자.

pip install pytest

 

기본구성

@pytest.fixture // fixture Decorator
def api():
    app = create_app(config.test_config)
    app.config['TESTING'] = True
    api = app.test_client()

flask 에서 제공하는 test_client 함수를 사용하여 엔드포인트들을 그들의 URI를 통해 호출하고 또한 데이터도 전송할 수 있다. 마치 실제로 HTTP 전송을 하는 듯한 효과를 볼 수 있는 것이다. 물론 실제로 전송하는 것은 아니며 메모리에서만 실행되는 것이다. 

 

pytest.fixture decorator를 적용한다. 이 decorator를 적용하는 것이 굉장히 중요하다. fixture decorator가 적용된 함수와 같은 이름의 인자가 다른 test용 함수에 지정되어 있으면 pytest가 알아서 같은 이름의 함수의 리턴값을 해당 인자에 넣어준다. 

import pytest from src.calculator 
import Calculator 

@pytest.fixture 
def calculator():  // calculator가 인자로 호출되는 함수에서 아래 내용을 수행하고 시작하게 되는 것임.
	calculator = Calculator() 
	return calculator 

def test_add(calculator): 
	assert calculator.add(1, 2) == 3 
	assert calculator.add(2, 2) == 4 

def test_subtract(calculator): 
	assert calculator.subtract(5, 1) == 4 
	assert calculator.subtract(3, 2) == 1 

 

 

 

 

본격적인 테스트 전 사용자를 미리생성하기

def setup_function():
    ## Create a test user
    hashed_password = bcrypt.hashpw(
        b"test password",
        bcrypt.gensalt()
    )
    new_users = [
        {
            'id'              : 1,
            'name'            : '송은우',
            'email'           : 'songew@gmail.com',
            'profile'         : 'test profile',
            'hashed_password' : hashed_password
        }, {
            'id'              : 2,
            'name'            : '김철수',
            'email'           : 'tet@gmail.com',
            'profile'         : 'test profile',
            'hashed_password' : hashed_password
        }
    ]
    database.execute(text("""
        INSERT INTO users (
            id,
            name,
            email,
            profile,
            hashed_password
        ) VALUES (
            :id,
            :name,
            :email,
            :profile,
            :hashed_password
        )
    """), new_users)
    
    ## User 2 의 트윗 미리 생성해 놓기
    database.execute(text("""
        INSERT INTO tweets (
            user_id,
            tweet
        ) VALUES (
            2,
            "Hello World!"
        )
    """))

 

api.post 수행한 결과를 사용하는 방법

def test_unfollow(api):
    # 로그인
    resp = api.post(
        '/login',
        data         = json.dumps({'email' : 'songew@gmail.com', 'password' : 'test password'}),
        content_type = 'application/json'
    )
    resp_json    = json.loads(resp.data.decode('utf-8')) // rest객체 호출
    access_token = resp_json['access_token'] // json 형식의 value를 사용