๐ ์ด ๊ธ์ ์ด๋ฐ ๋ถ๊ป ์ถ์ฒํฉ๋๋ค
- API ํ ์คํธ๊ฐ ๋ฌด์์ธ์ง ์๊ณ ์ถ์ QA ์์ง๋์ดใป๊ฐ๋ฐ์
- UI ํ ์คํธ์ API ํ ์คํธ์ ์ฐจ์ด๋ฅผ ์ดํดํ๊ณ ์ถ์ ๋ถ
- Python์ผ๋ก ์๋ํ ํ ์คํธ๋ฅผ ์์ํ๊ณ ์ถ์ ์์ง๋์ด
- pytest์ requests์ ์ฌ์ฉ๋ฒ์ ๊ธฐ์ด๋ถํฐ ๋ฐฐ์ฐ๊ณ ์ถ์ ๋ถ
โ ์ด ๊ธ์ ์ฝ์ผ๋ฉด ์ ์ ์๋ ๊ฒ
- API ํ ์คํธ์ UI ํ ์คํธ์ ์ฐจ์ด์ ์ฌ์ฉ ๊ตฌ๋ถ
- requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก HTTP ์์ฒญ์ ๋ณด๋ด๋ ๋ฐฉ๋ฒ
- pytest๋ก API ํ ์คํธ๋ฅผ ์๋ ์คํํ๋ ๊ธฐ๋ณธ ํจํด
- HTML ๋ฆฌํฌํธ๋ฅผ ์๋ ์์ฑํด์ ํฌํธํด๋ฆฌ์ค์ ํ์ฉํ๋ ๋ฐฉ๋ฒ
ใAPI ํ ์คํธ๋ ์ด๋ ต๊ฒ ์งโฆใ๋ผ๊ณ ์๊ฐํ๊ณ ์์ง๋ ์์ผ์ ๊ฐ์? ์ฌ์ค requests์ pytest ๋ ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์กฐํฉํ๋ ๊ฒ๋ง์ผ๋ก ์ค๋ฌด ์์ค์ API ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์ด ๊ธ์์๋ API ํ ์คํธ์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ถํฐ ํ๊ฒฝ ๊ตฌ์ถใป์ค์ ์ฝ๋๊น์ง ๊ผผ๊ผผํ๊ฒ ํด์คํฉ๋๋ค. UI ํ ์คํธ ๊ฒฝํ๋ฐ์ ์๋ ๋ถ๋ ๊ธ์ ๋ค ์ฝ์ ๋ฌด๋ ต์๋ ใAPI ํ ์คํธ๋ ๋ด๊ฐ ์ง์ ์ธ ์ ์๋คใ๋ ์์ ๊ฐ์ด ์๊ธธ ๊ฒ์ ๋๋ค.
00. API ํ ์คํธ๋๏ผ
API ํ ์คํธ๋, ์ ํ๋ฆฌ์ผ์ด์ ์ ใ๋ด๋ถ ๊ตฌ์กฐ๏ผAPI๏ผใ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๋์ง ํ์ธํ๋ ํ ์คํธ์ ๋๋ค.
UI ํ ์คํธ๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ์กฐ์ํด์ ํ๋ฉด ์ ์ฒด๋ฅผ ํ์ธํ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, API ํ ์คํธ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ HTTP ์์ฒญ์ ์ง์ ์ ์กํ์ฌ ์๋ต์ ๊ฒ์ฆํฉ๋๋ค.
| UI ํ ์คํธ | API ํ ์คํธ | |
|---|---|---|
| ํ์ธ ๋์ | ํ๋ฉดใป์ธ๊ดใป์กฐ์๊ฐ | ๋ฐ์ดํฐใป๋ก์งใป๋ณด์ |
| ๋ธ๋ผ์ฐ์ | ํ์ | ๋ถํ์ |
| ์คํ ์๋ | ๋๋ฆผ ๐ข | ๋งค์ฐ ๋น ๋ฆ โก |
| ๊นจ์ง๊ธฐ ์ฌ์ | UI ๋ณ๊ฒฝ์ผ๋ก ์ฝ๊ฒ ๊นจ์ง | ๋ก์ง์ด ๋ฐ๋์ง ์๋ ํ ์์ ์ |
๐ก ํฌ์ธํธ๏ผUI ํ ์คํธ์ API ํ ์คํธ๋ ใ์ด๋ ์ชฝ์ด ๋ ์ข๋คใ๊ฐ ์๋๋ผ, ๊ฐ๊ฐ ์ญํ ์ด ๋ค๋ฆ ๋๋ค. ๋ ๋ค ํ ์ ์์ผ๋ฉด QA ์์ง๋์ด๋ก์์ ๊ฐ์น๊ฐ ํฌ๊ฒ ๋์์ง๋๋ค.
01. API ํ ์คํธ๊ฐ ์ ์ค์ํ๊ฐ๏ผ
ํ๋์ ์น ์ฑ์ ๊ฑฐ์ ๋ชจ๋ ํ๋ก ํธ์๋๏ผํ๋ฉด๏ผ์ ๋ฐฑ์๋๏ผAPI๏ผ๊ฐ ๋ถ๋ฆฌ๋ ๊ตฌ์กฐ๋ก ๋์ด ์์ต๋๋ค.
API๊ฐ ๋ง๊ฐ์ง๋ฉด ํ๋ฉด์ด ์๋ฌด๋ฆฌ ์ฌ๋ฐ๋ฅด๊ฒ ํ์๋์ด ์์ด๋ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ง ์๊ฑฐ๋ใป๋ก๊ทธ์ธ์ด ์ ๋๊ฑฐ๋ใป๊ฒฐ์ ๊ฐ ์คํจํ๋ ๋ฑ ์น๋ช ์ ์ธ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
๋ํ API ํ ์คํธ๋ UI ํ ์คํธ๋ณด๋ค 10ใ100๋ฐฐ ๋น ๋ฅด๊ฒ ์คํํ ์ ์๊ธฐ ๋๋ฌธ์, CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉํ์ฌ ๋งค๋ฒ ๋ฐฐํฌ ์ ์ ์๋์ผ๋ก ํ์ธํ๋ ๊ฒ์ด ์ค๋ฌด์ ์ ์์ ๋๋ค.
# API ํ
์คํธ ์ด๋ฏธ์ง
# ๋ธ๋ผ์ฐ์ ์์ด๏ผ์ฝ๋๋ง์ผ๋ก ์๋ฒ์ ํต์ ํ๋ค
import requests
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
print(response.status_code) # 200
print(response.json()) # {"id": 1, "name": "Leanne Graham", ...}
๐ก ํฌ์ธํธ๏ผ๋จ 3์ค๋ก API์ ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด API ํ ์คํธ์ ๊ธฐ๋ณธ ํํ์ ๋๋ค.
02. ํ๊ฒฝ ๊ตฌ์ถ
ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
์๋ 3๊ฐ์ง๋ฅผ ์ค์นํ๊ธฐ๋ง ํ๋ฉด ๋์ํฉ๋๋ค.
pip install requests pytest pytest-html
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์ญํ |
|---|---|
requests |
API์ HTTP ์์ฒญ์ ๋ณด๋ธ๋ค |
pytest |
ํ ์คํธ๋ฅผ ์คํใป๊ด๋ฆฌํ๋ค |
pytest-html |
HTML ๋ฆฌํฌํธ๋ฅผ ์๋ ์์ฑํ๋ค |
pytest.ini ์ค์
ํ๋ก์ ํธ ๋ฃจํธ์ pytest.ini ๋ฅผ ๋๋ ๊ฒ์ผ๋ก, ํ
์คํธ ์คํ ๋๋ง๋ค HTML ๋ฆฌํฌํธ๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.
# pytest.ini
[pytest]
addopts = --html=report.html --self-contained-html
๐ก Tip๏ผํ ๋ฒ ์ค์ ํด๋๋ฉด ์ดํ๋ก๋ pytest test_api.py -v ๋ง์ผ๋ก ์๋์ผ๋ก HTML ๋ฆฌํฌํธ๊ฐ ์์ฑ๋ฉ๋๋ค. ํฌํธํด๋ฆฌ์ค ์ฆ๊ฑฐ๋ก๋ ํ์ฉํ ์ ์์ต๋๋ค.
03. requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ธฐ๋ณธ
HTTP ๋ฉ์๋ ์ฌ์ฉ๋ฒ
HTTP ๋ฉ์๋์ ๋์ํ๋ ๋ฉ์๋๊ฐ ๊ฐ๊ฐ ์ค๋น๋์ด ์์ต๋๋ค.
import requests
# GET: ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
# POST: ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ค
response = requests.post(
"https://jsonplaceholder.typicode.com/users",
json={"name": "Taro", "email": "taro@example.com"}
)
# PUT: ๋ฐ์ดํฐ๋ฅผ ์
๋ฐ์ดํธํ๋ค
response = requests.put(
"https://jsonplaceholder.typicode.com/users/1",
json={"name": "Updated Taro"}
)
# DELETE: ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ค
response = requests.delete("https://jsonplaceholder.typicode.com/users/1")
์๋ต ํ์ธ ๋ฐฉ๋ฒ
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
print(response.status_code) # ์ํ ์ฝ๋: 200
print(response.json()) # ์๋ต ๋ฐ๋๏ผJSON ํ์๏ผ
print(response.headers) # ์๋ต ํค๋
๐ก ํฌ์ธํธ๏ผresponse.json() ์ ์ฌ์ฉํ๋ฉด ์๋ต์ JSON์ Python ๋์
๋๋ฆฌ ํํ๋ก ๋ค๋ฃฐ ์ ์์ต๋๋ค. ๊ทธ๋๋ก ์ด์์
์ ์ฌ์ฉํ ์ ์์ด์ ํธ๋ฆฌํฉ๋๋ค.
04. pytest ๊ธฐ๋ณธ
ํ ์คํธ ์์ฑ๋ฒ
ํจ์๋ช
์ test_ ๋ก ์์ํ๊ธฐ๋ง ํ๋ฉด pytest๊ฐ ์๋์ผ๋ก ํ
์คํธ๋ก ์ธ์ํฉ๋๋ค.
import requests
def test_get_user():
"""์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ฐ์ ธ์ฌ ์ ์๋์ง ํ์ธ"""
response = requests.get("https://jsonplaceholder.typicode.com/users/1")
assert response.status_code == 200, f"๊ธฐ๋๊ฐ: 200, ์ค์ : {response.status_code}"
assert response.json()["id"] == 1
assert "name" in response.json()
์คํ ์ปค๋งจ๋
# ๋ชจ๋ ํ
์คํธ๋ฅผ ์คํ
pytest
# ์์ธ ํ์๋ก ์คํ
pytest -v
# ํน์ ํ์ผ๋ง ์คํ
pytest test_api.py -v
์คํ ๊ฒฐ๊ณผ ์ํ
test_api.py::test_get_user PASSED [ 33%]
test_api.py::test_create_user PASSED [ 66%]
test_api.py::test_delete_user PASSED [100%]
3 passed in 1.23s โ
๐ก ํฌ์ธํธ๏ผassert ๊ฐ ์คํจํ์ ๋๋, ์ด๋ค ๊ฐ์ด ๊ธฐ๋๊ฐ๊ณผ ๋ฌ๋๋์ง๋ฅผ ์๋์ผ๋ก ํ์ํด์ค๋๋ค. ๋๋ฒ๊น
์ด ๋งค์ฐ ํธํด์ง๋๋ค.
05. pytest + requests ์กฐํฉํ๊ธฐ
์ด ๋ ๊ฐ์ง๋ฅผ ์กฐํฉํ๋ฉด ์ค๋ฌด ์์ค์ API ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. JSONPlaceholder๋ผ๋ ๋ฌด๋ฃ ๋ชฉ๏ผmock๏ผ API๋ฅผ ์ฌ์ฉํด์ ์ค์ ๋ก ๋์์์ผ ๋ด ์๋ค.
import requests
import pytest
BASE_URL = "https://jsonplaceholder.typicode.com"
def test_get_all_users():
"""๋ชจ๋ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋์ง ํ์ธ"""
response = requests.get(f"{BASE_URL}/users")
assert response.status_code == 200
assert len(response.json()) == 10 # 10๋ช
์ ์ฌ์ฉ์๊ฐ ๋ฐํ๋ ๊ฒ
def test_create_user():
"""์ฌ์ฉ์๋ฅผ ์์ฑํ ์ ์๋์ง ํ์ธ"""
new_user = {"name": "Yoshitsugu", "email": "test@example.com"}
response = requests.post(f"{BASE_URL}/users", json=new_user)
assert response.status_code == 201
assert response.json()["name"] == "Yoshitsugu"
def test_delete_user():
"""์ฌ์ฉ์๋ฅผ ์ญ์ ํ ์ ์๋์ง ํ์ธ"""
response = requests.delete(f"{BASE_URL}/users/1")
assert response.status_code == 200
โ ๏ธ ์ฃผ์๏ผJSONPlaceholder๋ ๋ชฉ๏ผmock๏ผ API์ด๋ฏ๋ก ์ค์ ๋ก๋ ๋ฐ์ดํฐ๊ฐ ์ ์ฅใป์ญ์ ๋์ง ์์ต๋๋ค. ํ์ต์ฉ์ผ๋ก ์์ฌํ๊ณ ์ฌ์ฉํ ์ ์์ต๋๋ค.
06. ์์ฃผ ๊ฒช๋ ๋ฌธ์ & ํด๊ฒฐ๋ฒ
๊ตฌํ ์ค ์ค์ ๋ก ๊ฒช์๋ ๋ฌธ์ ๋ค์ ์ ๋ฆฌํ์ต๋๋ค. ๊ฐ์ ๊ณณ์์ ๋งํ๋ ๋ถ๋ค๊ป ๋์์ด ๋๋ฉด ์ข๊ฒ ์ต๋๋ค.
โ requests์ pytest-requests๋ฅผ ํผ๋ํด๋ฒ๋ฆฐ๋ค
์ฒ์์ ใpytest๋ก HTTP ์์ฒญ์ ๋ณด๋ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌใ๋ฅผ ๊ฒ์ํ๋๋ pytest-requests ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐพ์ ์ค์นํด๋ฒ๋ ธ์ต๋๋ค. ์ค์ ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๋ณ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, requests๏ผHTTP ํด๋ผ์ด์ธํธ๏ผ์ pytest๏ผํ
์คํธ ํ๋ ์์ํฌ๏ผ๋ฅผ ์กฐํฉํด์ ์ฌ์ฉํฉ๋๋ค.
# โ pytest-requests๋ ์ด๋ฒ์ ์ฌ์ฉํ์ง ์์
pip install pytest-requests
# โ
์ฌ๋ฐ๋ฅธ ์ค์น
pip install requests pytest pytest-html
๐ก ํฌ์ธํธ๏ผrequests ๋ HTTP ์์ฒญ ์ ์ฉ, pytest ๋ ํ
์คํธ ์คํ ์ ์ฉ์
๋๋ค. ์ญํ ์ด ๋ค๋ฅด๋ฏ๋ก ๋ ๋ค ์ค์นํ์ฌ ์ฌ์ฉํฉ๋๋ค.
โก response.json()์์ KeyError๊ฐ ๋ฐ์ํ๋ค
์๋ต์ JSON์์ ๊ฐ์ ๊บผ๋ด๋ ค๊ณ ํ์ ๋ ์กด์ฌํ์ง ์๋ ํค๋ฅผ ์ง์ ํด๋ฒ๋ ค KeyError ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋จผ์ ์๋ต ๋ด์ฉ์ ํ์ธํ๊ณ ๋์ ์ ๊ทผํ๋ ์ต๊ด์ด ์ค์ํฉ๋๋ค.
# โ ํค๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด KeyError ๋ฐ์
user_id = response.json()["userId"] # KeyError!
# โ
๋จผ์ print()๋ก ๋ด์ฉ์ ํ์ธํ๋ค
print(response.json())
# {'id': 1, 'name': 'Leanne Graham', ...}
# โ
get()์ ์ฌ์ฉํ๋ฉด KeyError๋ฅผ ๋ฐฉ์งํ ์ ์๋ค
user_id = response.json().get("id") # ์ค๋ฅ ๋์ None์ ๋ฐํ
๐ก ํฌ์ธํธ๏ผ์ฒ์ ์ ํ๋ API๋ ๋ฐ๋์ print(response.json()) ๋ก ์๋ต ๊ตฌ์กฐ๋ฅผ ํ์ธํ๊ณ ๋์ ์ด์์
์ ์์ฑํฉ์๋ค.
โข assert๊ฐ ์คํจํด๋ ์์ธ์ ์ ์ ์๋ค
์ฒ์์๋ assert response.status_code == 200 ๋ง ์์ฑํ๊ธฐ ๋๋ฌธ์ ์คํจํ์ ๋ ใ๋ฌด์์ด ๋ฐํ๋๋์งใ๋ฅผ ์ ์ ์์ด ์์ธ ์กฐ์ฌ์ ์๊ฐ์ด ๊ฑธ๋ ธ์ต๋๋ค.
# โ ์คํจ ์ ์ ๋ณด๊ฐ ์ ๋ค
assert response.status_code == 200
# โ
์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๊ฐํด์ ์์ธ์ ๋ฐ๋ก ํ์
assert response.status_code == 200, f"๊ธฐ๋๊ฐ: 200, ์ค์ ๊ฐ: {response.status_code}"
๐ก ํฌ์ธํธ๏ผassert ์กฐ๊ฑด, "๋ฉ์์ง" ํํ๋ก ๋ฉ์์ง๋ฅผ ์ถ๊ฐํ๋ฉด ์คํจ ์์ ๊ธฐ๋๊ฐ๊ณผ ์ค์ ๊ฐ์ด ๋ฌด์์ด์๋์ง๋ฅผ ๋ฐ๋ก ์ ์ ์์ต๋๋ค.
โฃ ํ ์คํธ ํ์ผ๋ช ใปํจ์๋ช ๊ท์น์ ๋ชฐ๋๋ค
pytest๊ฐ ํ ์คํธ๋ฅผ ์๋์ผ๋ก ์ธ์ํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์์ธ์ ํ์ผ๋ช ์ด๋ ํจ์๋ช ์ด pytest์ ๋ช ๋ช ๊ท์น์ ๋ฐ๋ฅด์ง ์์๊ธฐ ๋๋ฌธ์ด์์ต๋๋ค.
# โ pytest๊ฐ ์ธ์ํ์ง ๋ชปํจ
# ํ์ผ๋ช
: api_test.py๏ผtest_๋ก ์์ํ์ง ์์๏ผ
def check_user(): # test_๋ก ์์ํ์ง ์์
assert True
# โ
pytest๊ฐ ์๋์ผ๋ก ์ธ์
# ํ์ผ๋ช
: test_api.py๏ผtest_๋ก ์์๏ผ
def test_check_user(): # test_๋ก ์์
assert True
โ ๏ธ ์ฃผ์๏ผํ์ผ๋ช
์ test_ ๋ก ์์ํ๊ฑฐ๋ _test ๋ก ๋๋์ผ ํ๊ณ , ํจ์๋ช
์ test_ ๋ก ์์ํด์ผ ํฉ๋๋ค. ์ด ๋ ๊ฐ์ง๊ฐ pytest์ ๊ธฐ๋ณธ ๊ท์น์
๋๋ค.
โค BASE_URL ๋์ ์ฌ๋์๊ฐ ์์ด URL์ด ์ด์ค์ผ๋ก ๋๋ค
BASE_URL ๋์ / ๋ฅผ ๋ถ์ธ ์ํ์์ ๊ฒฝ๋ก๋ฅผ ๊ฒฐํฉํ๋๋ URL์ด //users ์ฒ๋ผ ์ด์ค ์ฌ๋์๊ฐ ๋์ด๋ฒ๋ ค ์์ฒญ์ด ์คํจํ์ต๋๋ค.
# โ ์ด์ค ์ฌ๋์๊ฐ ๋์ด๋ฒ๋ฆผ
BASE_URL = "https://jsonplaceholder.typicode.com/"
response = requests.get(f"{BASE_URL}/users")
# โ https://jsonplaceholder.typicode.com//users๏ผNG๏ผ
# โ
BASE_URL ๋์ ์ฌ๋์๋ฅผ ์ ๊ฑฐ
BASE_URL = "https://jsonplaceholder.typicode.com"
response = requests.get(f"{BASE_URL}/users")
# โ https://jsonplaceholder.typicode.com/users๏ผOK๏ผ
๐ก ํฌ์ธํธ๏ผBASE_URL ๋์๋ / ๋ฅผ ๋ถ์ด์ง ์๊ณ , ๊ฐ ๊ฒฝ๋ก์ ์์ / ๋ฅผ ๋ถ์ด๋ ๋ฐฉ์์ผ๋ก ํต์ผํ๋ฉด ํผ๋์ด ์์ต๋๋ค.
07. ์์ฃผ ๋ฌป๋ ์ง๋ฌธ๏ผFAQ๏ผ
Q. pytest๋ก API ํ
์คํธ๋ฅผ ํ๋ ์ฅ์ ์ ๋ฌด์์ธ๊ฐ์๏ผ
A. Python์ผ๋ก ์ง๊ด์ ์ผ๋ก ํ
์คํธ๋ฅผ ์์ฑํ ์ ์๊ณ CI/CD์์ ํตํฉ์ด ์ฌ์ด ๊ฒ์ด ๊ฐ์ฅ ํฐ ์ฅ์ ์
๋๋ค. ๋ํ pytest-html ๋ก HTML ๋ฆฌํฌํธ๋ฅผ ์๋ ์์ฑํ ์ ์์ด ํ
์คํธ ์ฆ๊ฑฐ ์์ฑ ๊ณต์๋ฅผ ๋ํญ ์ค์ผ ์ ์์ต๋๋ค.
Q. requests์ httpx ์ด๋ ์ชฝ์ด ์ข์๊ฐ์๏ผ
A. ์ฉ๋์ ๋ฐ๋ผ ๊ตฌ๋ถํ๋ ๊ฒ์ด ์ต์ ์
๋๋ค. ๊ฐ๋จํ ๋๊ธฐ ์ฒ๋ฆฌ๋ผ๋ฉด requests, ๋น๋๊ธฐ ์ฒ๋ฆฌ๏ผasync/await๏ผ๊ฐ ํ์ํ๋ค๋ฉด httpx ๋ฅผ ์ ํํ์ธ์. API ํ
์คํธ ์
๋ฌธ์๋ requests ๊ฐ ๋ ๊ฐ๋จํ์ฌ ์ถ์ฒํฉ๋๋ค.
Q. UI ํ
์คํธ์ API ํ
์คํธ ์ค ์ด๋ ๊ฒ๋ถํฐ ์์ํด์ผ ํ๋์๏ผ
A. API ํ
์คํธ๋ถํฐ ์์ํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค. ์คํ ์๋๊ฐ ๋น ๋ฅด๊ณ ํ๊ฒฝ ์ค์ ๋ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ํ
์คํธ ์๋ํ์ ๊ธฐ์ด๋ฅผ ๋ฐฐ์ฐ๊ธฐ์ ์ต์ ์
๋๋ค. UI ํ
์คํธ์ ์ต์ํ ๋ถ๋ API ํ
์คํธ๋ฅผ ์ถ๊ฐํจ์ผ๋ก์จ ใ๋ ๋ค ํ ์ ์๋ ์์ง๋์ดใ๋ก์ ์ดํํ ์ ์์ต๋๋ค.
Q. ํ
์คํธ ๋์ API๊ฐ ์๋ ๊ฒฝ์ฐ๋ ์ด๋ป๊ฒ ํ๋ฉด ๋๋์๏ผ
A. ์ฐ์ต์ฉ ๊ณต๊ฐ API๋ฅผ ์ฌ์ฉํฉ์๋ค. JSONPlaceholder๏ผ์ฌ์ฉ์ใป๊ฒ์๋ฌผ CRUD๏ผ๋ Restful Booker๏ผ์ธ์ฆ ํ๋ก์ฐ๏ผ๊ฐ ํฌํธํด๋ฆฌ์ค์ฉ API ํ
์คํธ์ ์ต์ ์
๋๋ค. ๋ ๋ค ๋ฌด๋ฃ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
Q. pytest์ fixture๋ ๋ฌด์์ธ๊ฐ์๏ผ
A. ํ
์คํธ์ ์ฌ์ ใป์ฌํ ์ฒ๋ฆฌ๋ฅผ ๊ณตํตํํ๋ ๊ตฌ์กฐ์
๋๋ค. ์๋ฅผ ๋ค์ด ์ธ์ฆ ํ ํฐ ์ทจ๋์ fixture์ ์์ฑํด๋๋ฉด ์ฌ๋ฌ ํ
์คํธ ์ผ์ด์ค์์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฝ๋์ ์ค๋ณต์ ์ค์ด๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ๊ตฌ์กฐ๋ก ๋ง๋ค๊ธฐ ์ํ ์ค์ํ ๊ธฐ๋ฅ์
๋๋ค.
08. ์ ๋ฆฌ
์ด ๊ธ์์๋ API ํ ์คํธ์ ๊ธฐ๋ณธ ๊ฐ๋ ๊ณผ pytest์ requests์ ์ฌ์ฉ๋ฒ์ ํด์คํ์ต๋๋ค.
| ํฌ์ธํธ | ๋ด์ฉ |
|---|---|
| API ํ ์คํธ๋ | ๋ธ๋ผ์ฐ์ ์์ด HTTP ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๊ฒ์ฆํ๋ ํ ์คํธ |
| requests์ ์ญํ | API์ HTTP ์์ฒญ ์ ์กใป์๋ต ์ทจ๋ |
| pytest์ ์ญํ | ํ ์คํธ ์คํใป๊ด๋ฆฌใปHTML ๋ฆฌํฌํธ ์์ฑ |
| ์กฐํฉ์ ๊ฐ์ | ๊ฐ๋จํ ์ฝ๋๋ก ์ค๋ฌด ์์ค์ API ํ ์คํธ๋ฅผ ์คํํ ์ ์๋ค |
UI ํ ์คํธ ๊ฒฝํ๋ฐ์ ์๋ ๋ถ๋, requests์ pytest ๋ ๊ฐ์ง๋ง ์ตํ๋ฉด API ํ ์คํธ๋ฅผ ์์ฑํ ์ ์๊ฒ ๋ฉ๋๋ค. GitHub์ ์ฝ๋๋ฅผ ๊ณต๊ฐํจ์ผ๋ก์จ ใUI๋ API๋ ๋ ๋ค ํ ์ ์์ต๋๋ค๏ผใ๋ผ๋ ์ดํ์ด ๋ฉ๋๋ค. ๋ค์ ๊ธ์์๋ ์ค์ API ํ ์คํธ ์ผ์ด์ค๋ฅผ ์์ธํ ํด์คํฉ๋๋ค.
