From 41cde292410e588211b4772e5331f9d8adc3d8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 24 Aug 2022 11:26:51 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20examples=20for=20testi?= =?UTF-8?q?ng=20with=20absolute=20imports,=20and=20fix=20the=20correspondi?= =?UTF-8?q?ng=20tests=20for=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs_src/app_testing/app_b/test_main.py | 3 +-- docs_src/app_testing/app_b_py310/test_main.py | 3 +-- docs_src/app_testing/test_main.py | 3 +-- tests/test_tutorial/test_testing/test_main.py | 16 +++++++++++----- tests/test_tutorial/test_testing/test_main_b.py | 11 ++++++++++- .../test_testing/test_main_b_py310.py | 9 +++++++++ 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/docs_src/app_testing/app_b/test_main.py b/docs_src/app_testing/app_b/test_main.py index d186b8ecbacfa..5be1d9e16ab59 100644 --- a/docs_src/app_testing/app_b/test_main.py +++ b/docs_src/app_testing/app_b/test_main.py @@ -1,6 +1,5 @@ from fastapi.testclient import TestClient - -from .main import app +from main import app client = TestClient(app) diff --git a/docs_src/app_testing/app_b_py310/test_main.py b/docs_src/app_testing/app_b_py310/test_main.py index d186b8ecbacfa..5be1d9e16ab59 100644 --- a/docs_src/app_testing/app_b_py310/test_main.py +++ b/docs_src/app_testing/app_b_py310/test_main.py @@ -1,6 +1,5 @@ from fastapi.testclient import TestClient - -from .main import app +from main import app client = TestClient(app) diff --git a/docs_src/app_testing/test_main.py b/docs_src/app_testing/test_main.py index ddc013f40c502..6c012cd428dad 100644 --- a/docs_src/app_testing/test_main.py +++ b/docs_src/app_testing/test_main.py @@ -1,6 +1,5 @@ from fastapi.testclient import TestClient - -from .main import app +from main import app client = TestClient(app) diff --git a/tests/test_tutorial/test_testing/test_main.py b/tests/test_tutorial/test_testing/test_main.py index e6747fffd0a1b..d6c11c37909ab 100644 --- a/tests/test_tutorial/test_testing/test_main.py +++ b/tests/test_tutorial/test_testing/test_main.py @@ -1,4 +1,5 @@ -from docs_src.app_testing.test_main import client, test_read_main +import sys +from pathlib import Path openapi_schema = { "openapi": "3.0.2", @@ -20,11 +21,16 @@ } -def test_openapi_schema(): +def test_testing(): + current_path = sys.path.copy() + import docs_src.app_testing + + testing_path = Path(docs_src.app_testing.__file__).parent + sys.path.append(str(testing_path)) + from docs_src.app_testing.test_main import client, test_read_main + response = client.get("/openapi.json") assert response.status_code == 200, response.text assert response.json() == openapi_schema - - -def test_main(): test_read_main() + sys.path = current_path diff --git a/tests/test_tutorial/test_testing/test_main_b.py b/tests/test_tutorial/test_testing/test_main_b.py index fc1a832f99620..e36abca807bc3 100644 --- a/tests/test_tutorial/test_testing/test_main_b.py +++ b/tests/test_tutorial/test_testing/test_main_b.py @@ -1,10 +1,19 @@ -from docs_src.app_testing.app_b import test_main +import sys +from pathlib import Path def test_app(): + current_path = sys.path.copy() + import docs_src.app_testing.app_b + + testing_path = Path(docs_src.app_testing.app_b.__file__).parent + sys.path.append(str(testing_path)) + from docs_src.app_testing.app_b import test_main + test_main.test_create_existing_item() test_main.test_create_item() test_main.test_create_item_bad_token() test_main.test_read_inexistent_item() test_main.test_read_item() test_main.test_read_item_bad_token() + sys.path = current_path diff --git a/tests/test_tutorial/test_testing/test_main_b_py310.py b/tests/test_tutorial/test_testing/test_main_b_py310.py index a504ed2346edf..61be9dfacb255 100644 --- a/tests/test_tutorial/test_testing/test_main_b_py310.py +++ b/tests/test_tutorial/test_testing/test_main_b_py310.py @@ -1,8 +1,16 @@ +import sys +from pathlib import Path + from ...utils import needs_py310 @needs_py310 def test_app(): + current_path = sys.path.copy() + import docs_src.app_testing.app_b_py310 + + testing_path = Path(docs_src.app_testing.app_b_py310.__file__).parent + sys.path.append(str(testing_path)) from docs_src.app_testing.app_b_py310 import test_main test_main.test_create_existing_item() @@ -11,3 +19,4 @@ def test_app(): test_main.test_read_inexistent_item() test_main.test_read_item() test_main.test_read_item_bad_token() + sys.path = current_path From 7fc989a0ebb9fe55f00731d6a0e105bd6e886814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 24 Aug 2022 14:47:40 +0200 Subject: [PATCH 2/4] =?UTF-8?q?=E2=8F=AA=20Undo=20all=20the=20weird=20tric?= =?UTF-8?q?ks=20to=20overcome=20absolute=20imports=20while=20testing=20wit?= =?UTF-8?q?h=20relative=20imports,=20they=20didn't=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs_src/app_testing/app_b/test_main.py | 3 ++- docs_src/app_testing/app_b_py310/test_main.py | 3 ++- docs_src/app_testing/test_main.py | 3 ++- tests/test_tutorial/test_testing/test_main.py | 16 +++++----------- tests/test_tutorial/test_testing/test_main_b.py | 11 +---------- .../test_testing/test_main_b_py310.py | 9 --------- 6 files changed, 12 insertions(+), 33 deletions(-) diff --git a/docs_src/app_testing/app_b/test_main.py b/docs_src/app_testing/app_b/test_main.py index 5be1d9e16ab59..d186b8ecbacfa 100644 --- a/docs_src/app_testing/app_b/test_main.py +++ b/docs_src/app_testing/app_b/test_main.py @@ -1,5 +1,6 @@ from fastapi.testclient import TestClient -from main import app + +from .main import app client = TestClient(app) diff --git a/docs_src/app_testing/app_b_py310/test_main.py b/docs_src/app_testing/app_b_py310/test_main.py index 5be1d9e16ab59..d186b8ecbacfa 100644 --- a/docs_src/app_testing/app_b_py310/test_main.py +++ b/docs_src/app_testing/app_b_py310/test_main.py @@ -1,5 +1,6 @@ from fastapi.testclient import TestClient -from main import app + +from .main import app client = TestClient(app) diff --git a/docs_src/app_testing/test_main.py b/docs_src/app_testing/test_main.py index 6c012cd428dad..ddc013f40c502 100644 --- a/docs_src/app_testing/test_main.py +++ b/docs_src/app_testing/test_main.py @@ -1,5 +1,6 @@ from fastapi.testclient import TestClient -from main import app + +from .main import app client = TestClient(app) diff --git a/tests/test_tutorial/test_testing/test_main.py b/tests/test_tutorial/test_testing/test_main.py index d6c11c37909ab..e6747fffd0a1b 100644 --- a/tests/test_tutorial/test_testing/test_main.py +++ b/tests/test_tutorial/test_testing/test_main.py @@ -1,5 +1,4 @@ -import sys -from pathlib import Path +from docs_src.app_testing.test_main import client, test_read_main openapi_schema = { "openapi": "3.0.2", @@ -21,16 +20,11 @@ } -def test_testing(): - current_path = sys.path.copy() - import docs_src.app_testing - - testing_path = Path(docs_src.app_testing.__file__).parent - sys.path.append(str(testing_path)) - from docs_src.app_testing.test_main import client, test_read_main - +def test_openapi_schema(): response = client.get("/openapi.json") assert response.status_code == 200, response.text assert response.json() == openapi_schema + + +def test_main(): test_read_main() - sys.path = current_path diff --git a/tests/test_tutorial/test_testing/test_main_b.py b/tests/test_tutorial/test_testing/test_main_b.py index e36abca807bc3..fc1a832f99620 100644 --- a/tests/test_tutorial/test_testing/test_main_b.py +++ b/tests/test_tutorial/test_testing/test_main_b.py @@ -1,19 +1,10 @@ -import sys -from pathlib import Path +from docs_src.app_testing.app_b import test_main def test_app(): - current_path = sys.path.copy() - import docs_src.app_testing.app_b - - testing_path = Path(docs_src.app_testing.app_b.__file__).parent - sys.path.append(str(testing_path)) - from docs_src.app_testing.app_b import test_main - test_main.test_create_existing_item() test_main.test_create_item() test_main.test_create_item_bad_token() test_main.test_read_inexistent_item() test_main.test_read_item() test_main.test_read_item_bad_token() - sys.path = current_path diff --git a/tests/test_tutorial/test_testing/test_main_b_py310.py b/tests/test_tutorial/test_testing/test_main_b_py310.py index 61be9dfacb255..a504ed2346edf 100644 --- a/tests/test_tutorial/test_testing/test_main_b_py310.py +++ b/tests/test_tutorial/test_testing/test_main_b_py310.py @@ -1,16 +1,8 @@ -import sys -from pathlib import Path - from ...utils import needs_py310 @needs_py310 def test_app(): - current_path = sys.path.copy() - import docs_src.app_testing.app_b_py310 - - testing_path = Path(docs_src.app_testing.app_b_py310.__file__).parent - sys.path.append(str(testing_path)) from docs_src.app_testing.app_b_py310 import test_main test_main.test_create_existing_item() @@ -19,4 +11,3 @@ def test_app(): test_main.test_read_inexistent_item() test_main.test_read_item() test_main.test_read_item_bad_token() - sys.path = current_path From 0ed24357ea6cc8ce8bd1260e702e562b08e17ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 24 Aug 2022 14:48:27 +0200 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9D=20Update=20Testing=20docs=20to?= =?UTF-8?q?=20explain=20how=20to=20handle=20packages=20and=20relative=20im?= =?UTF-8?q?ports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/advanced/async-tests.md | 14 ++++++++-- docs/en/docs/tutorial/testing.md | 38 +++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/docs/en/docs/advanced/async-tests.md b/docs/en/docs/advanced/async-tests.md index d5116233f8c55..e34f48f1732fa 100644 --- a/docs/en/docs/advanced/async-tests.md +++ b/docs/en/docs/advanced/async-tests.md @@ -26,13 +26,23 @@ The important difference for us is that with HTTPX we are not limited to synchro ## Example -For a simple example, let's consider the following `main.py` module: +For a simple example, let's consider a file structure similar to the one described in [Bigger Applications](../tutorial/bigger-applications.md){.internal-link target=_blank} and [Testing](../tutorial/testing.md){.internal-link target=_blank}: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── test_main.py +``` + +The file `main.py` would have: ```Python {!../../../docs_src/async_tests/main.py!} ``` -The `test_main.py` module that contains the tests for `main.py` could look like this now: +The file `test_main.py` would have the tests for `main.py`, it could look like this now: ```Python {!../../../docs_src/async_tests/test_main.py!} diff --git a/docs/en/docs/tutorial/testing.md b/docs/en/docs/tutorial/testing.md index 79ea2b1ab58b8..d2ccd7dc77d45 100644 --- a/docs/en/docs/tutorial/testing.md +++ b/docs/en/docs/tutorial/testing.md @@ -50,7 +50,17 @@ And your **FastAPI** application might also be composed of several files/modules ### **FastAPI** app file -Let's say you have a file `main.py` with your **FastAPI** app: +Let's say you have a file structure as described in [Bigger Applications](./bigger-applications.md){.internal-link target=_blank}: + +``` +. +├── app +│   ├── __init__.py +│   └── main.py +``` + +In the file `main.py` you have your **FastAPI** app: + ```Python {!../../../docs_src/app_testing/main.py!} @@ -58,18 +68,40 @@ Let's say you have a file `main.py` with your **FastAPI** app: ### Testing file -Then you could have a file `test_main.py` with your tests, and import your `app` from the `main` module (`main.py`): +Then you could have a file `test_main.py` with your tests. It could live on the same Python package (the same directory with a `__init__.py` file): -```Python +``` hl_lines="5" +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── test_main.py +``` + +Because this file is in the same package, you can use relative imports to import the object `app` from the `main` module (`main.py`): + +```Python hl_lines="3" {!../../../docs_src/app_testing/test_main.py!} ``` +...and have the code for the tests just like before. + ## Testing: extended example Now let's extend this example and add more details to see how to test different parts. ### Extended **FastAPI** app file +Let's continue with the same file structure as before: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── test_main.py +``` + Let's say that now the file `main.py` with your **FastAPI** app has some other **path operations**. It has a `GET` operation that could return an error. From 3164a2ac39b751ebf584ec481df0f47b2aa3e64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 24 Aug 2022 16:13:24 +0200 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=91=B7=20Trigger=20CI=20because=20Cod?= =?UTF-8?q?ecov=20is=20behaving?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit