백엔드 Back-end/테스트 Test

Python requests와 pytest로 REST API 서버 테스트하기

Tap to restart 2022. 11. 6. 17:00
반응형

자바스크립트 기반인 frisby.js로 REST API 서버 테스트를 할 수도 있지만, 파이썬이 익숙하다면 requests로도 쉽게 구현할 수 있다.

 

준비: API 서버 실행

우선 FastAPI 예제를 실행한다. 

예제코드는 FastAPI - Email Login with Password.. 여기 있다. 

localhost:8000/docs로 접속했을 때 아래처럼 뜬다면 정상 작동하고 있는 것이다.

 

API 테스트 코드 작성

위에 브라우저로 확인한 것을 그냥 코드로 아래처럼 작성해서 확인할 수도 있다.

import requests

def test_get_docs():
    endpoint = "http://localhost:8000/docs/"
    response = requests.get(endpoint)
    assert response.status_code == 200

서버가 제대로 작동한다면 당연히 응답 상태 코드가 200이라 테스트를 통과하게 된다.

 

엑세스 토큰 얻기 코드 예

API 서버를 대상으로 한 E2E(EndToEnd) 테스트는 실제 데이터베이스가 연결된 상태로 진행한다. 진짜 실제 서비스 상태와 최대한 비슷하게 하기 위해서다. 그래서 엑세스 토큰을 얻어서 넣어야 할 때도 있다. 

 

그때는 아래 예처럼 하면 된다.

def _get_admin_access_token():
    data = {
        "email": ADMIN_EMAIL,
        "password": ADMIN_PASSWORD
    }
    endpoint = "http://localhost:8000/api/v1/login/access-token"
    response = requests.post(url=endpoint, json=data)
    access_token = response.json()["access_token"]
    return access_token


def _get_headers_with_admin_access_token():
    access_token = _get_admin_access_token()
    headers = {
        "Content-type": "application/json",
        "Authorization": f"bearer {access_token}"
    }
    return headers

 

코드 예는 아래와 같다. 아래 예에는 PUT, DELETE 예는 없지만 크게 다르지 않다.

import requests
from dotenv import dotenv_values

BASE_URL = dotenv_values(".env")["BASE_URL"]
ADMIN_EMAIL = dotenv_values(".env")["ADMIN_EMAIL"]
ADMIN_PASSWORD = dotenv_values(".env")["ADMIN_PASSWORD"]


def test_get_index():
    """
    Test http://localhost:8000
    """
    endpoint = f"{BASE_URL}"
    response = requests.get(endpoint)
    assert response.status_code == 404


def test_get_docs():
    """
    Test http://localhost:8000/docs/
    """
    endpoint = f"{BASE_URL}/docs/"
    response = requests.get(endpoint)
    assert response.status_code == 200


def _get_admin_access_token():
    data = {
        "email": ADMIN_EMAIL,
        "password": ADMIN_PASSWORD
    }
    endpoint = f"{BASE_URL}/api/v1/login/access-token"
    response = requests.post(url=endpoint, json=data)
    access_token = response.json()["access_token"]
    return access_token


def _get_headers_with_admin_access_token():
    access_token = _get_admin_access_token()
    headers = {
        "Content-type": "application/json",
        "Authorization": f"bearer {access_token}"
    }
    return headers


def test_get_api_v1_users_me():
    headers = _get_headers_with_admin_access_token()
    endpoint = f"{BASE_URL}/api/v1/users/me"
    response = requests.get(url=endpoint, headers=headers)
    assert response.json()["email"] == "taptorestart@gmail.com"


TEST_USER_EMAIL = "janedoe@gmail.com"
TEST_USER_PASSWORD = "verysecret"


def _register_test_user():
    headers = _get_headers_with_admin_access_token()
    endpoint = f"{BASE_URL}/api/v1/register"
    data = {
        "email": TEST_USER_EMAIL,
        "password": TEST_USER_PASSWORD,
    }
    requests.post(url=endpoint, headers=headers, json=data)
    return None


def _get_headers_with_test_user_access_token():
    _register_test_user()
    data = {
        "email": TEST_USER_EMAIL,
        "password": TEST_USER_PASSWORD,
    }
    endpoint = f"{BASE_URL}/api/v1/login/access-token"
    response = requests.post(url=endpoint, json=data)
    access_token = response.json()["access_token"]
    headers = {
        "Content-type": "application/json",
        "Authorization": f"bearer {access_token}"
    }
    return headers


def _get_test_user_id():
    headers = _get_headers_with_test_user_access_token()
    endpoint = f"{BASE_URL}/api/v1/users/me"
    response = requests.get(url=endpoint, headers=headers)
    user_id = response.json()["id"]
    return user_id


def test_patch_api_v1_users_id_by_admin():
    headers = _get_headers_with_admin_access_token()
    test_user_id = _get_test_user_id()
    endpoint = f"{BASE_URL}/api/v1/users/{test_user_id}"
    data = {
        "email": "johndoe@gmail.com"
    }
    response = requests.patch(url=endpoint, headers=headers, json=data)
    assert response.json()["email"] == "johndoe@gmail.com"

 

 

여기 REST API Test using requests 서 전체 코드를 확인할 수 있다.

 

관련 글

frisby.js로 REST API 서버 테스트 하기

DRF(Django Rest Framework) API 서버에 requests로 PUT할 때 나타나는 이상현상

반응형