Python Unit Testing | FastAPI with Pytest Tutorial (fast & easy)

  Рет қаралды 19,717

Eric Roby

Eric Roby

Күн бұрын

Пікірлер: 30
@laszlomagyar3156
@laszlomagyar3156 Жыл бұрын
The quality of your content is amazing! Keep up the good work!
@codingwithroby
@codingwithroby Жыл бұрын
I’m so glad you enjoy it 🙂
@vatsal_gamit
@vatsal_gamit 11 ай бұрын
This is my first video on tests in python and its worth watching !! Keep doing the great work man!! 🙌🏼
@codingwithroby
@codingwithroby 11 ай бұрын
Thanks, will do!
@prasenjitgiri919
@prasenjitgiri919 Жыл бұрын
are you runnig the main,py before running the test ? and what if the main.py file reads from os environment variables - how do you handle it without running the main file? - btw, great video!
@tenzingyatso5096
@tenzingyatso5096 Жыл бұрын
Nice! Could you make the same with async test and test db (postgres)?
@jordiprim2668
@jordiprim2668 4 күн бұрын
One question: if I change de order in the tests does not work, I mean, when the test_create_todo() goes first, then the test_read_todos() returns one element, so assert response.json()==[] is not true. Yes, I know thant there is setup_function, but does not efect the response.json(). I check also with fixture(autouse=True) and nothing changes...Do you know something about that? Thanks. Jordi.
@codingwithroby
@codingwithroby 3 күн бұрын
Hey there! Your issue is happening because we are not returning a new client each time. What you need to do is create a new @pytest.fixture and also return the TestClient. I think you'd want something like: from fastapi.testclient import TestClient import pytest from .main import app, todos @pytest.fixture(autouse=True) def client(): # Clear the todos before each test todos.clear() # Create a fresh client for each test return TestClient(app) # Remove the setup_function as we're using fixture now def test_read_todos(client): response = client.get("/") assert response.status_code == 200 assert response.json() == [] def test_create_todo(client): response = client.post("/", json={"name": "Buy groceries", "completed": False}) assert response.status_code == 200 assert response.json() == {"name": "Buy groceries", "completed": False} // ... existing code for other test functions ... -- Make sure you pass in client to each test function due to us now using a pytest fixture.
@jordiprim2668
@jordiprim2668 3 күн бұрын
@@codingwithroby I understant what you mean, but the same happends with your code. If I run the test (test_get_totes_imatges) (test_get_all_images in english) alone works, but if I run all the tests no. I'm not pretending you analize all the code for me, but here it is, just in case you are bored :p -----------------------tests------------------ import pytest from fastapi.testclient import TestClient from main import app from dades.dades import imatges_db import logging import json @pytest.fixture(autouse=True) def client(): imatges_db["imatges"].clear() imatges_db["imatges"] = ([ {"id_imatge": 1, "nom_fotograf": "Joan", "titol_imatge": "Lluna plena", "descripcio_imatge": "Vista espectacular de la lluna"}, {"id_imatge": 2, "nom_fotograf": "Pep", "titol_imatge": "Ciutat de nit", "descripcio_imatge": "Vista espectacular ciutat per la nit"}, {"id_imatge": 3, "nom_fotograf": "Maria", "titol_imatge": "Ciutat de dia", "descripcio_imatge": "Vista espectacular ciutat pel dia"}, {"id_imatge": 4, "nom_fotograf": "Miriam", "titol_imatge": "Ciutat al migdia", "descripcio_imatge": "Vista espectacular ciutat al migdia"} ]) return TestClient(app) # Tests def test_create_new_imatge(client): nova_imatge = { "id_imatge": 5, "nom_fotograf": "Anna", "titol_imatge": "Nova imatge", "descripcio_imatge": "Una descripció nova." } response = client.post("/nova_imatge", json=nova_imatge) assert response.status_code == 200 assert response.json() == nova_imatge def test_create_duplicate_imatge(client): nova_imatge = { "id_imatge": 1, "nom_fotograf": "Joan", "titol_imatge": "Lluna plena", "descripcio_imatge": "Vista espectacular de la lluna" } response = client.post("/nova_imatge", json=nova_imatge) assert response.status_code == 400 assert response.json()["detail"] == "Codi ja existeix" def test_get_totes_imatges(client): response = client.get("/totes_imatges") assert response.status_code == 200 logging.info("RESPONSE JSON......: %s", response.json()) assert response.json() == imatges_db["imatges"] -------------------------------------error or not error (if alone)---------------------------------------------------------- pytest -k "totes" ======================================================== test session starts ========================================================= platform linux -- Python 3.12.3, pytest-8.3.4, pluggy-1.5.0 rootdir: /home/jordi/Documents/fastapi/imatges_test_fakedb configfile: pyproject.toml plugins: asyncio-0.25.2, anyio-4.7.0 asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=function collected 3 items / 2 deselected / 1 selected test_imatges.py . [100%] ================================================== 1 passed, 2 deselected in 0.31s =================================================== (venv) jordi@jordi-Lenovo-ThinkBook-15-IIL:~/Documents/fastapi/imatges_test_fakedb/app$ pytest -v ======================================================== test session starts ========================================================= platform linux -- Python 3.12.3, pytest-8.3.4, pluggy-1.5.0 -- /home/jordi/Documents/fastapi/imatges_test_fakedb/venv/bin/python cachedir: .pytest_cache rootdir: /home/jordi/Documents/fastapi/imatges_test_fakedb configfile: pyproject.toml plugins: asyncio-0.25.2, anyio-4.7.0 asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=function collected 3 items test_imatges.py::test_create_new_imatge PASSED [ 33%] test_imatges.py::test_create_duplicate_imatge PASSED [ 66%] test_imatges.py::test_get_totes_imatges FAILED [100%] ============================================================== FAILURES ============================================================== _______________________________________________________ test_get_totes_imatges _______________________________________________________ client = def test_get_totes_imatges(client): response = client.get("/totes_imatges") assert response.status_code == 200 logging.info("RESPONSE JSON......: %s", response.json()) > assert response.json() == imatges_db["imatges"] E AssertionError: assert [{'descripcio...Nova imatge'}] == [{'descripcio...t al migdia'}] E E Left contains one more item: {'descripcio_imatge': 'Una descripció nova.', 'id_imatge': 5, 'nom_fotograf': 'Anna', 'titol_imatge': 'Nova imatge'} E E Full diff: E [ E { E 'descripcio_imatge': 'Vista espectacular de la lluna',... E E ...Full output truncated (29 lines hidden), use '-vv' to show test_imatges.py:48: AssertionError ====================================================== short test summary info ======================================================= FAILED test_imatges.py::test_get_totes_imatges - AssertionError: assert [{'descripcio...Nova imatge'}] == [{'descripcio...t al migdia'}] ==================================================== 1 failed, 2 passed in 0.33s ============== Even if you analize my code or not I love your videos. I will change the order and thats it. Thanks for your help Eric!
@Ruthwikranganathbethapudi
@Ruthwikranganathbethapudi Жыл бұрын
How to unit test a FastAPI which is connected to Sqlite?
@h3ct0rjs
@h3ct0rjs 11 ай бұрын
Thanks for this, have you test Tavern which can be used to run this test to using yaml and python ?
@codingwithroby
@codingwithroby 11 ай бұрын
Oh interesting - I have never seen this before.
@davidinawe791
@davidinawe791 10 ай бұрын
Hello. I have a question for fastapi testing with pytest and if someone could help me it would be very much appreciated! Essentially, what I need to do within my test is to simulate a server restart. But I do not understand how the server is actually started in pytest. We are running our API with hypercorn. Hypercorns serv() function in our main.py takes the app as a parameter and from my understanding runs the server like you normally would with "hypercorn main:app" by just running the main.py. I just don't understand how the server is actually started with pytest. All we do in pytest (same as in this video) is to define the TestClient, but from my understanding the TestClient is only the one ACCESSING the server that is already running. Therfore I don't know how I could simulate a restart of the server in pytest (like stopping and restarting the execution of "hypercorn main:app" in cmd). Could anyone help me out here and tell me what I am misunderstanding?
@zeldacamila
@zeldacamila 8 ай бұрын
How to unit test a FastAPI which is connected to postgresql, on a CI environment (using github actions)??
@codingwithroby
@codingwithroby 8 ай бұрын
Same way - I'd suggest use SQLite3 and create a separate testing database and not use a production database like PostgreSQL or MySQL
@DhavalAhir10
@DhavalAhir10 3 ай бұрын
Ohhh, I thought pytest is only for Django based project. In Django we used Rq Worker or Celery. What it is in fastapi?
@codingwithroby
@codingwithroby 3 ай бұрын
Celery often times. You can use whatever you'd like!
@DhavalAhir10
@DhavalAhir10 3 ай бұрын
@@codingwithroby Thanks :)
@amadzarak7746
@amadzarak7746 6 ай бұрын
Great vid!
@codingwithroby
@codingwithroby 6 ай бұрын
Thank you sir!
@adithyayelloju8296
@adithyayelloju8296 9 ай бұрын
When test cases become larger, How to refactor them?
@codingwithroby
@codingwithroby 7 ай бұрын
Structure by business functionality. If you are testing more than 1 thing, break it into two tests.
@hemantgiri2377
@hemantgiri2377 Жыл бұрын
sir, please make a video on fastapi with mvc architecture with celery and and redis.
@codingwithroby
@codingwithroby Жыл бұрын
Not a bad idea 🙂
@nuri3029
@nuri3029 Жыл бұрын
Great! Thank you
@codingwithroby
@codingwithroby Жыл бұрын
You’re welcome! I am glad you found value 🙂
@CodingStudio
@CodingStudio Жыл бұрын
but this is not unittesting? this is integration tests?
@codingwithroby
@codingwithroby Жыл бұрын
Well, you are not completely wrong. This would be considered integration testing but we do not really have a service layer here so it incorporates them both.
@AlexanderLindholm-z1q
@AlexanderLindholm-z1q 3 күн бұрын
You didn't test status code 400
@codingwithroby
@codingwithroby Күн бұрын
I must have forgotten, feel free to test 400 on your side!
Design Scalable Apps with CQRS and FastAPI (easy)
8:50
Eric Roby
Рет қаралды 3,5 М.
How To Write Unit Tests in Python • Pytest Tutorial
35:34
pixegami
Рет қаралды 155 М.
VIP ACCESS
00:47
Natan por Aí
Рет қаралды 30 МЛН
When you have a very capricious child 😂😘👍
00:16
Like Asiya
Рет қаралды 18 МЛН
Sigma Kid Mistake #funny #sigma
00:17
CRAZY GREAPA
Рет қаралды 30 МЛН
Python Tutorial: Unit Testing Your Code with the unittest Module
39:13
Corey Schafer
Рет қаралды 1,4 МЛН
Pydantic Has Saved Me Countless Hours Of Debugging
14:52
Eric Roby
Рет қаралды 7 М.
Please Master This MAGIC Python Feature... 🪄
25:10
Tech With Tim
Рет қаралды 145 М.
Pytest Tutorial - How to Test Python Code
1:28:39
freeCodeCamp.org
Рет қаралды 238 М.
Intro to Python Mocks | Python tutorial
18:42
Red Eyed Coder Club
Рет қаралды 90 М.
How To Write Unit Tests For Existing Python Code // Part 1 of 2
25:07
Python Web Apps: Testing with Pytest and Playwright
1:31:29
Microsoft Reactor
Рет қаралды 2,5 М.
VIP ACCESS
00:47
Natan por Aí
Рет қаралды 30 МЛН