Skip to content

Commit 43d5b49

Browse files
authored
✨ Test using the TestClient (#160)
1 parent 41a2f15 commit 43d5b49

File tree

8 files changed

+82
-103
lines changed

8 files changed

+82
-103
lines changed

{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_celery.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
from typing import Dict
22

3-
import requests
3+
from fastapi.testclient import TestClient
44

55
from app.core.config import settings
6-
from app.tests.utils.utils import get_server_api
76

87

9-
def test_celery_worker_test(superuser_token_headers: Dict[str, str]) -> None:
10-
server_api = get_server_api()
8+
def test_celery_worker_test(
9+
client: TestClient, superuser_token_headers: Dict[str, str]
10+
) -> None:
1111
data = {"msg": "test"}
12-
r = requests.post(
13-
f"{server_api}{settings.API_V1_STR}/utils/test-celery/",
12+
r = client.post(
13+
f"{settings.API_V1_STR}/utils/test-celery/",
1414
json=data,
1515
headers=superuser_token_headers,
1616
)

{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_items.py

+11-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import requests
1+
from fastapi.testclient import TestClient
22
from sqlalchemy.orm import Session
33

44
from app.core.config import settings
55
from app.tests.utils.item import create_random_item
6-
from app.tests.utils.utils import get_server_api
76

87

9-
def test_create_item(superuser_token_headers: dict, db: Session) -> None:
10-
server_api = get_server_api()
8+
def test_create_item(
9+
client: TestClient, superuser_token_headers: dict, db: Session
10+
) -> None:
1111
data = {"title": "Foo", "description": "Fighters"}
12-
response = requests.post(
13-
f"{server_api}{settings.API_V1_STR}/items/",
14-
headers=superuser_token_headers,
15-
json=data,
12+
response = client.post(
13+
f"{settings.API_V1_STR}/items/", headers=superuser_token_headers, json=data,
1614
)
1715
assert response.status_code == 200
1816
content = response.json()
@@ -22,12 +20,12 @@ def test_create_item(superuser_token_headers: dict, db: Session) -> None:
2220
assert "owner_id" in content
2321

2422

25-
def test_read_item(superuser_token_headers: dict, db: Session) -> None:
23+
def test_read_item(
24+
client: TestClient, superuser_token_headers: dict, db: Session
25+
) -> None:
2626
item = create_random_item(db)
27-
server_api = get_server_api()
28-
response = requests.get(
29-
f"{server_api}{settings.API_V1_STR}/items/{item.id}",
30-
headers=superuser_token_headers,
27+
response = client.get(
28+
f"{settings.API_V1_STR}/items/{item.id}", headers=superuser_token_headers,
3129
)
3230
assert response.status_code == 200
3331
content = response.json()

{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_login.py

+8-12
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,27 @@
11
from typing import Dict
22

3-
import requests
3+
from fastapi.testclient import TestClient
44

55
from app.core.config import settings
6-
from app.tests.utils.utils import get_server_api
76

87

9-
def test_get_access_token() -> None:
10-
server_api = get_server_api()
8+
def test_get_access_token(client: TestClient) -> None:
119
login_data = {
1210
"username": settings.FIRST_SUPERUSER,
1311
"password": settings.FIRST_SUPERUSER_PASSWORD,
1412
}
15-
r = requests.post(
16-
f"{server_api}{settings.API_V1_STR}/login/access-token", data=login_data
17-
)
13+
r = client.post(f"{settings.API_V1_STR}/login/access-token", data=login_data)
1814
tokens = r.json()
1915
assert r.status_code == 200
2016
assert "access_token" in tokens
2117
assert tokens["access_token"]
2218

2319

24-
def test_use_access_token(superuser_token_headers: Dict[str, str]) -> None:
25-
server_api = get_server_api()
26-
r = requests.post(
27-
f"{server_api}{settings.API_V1_STR}/login/test-token",
28-
headers=superuser_token_headers,
20+
def test_use_access_token(
21+
client: TestClient, superuser_token_headers: Dict[str, str]
22+
) -> None:
23+
r = client.post(
24+
f"{settings.API_V1_STR}/login/test-token", headers=superuser_token_headers,
2925
)
3026
result = r.json()
3127
assert r.status_code == 200

{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_users.py

+32-40
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
11
from typing import Dict
22

3-
import requests
3+
from fastapi.testclient import TestClient
44
from sqlalchemy.orm import Session
55

66
from app import crud
77
from app.core.config import settings
88
from app.schemas.user import UserCreate
9-
from app.tests.utils.utils import get_server_api, random_email, random_lower_string
9+
from app.tests.utils.utils import random_email, random_lower_string
1010

1111

12-
def test_get_users_superuser_me(superuser_token_headers: Dict[str, str]) -> None:
13-
server_api = get_server_api()
14-
r = requests.get(
15-
f"{server_api}{settings.API_V1_STR}/users/me", headers=superuser_token_headers
16-
)
12+
def test_get_users_superuser_me(
13+
client: TestClient, superuser_token_headers: Dict[str, str]
14+
) -> None:
15+
r = client.get(f"{settings.API_V1_STR}/users/me", headers=superuser_token_headers)
1716
current_user = r.json()
1817
assert current_user
1918
assert current_user["is_active"] is True
2019
assert current_user["is_superuser"]
2120
assert current_user["email"] == settings.FIRST_SUPERUSER
2221

2322

24-
def test_get_users_normal_user_me(normal_user_token_headers: Dict[str, str]) -> None:
25-
server_api = get_server_api()
26-
r = requests.get(
27-
f"{server_api}{settings.API_V1_STR}/users/me", headers=normal_user_token_headers
28-
)
23+
def test_get_users_normal_user_me(
24+
client: TestClient, normal_user_token_headers: Dict[str, str]
25+
) -> None:
26+
r = client.get(f"{settings.API_V1_STR}/users/me", headers=normal_user_token_headers)
2927
current_user = r.json()
3028
assert current_user
3129
assert current_user["is_active"] is True
3230
assert current_user["is_superuser"] is False
3331
assert current_user["email"] == settings.EMAIL_TEST_USER
3432

3533

36-
def test_create_user_new_email(superuser_token_headers: dict, db: Session) -> None:
37-
server_api = get_server_api()
34+
def test_create_user_new_email(
35+
client: TestClient, superuser_token_headers: dict, db: Session
36+
) -> None:
3837
username = random_email()
3938
password = random_lower_string()
4039
data = {"email": username, "password": password}
41-
r = requests.post(
42-
f"{server_api}{settings.API_V1_STR}/users/",
43-
headers=superuser_token_headers,
44-
json=data,
40+
r = client.post(
41+
f"{settings.API_V1_STR}/users/", headers=superuser_token_headers, json=data,
4542
)
4643
assert 200 <= r.status_code < 300
4744
created_user = r.json()
@@ -50,16 +47,16 @@ def test_create_user_new_email(superuser_token_headers: dict, db: Session) -> No
5047
assert user.email == created_user["email"]
5148

5249

53-
def test_get_existing_user(superuser_token_headers: dict, db: Session) -> None:
54-
server_api = get_server_api()
50+
def test_get_existing_user(
51+
client: TestClient, superuser_token_headers: dict, db: Session
52+
) -> None:
5553
username = random_email()
5654
password = random_lower_string()
5755
user_in = UserCreate(email=username, password=password)
5856
user = crud.user.create(db, obj_in=user_in)
5957
user_id = user.id
60-
r = requests.get(
61-
f"{server_api}{settings.API_V1_STR}/users/{user_id}",
62-
headers=superuser_token_headers,
58+
r = client.get(
59+
f"{settings.API_V1_STR}/users/{user_id}", headers=superuser_token_headers,
6360
)
6461
assert 200 <= r.status_code < 300
6562
api_user = r.json()
@@ -69,40 +66,37 @@ def test_get_existing_user(superuser_token_headers: dict, db: Session) -> None:
6966

7067

7168
def test_create_user_existing_username(
72-
superuser_token_headers: dict, db: Session
69+
client: TestClient, superuser_token_headers: dict, db: Session
7370
) -> None:
74-
server_api = get_server_api()
7571
username = random_email()
7672
# username = email
7773
password = random_lower_string()
7874
user_in = UserCreate(email=username, password=password)
7975
crud.user.create(db, obj_in=user_in)
8076
data = {"email": username, "password": password}
81-
r = requests.post(
82-
f"{server_api}{settings.API_V1_STR}/users/",
83-
headers=superuser_token_headers,
84-
json=data,
77+
r = client.post(
78+
f"{settings.API_V1_STR}/users/", headers=superuser_token_headers, json=data,
8579
)
8680
created_user = r.json()
8781
assert r.status_code == 400
8882
assert "_id" not in created_user
8983

9084

91-
def test_create_user_by_normal_user(normal_user_token_headers: Dict[str, str]) -> None:
92-
server_api = get_server_api()
85+
def test_create_user_by_normal_user(
86+
client: TestClient, normal_user_token_headers: Dict[str, str]
87+
) -> None:
9388
username = random_email()
9489
password = random_lower_string()
9590
data = {"email": username, "password": password}
96-
r = requests.post(
97-
f"{server_api}{settings.API_V1_STR}/users/",
98-
headers=normal_user_token_headers,
99-
json=data,
91+
r = client.post(
92+
f"{settings.API_V1_STR}/users/", headers=normal_user_token_headers, json=data,
10093
)
10194
assert r.status_code == 400
10295

10396

104-
def test_retrieve_users(superuser_token_headers: dict, db: Session) -> None:
105-
server_api = get_server_api()
97+
def test_retrieve_users(
98+
client: TestClient, superuser_token_headers: dict, db: Session
99+
) -> None:
106100
username = random_email()
107101
password = random_lower_string()
108102
user_in = UserCreate(email=username, password=password)
@@ -113,9 +107,7 @@ def test_retrieve_users(superuser_token_headers: dict, db: Session) -> None:
113107
user_in2 = UserCreate(email=username2, password=password2)
114108
crud.user.create(db, obj_in=user_in2)
115109

116-
r = requests.get(
117-
f"{server_api}{settings.API_V1_STR}/users/", headers=superuser_token_headers
118-
)
110+
r = client.get(f"{settings.API_V1_STR}/users/", headers=superuser_token_headers)
119111
all_users = r.json()
120112

121113
assert len(all_users) > 1
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
1-
from typing import Dict, Iterator
1+
from typing import Dict, Generator
22

33
import pytest
4+
from fastapi.testclient import TestClient
45
from sqlalchemy.orm import Session
56

67
from app.core.config import settings
78
from app.db.session import SessionLocal
9+
from app.main import app
810
from app.tests.utils.user import authentication_token_from_email
9-
from app.tests.utils.utils import get_server_api, get_superuser_token_headers
11+
from app.tests.utils.utils import get_superuser_token_headers
1012

1113

1214
@pytest.fixture(scope="session")
13-
def db() -> Iterator[Session]:
15+
def db() -> Generator:
1416
yield SessionLocal()
1517

1618

1719
@pytest.fixture(scope="module")
18-
def server_api() -> str:
19-
return get_server_api()
20+
def client() -> Generator:
21+
with TestClient(app) as c:
22+
yield c
2023

2124

2225
@pytest.fixture(scope="module")
23-
def superuser_token_headers() -> Dict[str, str]:
24-
return get_superuser_token_headers()
26+
def superuser_token_headers(client: TestClient) -> Dict[str, str]:
27+
return get_superuser_token_headers(client)
2528

2629

2730
@pytest.fixture(scope="module")
28-
def normal_user_token_headers(db: Session) -> Dict[str, str]:
29-
return authentication_token_from_email(email=settings.EMAIL_TEST_USER, db=db)
31+
def normal_user_token_headers(client: TestClient, db: Session) -> Dict[str, str]:
32+
return authentication_token_from_email(
33+
client=client, email=settings.EMAIL_TEST_USER, db=db
34+
)

{{cookiecutter.project_slug}}/backend/app/app/tests/utils/user.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
from typing import Dict
22

3-
import requests
3+
from fastapi.testclient import TestClient
44
from sqlalchemy.orm import Session
55

66
from app import crud
77
from app.core.config import settings
88
from app.models.user import User
99
from app.schemas.user import UserCreate, UserUpdate
10-
from app.tests.utils.utils import get_server_api, random_email, random_lower_string
10+
from app.tests.utils.utils import random_email, random_lower_string
1111

1212

1313
def user_authentication_headers(
14-
server_api: str, email: str, password: str
14+
*, client: TestClient, email: str, password: str
1515
) -> Dict[str, str]:
1616
data = {"username": email, "password": password}
1717

18-
r = requests.post(
19-
f"{server_api}{settings.API_V1_STR}/login/access-token", data=data
20-
)
18+
r = client.post(f"{settings.API_V1_STR}/login/access-token", data=data)
2119
response = r.json()
2220
auth_token = response["access_token"]
2321
headers = {"Authorization": f"Bearer {auth_token}"}
@@ -32,7 +30,9 @@ def create_random_user(db: Session) -> User:
3230
return user
3331

3432

35-
def authentication_token_from_email(*, email: str, db: Session) -> Dict[str, str]:
33+
def authentication_token_from_email(
34+
*, client: TestClient, email: str, db: Session
35+
) -> Dict[str, str]:
3636
"""
3737
Return a valid token for the user with given email.
3838
@@ -47,4 +47,4 @@ def authentication_token_from_email(*, email: str, db: Session) -> Dict[str, str
4747
user_in_update = UserUpdate(password=password)
4848
user = crud.user.update(db, db_obj=user, obj_in=user_in_update)
4949

50-
return user_authentication_headers(get_server_api(), email, password)
50+
return user_authentication_headers(client=client, email=email, password=password)

{{cookiecutter.project_slug}}/backend/app/app/tests/utils/utils.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import string
33
from typing import Dict
44

5-
import requests
5+
from fastapi.testclient import TestClient
66

77
from app.core.config import settings
88

@@ -15,22 +15,13 @@ def random_email() -> str:
1515
return f"{random_lower_string()}@{random_lower_string()}.com"
1616

1717

18-
def get_server_api() -> str:
19-
server_name = f"http://{settings.SERVER_NAME}"
20-
return server_name
21-
22-
23-
def get_superuser_token_headers() -> Dict[str, str]:
24-
server_api = get_server_api()
18+
def get_superuser_token_headers(client: TestClient) -> Dict[str, str]:
2519
login_data = {
2620
"username": settings.FIRST_SUPERUSER,
2721
"password": settings.FIRST_SUPERUSER_PASSWORD,
2822
}
29-
r = requests.post(
30-
f"{server_api}{settings.API_V1_STR}/login/access-token", data=login_data
31-
)
23+
r = client.post(f"{settings.API_V1_STR}/login/access-token", data=login_data)
3224
tokens = r.json()
3325
a_token = tokens["access_token"]
3426
headers = {"Authorization": f"Bearer {a_token}"}
35-
# superuser_token_headers = headers
3627
return headers

{{cookiecutter.project_slug}}/backend/app/app/tests_pre_start.py

-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
44

55
from app.db.session import SessionLocal
6-
from app.tests.api.api_v1.test_login import test_get_access_token
76

87
logging.basicConfig(level=logging.INFO)
98
logger = logging.getLogger(__name__)
@@ -23,8 +22,6 @@ def init() -> None:
2322
# Try to create session to check if DB is awake
2423
db = SessionLocal()
2524
db.execute("SELECT 1")
26-
# Wait for API to be awake, run one simple tests to authenticate
27-
test_get_access_token()
2825
except Exception as e:
2926
logger.error(e)
3027
raise e

0 commit comments

Comments
 (0)