Git Commit: unit test to verify getting a blog
Let's write one more unit test to get more familiar with unit testing. Ideally, We should have 100% coverage and test each of our routes. However, unit tests just follow a pattern, if you understand the pattern you can write a unit test for all the routes on your own.
This time let's tackle the get_blog route. In order to test fetching a blog, we must first create a blog then only we can fetch the blog. However, in order to create a blog we need to create a userπ€¦!
Since the transactions are rolled back and even the database is truncated on each unit test. All our unit tests are independent of each other. The user that we created in our last tutorial for the unit test of create_user route, no longer exists. Let's write some utility functions to create a random user and a random blog.
π backend/
ββπ .env
ββπ .env.example
ββπ alembic/
ββπ alembic.ini
ββπ apis/
ββπ core/
ββπ db/
ββπ main.py
ββπ requirements.txt
ββπ tests/
β ββπ conftest.py
β ββπ test_routes/
β ββπ test_blog.py #new
β ββπ test_user.py
β ββπ utils/
β ββπ blog.py #new
β ββπ user.py #new
In the file named tests > utils > user.py, We need to put the logic to create a new random user. We can utilize the repository to create a new user.
from sqlalchemy.orm import Session
from db.repository.user import create_new_user
from schemas.user import UserCreate
def create_random_user(db: Session):
user = UserCreate(email="[email protected]",password="Hello!")
user = create_new_user(user=user, db=db)
return user
This handles the responsibility of creating a new user and returning it, we can utilize this method in creating a new random blog at tests > utils> blog.py
from sqlalchemy.orm import Session
from db.repository.blog import create_new_blog
from schemas.blog import CreateBlog
from tests.utils.user import create_random_user
def create_random_blog(db: Session):
blog = CreateBlog(title="first_blog", content="Tests make the system stable!")
user = create_random_user(db=db)
blog = create_new_blog(blog=blog, db=db, author_id=user.id)
return blog
Now, we are good to create a test that fetches a blog from the get_blog() route.
from tests.utils.blog import create_random_blog
def test_should_fetch_blog_created(client, db_session):
blog = create_random_blog(db=db_session)
# print(blog.__dict__) #use pytest -s to see print statements
response = client.get(f"blog/{blog.id}/")
assert response.status_code == 200
assert response.json()["title"] == blog.title
Now, if you type in pytest. You should see 2 tests passing.
(env) C:\Users\nofoobar\fastapi-blog\backend > pytest
=================================================================== test session starts ===================================================================
platform win32 -- Python 3.9.6, pytest-7.4.0, pluggy-1.2.0
rootdir: C:\Users\nofoobar\fastapi-blog\backend
plugins: anyio-3.7.0
collected 2 items
tests\test_routes\test_blog.py . [ 50%]
tests\test_routes\test_user.py . [100%]
======================= 2 passed in 1.03s =======================
In case you want to debug a test, you can put some print statements and type pytest -s, this lets pytest know that it has to be verbose and show the output of print statements to stdout.
Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.
We know, we might make it hard for you but definitely worth the efforts.
Β© Copyright 2022-23 Team FastAPITutorial