]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✅ Simplify tests for request_files (#13182)
authorAlejandra <90076947+alejsdev@users.noreply.github.com>
Thu, 30 Jan 2025 12:04:34 +0000 (12:04 +0000)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2025 12:04:34 +0000 (12:04 +0000)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
24 files changed:
tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an.py [deleted file]
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py310.py [deleted file]
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py39.py [deleted file]
tests/test_tutorial/test_body_multiple_params/test_tutorial003_py310.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001.py
tests/test_tutorial/test_request_files/test_tutorial001_02.py
tests/test_tutorial/test_request_files/test_tutorial001_02_an.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_02_an_py310.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_02_an_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_02_py310.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_03.py
tests/test_tutorial/test_request_files/test_tutorial001_03_an.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_03_an_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_an.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial001_an_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial002.py
tests/test_tutorial/test_request_files/test_tutorial002_an.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial002_an_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial002_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial003.py
tests/test_tutorial/test_request_files/test_tutorial003_an.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial003_an_py39.py [deleted file]
tests/test_tutorial/test_request_files/test_tutorial003_py39.py [deleted file]

index c26f8b89bce374056136129dda8261440e557151..d18ceae4862c5b809ce67c315bf5889faff5956f 100644 (file)
@@ -1,13 +1,26 @@
+import importlib
+
 import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
+from ...utils import needs_py39, needs_py310
+
 
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.body_multiple_params.tutorial003 import app
+@pytest.fixture(
+    name="client",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+        "tutorial003_an",
+        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py310", marks=needs_py310),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.body_multiple_params.{request.param}")
 
-    client = TestClient(app)
+    client = TestClient(mod.app)
     return client
 
 
diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an.py
deleted file mode 100644 (file)
index 62c7e2f..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.body_multiple_params.tutorial003_an import app
-
-    client = TestClient(app)
-    return client
-
-
-def test_post_body_valid(client: TestClient):
-    response = client.put(
-        "/items/5",
-        json={
-            "importance": 2,
-            "item": {"name": "Foo", "price": 50.5},
-            "user": {"username": "Dave"},
-        },
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "item_id": 5,
-        "importance": 2,
-        "item": {
-            "name": "Foo",
-            "price": 50.5,
-            "description": None,
-            "tax": None,
-        },
-        "user": {"username": "Dave", "full_name": None},
-    }
-
-
-def test_post_body_no_data(client: TestClient):
-    response = client.put("/items/5", json=None)
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-def test_post_body_empty_list(client: TestClient):
-    response = client.put("/items/5", json=[])
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "put": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "integer"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": IsDict(
-                            {
-                                "title": "Description",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Description", "type": "string"}
-                        ),
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": IsDict(
-                            {
-                                "title": "Tax",
-                                "anyOf": [{"type": "number"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Tax", "type": "number"}
-                        ),
-                    },
-                },
-                "User": {
-                    "title": "User",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {
-                        "username": {"title": "Username", "type": "string"},
-                        "full_name": IsDict(
-                            {
-                                "title": "Full Name",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Full Name", "type": "string"}
-                        ),
-                    },
-                },
-                "Body_update_item_items__item_id__put": {
-                    "title": "Body_update_item_items__item_id__put",
-                    "required": ["item", "user", "importance"],
-                    "type": "object",
-                    "properties": {
-                        "item": {"$ref": "#/components/schemas/Item"},
-                        "user": {"$ref": "#/components/schemas/User"},
-                        "importance": {"title": "Importance", "type": "integer"},
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py310.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py310.py
deleted file mode 100644 (file)
index f46430f..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.body_multiple_params.tutorial003_an_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py310
-def test_post_body_valid(client: TestClient):
-    response = client.put(
-        "/items/5",
-        json={
-            "importance": 2,
-            "item": {"name": "Foo", "price": 50.5},
-            "user": {"username": "Dave"},
-        },
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "item_id": 5,
-        "importance": 2,
-        "item": {
-            "name": "Foo",
-            "price": 50.5,
-            "description": None,
-            "tax": None,
-        },
-        "user": {"username": "Dave", "full_name": None},
-    }
-
-
-@needs_py310
-def test_post_body_no_data(client: TestClient):
-    response = client.put("/items/5", json=None)
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py310
-def test_post_body_empty_list(client: TestClient):
-    response = client.put("/items/5", json=[])
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "put": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "integer"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": IsDict(
-                            {
-                                "title": "Description",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Description", "type": "string"}
-                        ),
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": IsDict(
-                            {
-                                "title": "Tax",
-                                "anyOf": [{"type": "number"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Tax", "type": "number"}
-                        ),
-                    },
-                },
-                "User": {
-                    "title": "User",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {
-                        "username": {"title": "Username", "type": "string"},
-                        "full_name": IsDict(
-                            {
-                                "title": "Full Name",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Full Name", "type": "string"}
-                        ),
-                    },
-                },
-                "Body_update_item_items__item_id__put": {
-                    "title": "Body_update_item_items__item_id__put",
-                    "required": ["item", "user", "importance"],
-                    "type": "object",
-                    "properties": {
-                        "item": {"$ref": "#/components/schemas/Item"},
-                        "user": {"$ref": "#/components/schemas/User"},
-                        "importance": {"title": "Importance", "type": "integer"},
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py39.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py39.py
deleted file mode 100644 (file)
index 29071cd..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.body_multiple_params.tutorial003_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py39
-def test_post_body_valid(client: TestClient):
-    response = client.put(
-        "/items/5",
-        json={
-            "importance": 2,
-            "item": {"name": "Foo", "price": 50.5},
-            "user": {"username": "Dave"},
-        },
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "item_id": 5,
-        "importance": 2,
-        "item": {
-            "name": "Foo",
-            "price": 50.5,
-            "description": None,
-            "tax": None,
-        },
-        "user": {"username": "Dave", "full_name": None},
-    }
-
-
-@needs_py39
-def test_post_body_no_data(client: TestClient):
-    response = client.put("/items/5", json=None)
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_body_empty_list(client: TestClient):
-    response = client.put("/items/5", json=[])
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "put": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "integer"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": IsDict(
-                            {
-                                "title": "Description",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Description", "type": "string"}
-                        ),
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": IsDict(
-                            {
-                                "title": "Tax",
-                                "anyOf": [{"type": "number"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Tax", "type": "number"}
-                        ),
-                    },
-                },
-                "User": {
-                    "title": "User",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {
-                        "username": {"title": "Username", "type": "string"},
-                        "full_name": IsDict(
-                            {
-                                "title": "Full Name",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Full Name", "type": "string"}
-                        ),
-                    },
-                },
-                "Body_update_item_items__item_id__put": {
-                    "title": "Body_update_item_items__item_id__put",
-                    "required": ["item", "user", "importance"],
-                    "type": "object",
-                    "properties": {
-                        "item": {"$ref": "#/components/schemas/Item"},
-                        "user": {"$ref": "#/components/schemas/User"},
-                        "importance": {"title": "Importance", "type": "integer"},
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_body_multiple_params/test_tutorial003_py310.py b/tests/test_tutorial/test_body_multiple_params/test_tutorial003_py310.py
deleted file mode 100644 (file)
index 133afe9..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.body_multiple_params.tutorial003_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py310
-def test_post_body_valid(client: TestClient):
-    response = client.put(
-        "/items/5",
-        json={
-            "importance": 2,
-            "item": {"name": "Foo", "price": 50.5},
-            "user": {"username": "Dave"},
-        },
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "item_id": 5,
-        "importance": 2,
-        "item": {
-            "name": "Foo",
-            "price": 50.5,
-            "description": None,
-            "tax": None,
-        },
-        "user": {"username": "Dave", "full_name": None},
-    }
-
-
-@needs_py310
-def test_post_body_no_data(client: TestClient):
-    response = client.put("/items/5", json=None)
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py310
-def test_post_body_empty_list(client: TestClient):
-    response = client.put("/items/5", json=[])
-    assert response.status_code == 422
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "item"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "user"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-                {
-                    "type": "missing",
-                    "loc": ["body", "importance"],
-                    "msg": "Field required",
-                    "input": None,
-                },
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "item"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "user"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-                {
-                    "loc": ["body", "importance"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                },
-            ]
-        }
-    )
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "put": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "integer"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": IsDict(
-                            {
-                                "title": "Description",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Description", "type": "string"}
-                        ),
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": IsDict(
-                            {
-                                "title": "Tax",
-                                "anyOf": [{"type": "number"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Tax", "type": "number"}
-                        ),
-                    },
-                },
-                "User": {
-                    "title": "User",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {
-                        "username": {"title": "Username", "type": "string"},
-                        "full_name": IsDict(
-                            {
-                                "title": "Full Name",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "Full Name", "type": "string"}
-                        ),
-                    },
-                },
-                "Body_update_item_items__item_id__put": {
-                    "title": "Body_update_item_items__item_id__put",
-                    "required": ["item", "user", "importance"],
-                    "type": "object",
-                    "properties": {
-                        "item": {"$ref": "#/components/schemas/Item"},
-                        "user": {"$ref": "#/components/schemas/User"},
-                        "importance": {"title": "Importance", "type": "integer"},
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index f5817593bbf885ad5aa7748a0084d63bd23fbe38..b06919961288481a7d385db73fb16a8fdca8a9f1 100644 (file)
@@ -1,23 +1,28 @@
+import importlib
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.request_files.tutorial001 import app
+from ...utils import needs_py39
 
-client = TestClient(app)
 
+@pytest.fixture(
+    name="client",
+    params=[
+        "tutorial001",
+        "tutorial001_an",
+        pytest.param("tutorial001_an_py39", marks=needs_py39),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.request_files.{request.param}")
 
-file_required = {
-    "detail": [
-        {
-            "loc": ["body", "file"],
-            "msg": "field required",
-            "type": "value_error.missing",
-        }
-    ]
-}
+    client = TestClient(mod.app)
+    return client
 
 
-def test_post_form_no_body():
+def test_post_form_no_body(client: TestClient):
     response = client.post("/files/")
     assert response.status_code == 422, response.text
     assert response.json() == IsDict(
@@ -45,7 +50,7 @@ def test_post_form_no_body():
     )
 
 
-def test_post_body_json():
+def test_post_body_json(client: TestClient):
     response = client.post("/files/", json={"file": "Foo"})
     assert response.status_code == 422, response.text
     assert response.json() == IsDict(
@@ -73,41 +78,38 @@ def test_post_body_json():
     )
 
 
-def test_post_file(tmp_path):
+def test_post_file(tmp_path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/files/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"file_size": 14}
 
 
-def test_post_large_file(tmp_path):
+def test_post_large_file(tmp_path, client: TestClient):
     default_pydantic_max_size = 2**16
     path = tmp_path / "test.txt"
     path.write_bytes(b"x" * (default_pydantic_max_size + 1))
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/files/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"file_size": default_pydantic_max_size + 1}
 
 
-def test_post_upload_file(tmp_path):
+def test_post_upload_file(tmp_path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/uploadfile/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"filename": "test.txt"}
 
 
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
     assert response.json() == {
index 42f75442a54899ede263fde35862ade21ede36e5..9075a1756194d25a2385a7410b800fbb9c5a3c00 100644 (file)
@@ -1,46 +1,63 @@
+import importlib
+from pathlib import Path
+
+import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.request_files.tutorial001_02 import app
+from ...utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+    name="client",
+    params=[
+        "tutorial001_02",
+        pytest.param("tutorial001_02_py310", marks=needs_py310),
+        "tutorial001_02_an",
+        pytest.param("tutorial001_02_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_02_an_py310", marks=needs_py310),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.request_files.{request.param}")
 
-client = TestClient(app)
+    client = TestClient(mod.app)
+    return client
 
 
-def test_post_form_no_body():
+def test_post_form_no_body(client: TestClient):
     response = client.post("/files/")
     assert response.status_code == 200, response.text
     assert response.json() == {"message": "No file sent"}
 
 
-def test_post_uploadfile_no_body():
+def test_post_uploadfile_no_body(client: TestClient):
     response = client.post("/uploadfile/")
     assert response.status_code == 200, response.text
     assert response.json() == {"message": "No upload file sent"}
 
 
-def test_post_file(tmp_path):
+def test_post_file(tmp_path: Path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/files/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"file_size": 14}
 
 
-def test_post_upload_file(tmp_path):
+def test_post_upload_file(tmp_path: Path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/uploadfile/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"filename": "test.txt"}
 
 
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
     assert response.json() == {
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_02_an.py b/tests/test_tutorial/test_request_files/test_tutorial001_02_an.py
deleted file mode 100644 (file)
index f63eb33..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.request_files.tutorial001_02_an import app
-
-client = TestClient(app)
-
-
-def test_post_form_no_body():
-    response = client.post("/files/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No file sent"}
-
-
-def test_post_uploadfile_no_body():
-    response = client.post("/uploadfile/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No upload file sent"}
-
-
-def test_post_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-def test_post_upload_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_file_files__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_file_files__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_02_an_py310.py b/tests/test_tutorial/test_request_files/test_tutorial001_02_an_py310.py
deleted file mode 100644 (file)
index 94b6ac6..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.request_files.tutorial001_02_an_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py310
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No file sent"}
-
-
-@needs_py310
-def test_post_uploadfile_no_body(client: TestClient):
-    response = client.post("/uploadfile/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No upload file sent"}
-
-
-@needs_py310
-def test_post_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-@needs_py310
-def test_post_upload_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_file_files__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_file_files__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_02_an_py39.py b/tests/test_tutorial/test_request_files/test_tutorial001_02_an_py39.py
deleted file mode 100644 (file)
index fcb39f8..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.request_files.tutorial001_02_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py39
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No file sent"}
-
-
-@needs_py39
-def test_post_uploadfile_no_body(client: TestClient):
-    response = client.post("/uploadfile/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No upload file sent"}
-
-
-@needs_py39
-def test_post_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_file_files__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_file_files__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_02_py310.py b/tests/test_tutorial/test_request_files/test_tutorial001_02_py310.py
deleted file mode 100644 (file)
index a700752..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-from pathlib import Path
-
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.request_files.tutorial001_02_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py310
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No file sent"}
-
-
-@needs_py310
-def test_post_uploadfile_no_body(client: TestClient):
-    response = client.post("/uploadfile/")
-    assert response.status_code == 200, response.text
-    assert response.json() == {"message": "No upload file sent"}
-
-
-@needs_py310
-def test_post_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-@needs_py310
-def test_post_upload_file(tmp_path: Path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_file_files__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_file_files__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": IsDict(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                            }
-                                        ],
-                                        "title": "Body",
-                                    }
-                                )
-                                | IsDict(
-                                    # TODO: remove when deprecating Pydantic v1
-                                    {
-                                        "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                    }
-                                )
-                            }
-                        }
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "type": "object",
-                    "properties": {
-                        "file": IsDict(
-                            {
-                                "title": "File",
-                                "anyOf": [
-                                    {"type": "string", "format": "binary"},
-                                    {"type": "null"},
-                                ],
-                            }
-                        )
-                        | IsDict(
-                            # TODO: remove when deprecating Pydantic v1
-                            {"title": "File", "type": "string", "format": "binary"}
-                        )
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
index f02170814c9eb52c51e0a955a5f59276a7d24bd6..9fbe2166c17b578648c89b9400e3832593c47c23 100644 (file)
@@ -1,33 +1,47 @@
+import importlib
+
+import pytest
 from fastapi.testclient import TestClient
 
-from docs_src.request_files.tutorial001_03 import app
+from ...utils import needs_py39
+
+
+@pytest.fixture(
+    name="client",
+    params=[
+        "tutorial001_03",
+        "tutorial001_03_an",
+        pytest.param("tutorial001_03_an_py39", marks=needs_py39),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.request_files.{request.param}")
 
-client = TestClient(app)
+    client = TestClient(mod.app)
+    return client
 
 
-def test_post_file(tmp_path):
+def test_post_file(tmp_path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/files/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"file_size": 14}
 
 
-def test_post_upload_file(tmp_path):
+def test_post_upload_file(tmp_path, client: TestClient):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
 
-    client = TestClient(app)
     with path.open("rb") as file:
         response = client.post("/uploadfile/", files={"file": file})
     assert response.status_code == 200, response.text
     assert response.json() == {"filename": "test.txt"}
 
 
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
     assert response.json() == {
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_03_an.py b/tests/test_tutorial/test_request_files/test_tutorial001_03_an.py
deleted file mode 100644 (file)
index acfb749..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-from fastapi.testclient import TestClient
-
-from docs_src.request_files.tutorial001_03_an import app
-
-client = TestClient(app)
-
-
-def test_post_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-def test_post_upload_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_file_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {
-                            "title": "File",
-                            "type": "string",
-                            "description": "A file read as bytes",
-                            "format": "binary",
-                        }
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {
-                            "title": "File",
-                            "type": "string",
-                            "description": "A file read as UploadFile",
-                            "format": "binary",
-                        }
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_03_an_py39.py b/tests/test_tutorial/test_request_files/test_tutorial001_03_an_py39.py
deleted file mode 100644 (file)
index 36e5faa..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-import pytest
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.request_files.tutorial001_03_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py39
-def test_post_file(tmp_path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_file_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {
-                            "title": "File",
-                            "type": "string",
-                            "description": "A file read as bytes",
-                            "format": "binary",
-                        }
-                    },
-                },
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {
-                            "title": "File",
-                            "type": "string",
-                            "description": "A file read as UploadFile",
-                            "format": "binary",
-                        }
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_an.py b/tests/test_tutorial/test_request_files/test_tutorial001_an.py
deleted file mode 100644 (file)
index 1c78e36..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.request_files.tutorial001_an import app
-
-client = TestClient(app)
-
-
-def test_post_form_no_body():
-    response = client.post("/files/")
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "file"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "file"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-def test_post_body_json():
-    response = client.post("/files/", json={"file": "Foo"})
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "file"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "file"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-def test_post_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-def test_post_large_file(tmp_path):
-    default_pydantic_max_size = 2**16
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"x" * (default_pydantic_max_size + 1))
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": default_pydantic_max_size + 1}
-
-
-def test_post_upload_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    client = TestClient(app)
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_file_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {"title": "File", "type": "string", "format": "binary"}
-                    },
-                },
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {"title": "File", "type": "string", "format": "binary"}
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial001_an_py39.py b/tests/test_tutorial/test_request_files/test_tutorial001_an_py39.py
deleted file mode 100644 (file)
index 843fcec..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
-    from docs_src.request_files.tutorial001_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-@needs_py39
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "file"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "file"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_body_json(client: TestClient):
-    response = client.post("/files/", json={"file": "Foo"})
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "file"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "file"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_file(tmp_path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": 14}
-
-
-@needs_py39
-def test_post_large_file(tmp_path, client: TestClient):
-    default_pydantic_max_size = 2**16
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"x" * (default_pydantic_max_size + 1))
-
-    with path.open("rb") as file:
-        response = client.post("/files/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_size": default_pydantic_max_size + 1}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, client: TestClient):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-
-    with path.open("rb") as file:
-        response = client.post("/uploadfile/", files={"file": file})
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filename": "test.txt"}
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create File",
-                    "operationId": "create_file_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_file_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/uploadfile/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Upload File",
-                    "operationId": "create_upload_file_uploadfile__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_upload_file_uploadfile__post": {
-                    "title": "Body_create_upload_file_uploadfile__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {"title": "File", "type": "string", "format": "binary"}
-                    },
-                },
-                "Body_create_file_files__post": {
-                    "title": "Body_create_file_files__post",
-                    "required": ["file"],
-                    "type": "object",
-                    "properties": {
-                        "file": {"title": "File", "type": "string", "format": "binary"}
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index db1552e5c661046399c258c9da89869871627490..446a8765784f8116b25dc26e0366ef7c15674579 100644 (file)
@@ -1,12 +1,35 @@
+import importlib
+
+import pytest
 from dirty_equals import IsDict
+from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from docs_src.request_files.tutorial002 import app
+from ...utils import needs_py39
+
+
+@pytest.fixture(
+    name="app",
+    params=[
+        "tutorial002",
+        "tutorial002_an",
+        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py39", marks=needs_py39),
+    ],
+)
+def get_app(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.request_files.{request.param}")
 
-client = TestClient(app)
+    return mod.app
+
+
+@pytest.fixture(name="client")
+def get_client(app: FastAPI):
+    client = TestClient(app)
+    return client
 
 
-def test_post_form_no_body():
+def test_post_form_no_body(client: TestClient):
     response = client.post("/files/")
     assert response.status_code == 422, response.text
     assert response.json() == IsDict(
@@ -34,7 +57,7 @@ def test_post_form_no_body():
     )
 
 
-def test_post_body_json():
+def test_post_body_json(client: TestClient):
     response = client.post("/files/", json={"file": "Foo"})
     assert response.status_code == 422, response.text
     assert response.json() == IsDict(
@@ -62,7 +85,7 @@ def test_post_body_json():
     )
 
 
-def test_post_files(tmp_path):
+def test_post_files(tmp_path, app: FastAPI):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
     path2 = tmp_path / "test2.txt"
@@ -81,7 +104,7 @@ def test_post_files(tmp_path):
     assert response.json() == {"file_sizes": [14, 15]}
 
 
-def test_post_upload_file(tmp_path):
+def test_post_upload_file(tmp_path, app: FastAPI):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
     path2 = tmp_path / "test2.txt"
@@ -100,14 +123,14 @@ def test_post_upload_file(tmp_path):
     assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
 
 
-def test_get_root():
+def test_get_root(app: FastAPI):
     client = TestClient(app)
     response = client.get("/")
     assert response.status_code == 200, response.text
     assert b"<form" in response.content
 
 
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
     assert response.json() == {
diff --git a/tests/test_tutorial/test_request_files/test_tutorial002_an.py b/tests/test_tutorial/test_request_files/test_tutorial002_an.py
deleted file mode 100644 (file)
index b16da16..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.request_files.tutorial002_an import app
-
-client = TestClient(app)
-
-
-def test_post_form_no_body():
-    response = client.post("/files/")
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-def test_post_body_json():
-    response = client.post("/files/", json={"file": "Foo"})
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-def test_post_files(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-def test_post_upload_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-def test_get_root():
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                    "summary": "Main",
-                    "operationId": "main__get",
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial002_an_py39.py b/tests/test_tutorial/test_request_files/test_tutorial002_an_py39.py
deleted file mode 100644 (file)
index e092a51..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi import FastAPI
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="app")
-def get_app():
-    from docs_src.request_files.tutorial002_an_py39 import app
-
-    return app
-
-
-@pytest.fixture(name="client")
-def get_client(app: FastAPI):
-    client = TestClient(app)
-    return client
-
-
-@needs_py39
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_body_json(client: TestClient):
-    response = client.post("/files/", json={"file": "Foo"})
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_files(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-@needs_py39
-def test_get_root(app: FastAPI):
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                    "summary": "Main",
-                    "operationId": "main__get",
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial002_py39.py b/tests/test_tutorial/test_request_files/test_tutorial002_py39.py
deleted file mode 100644 (file)
index 341a9ac..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi import FastAPI
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="app")
-def get_app():
-    from docs_src.request_files.tutorial002_py39 import app
-
-    return app
-
-
-@pytest.fixture(name="client")
-def get_client(app: FastAPI):
-    client = TestClient(app)
-    return client
-
-
-file_required = {
-    "detail": [
-        {
-            "loc": ["body", "files"],
-            "msg": "field required",
-            "type": "value_error.missing",
-        }
-    ]
-}
-
-
-@needs_py39
-def test_post_form_no_body(client: TestClient):
-    response = client.post("/files/")
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_body_json(client: TestClient):
-    response = client.post("/files/", json={"file": "Foo"})
-    assert response.status_code == 422, response.text
-    assert response.json() == IsDict(
-        {
-            "detail": [
-                {
-                    "type": "missing",
-                    "loc": ["body", "files"],
-                    "msg": "Field required",
-                    "input": None,
-                }
-            ]
-        }
-    ) | IsDict(
-        # TODO: remove when deprecating Pydantic v1
-        {
-            "detail": [
-                {
-                    "loc": ["body", "files"],
-                    "msg": "field required",
-                    "type": "value_error.missing",
-                }
-            ]
-        }
-    )
-
-
-@needs_py39
-def test_post_files(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-@needs_py39
-def test_get_root(app: FastAPI):
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                    "summary": "Main",
-                    "operationId": "main__get",
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index 85cd03a590e62360ba69c7bc9f9230c480f34c6b..8534ba3e9a2efbf9fd92cf2cd7739d6bcffd1485 100644 (file)
@@ -1,11 +1,34 @@
+import importlib
+
+import pytest
+from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from docs_src.request_files.tutorial003 import app
+from ...utils import needs_py39
+
+
+@pytest.fixture(
+    name="app",
+    params=[
+        "tutorial003",
+        "tutorial003_an",
+        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py39", marks=needs_py39),
+    ],
+)
+def get_app(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.request_files.{request.param}")
 
-client = TestClient(app)
+    return mod.app
+
+
+@pytest.fixture(name="client")
+def get_client(app: FastAPI):
+    client = TestClient(app)
+    return client
 
 
-def test_post_files(tmp_path):
+def test_post_files(tmp_path, app: FastAPI):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
     path2 = tmp_path / "test2.txt"
@@ -24,7 +47,7 @@ def test_post_files(tmp_path):
     assert response.json() == {"file_sizes": [14, 15]}
 
 
-def test_post_upload_file(tmp_path):
+def test_post_upload_file(tmp_path, app: FastAPI):
     path = tmp_path / "test.txt"
     path.write_bytes(b"<file content>")
     path2 = tmp_path / "test2.txt"
@@ -43,14 +66,14 @@ def test_post_upload_file(tmp_path):
     assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
 
 
-def test_get_root():
+def test_get_root(app: FastAPI):
     client = TestClient(app)
     response = client.get("/")
     assert response.status_code == 200, response.text
     assert b"<form" in response.content
 
 
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
     assert response.json() == {
diff --git a/tests/test_tutorial/test_request_files/test_tutorial003_an.py b/tests/test_tutorial/test_request_files/test_tutorial003_an.py
deleted file mode 100644 (file)
index 0327a2d..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-from fastapi.testclient import TestClient
-
-from docs_src.request_files.tutorial003_an import app
-
-client = TestClient(app)
-
-
-def test_post_files(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-def test_post_upload_file(tmp_path):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-def test_get_root():
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "summary": "Main",
-                    "operationId": "main__get",
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as bytes",
-                        }
-                    },
-                },
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as UploadFile",
-                        }
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial003_an_py39.py b/tests/test_tutorial/test_request_files/test_tutorial003_an_py39.py
deleted file mode 100644 (file)
index 3aa68c6..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-import pytest
-from fastapi import FastAPI
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="app")
-def get_app():
-    from docs_src.request_files.tutorial003_an_py39 import app
-
-    return app
-
-
-@pytest.fixture(name="client")
-def get_client(app: FastAPI):
-    client = TestClient(app)
-    return client
-
-
-file_required = {
-    "detail": [
-        {
-            "loc": ["body", "files"],
-            "msg": "field required",
-            "type": "value_error.missing",
-        }
-    ]
-}
-
-
-@needs_py39
-def test_post_files(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-@needs_py39
-def test_get_root(app: FastAPI):
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "summary": "Main",
-                    "operationId": "main__get",
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as bytes",
-                        }
-                    },
-                },
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as UploadFile",
-                        }
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
diff --git a/tests/test_tutorial/test_request_files/test_tutorial003_py39.py b/tests/test_tutorial/test_request_files/test_tutorial003_py39.py
deleted file mode 100644 (file)
index 238bb39..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-import pytest
-from fastapi import FastAPI
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="app")
-def get_app():
-    from docs_src.request_files.tutorial003_py39 import app
-
-    return app
-
-
-@pytest.fixture(name="client")
-def get_client(app: FastAPI):
-    client = TestClient(app)
-    return client
-
-
-file_required = {
-    "detail": [
-        {
-            "loc": ["body", "files"],
-            "msg": "field required",
-            "type": "value_error.missing",
-        }
-    ]
-}
-
-
-@needs_py39
-def test_post_files(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/files/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"file_sizes": [14, 15]}
-
-
-@needs_py39
-def test_post_upload_file(tmp_path, app: FastAPI):
-    path = tmp_path / "test.txt"
-    path.write_bytes(b"<file content>")
-    path2 = tmp_path / "test2.txt"
-    path2.write_bytes(b"<file content2>")
-
-    client = TestClient(app)
-    with path.open("rb") as file, path2.open("rb") as file2:
-        response = client.post(
-            "/uploadfiles/",
-            files=(
-                ("files", ("test.txt", file)),
-                ("files", ("test2.txt", file2)),
-            ),
-        )
-    assert response.status_code == 200, response.text
-    assert response.json() == {"filenames": ["test.txt", "test2.txt"]}
-
-
-@needs_py39
-def test_get_root(app: FastAPI):
-    client = TestClient(app)
-    response = client.get("/")
-    assert response.status_code == 200, response.text
-    assert b"<form" in response.content
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/files/": {
-                "post": {
-                    "summary": "Create Files",
-                    "operationId": "create_files_files__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_files_files__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/uploadfiles/": {
-                "post": {
-                    "summary": "Create Upload Files",
-                    "operationId": "create_upload_files_uploadfiles__post",
-                    "requestBody": {
-                        "content": {
-                            "multipart/form-data": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/": {
-                "get": {
-                    "summary": "Main",
-                    "operationId": "main__get",
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        }
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Body_create_files_files__post": {
-                    "title": "Body_create_files_files__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as bytes",
-                        }
-                    },
-                },
-                "Body_create_upload_files_uploadfiles__post": {
-                    "title": "Body_create_upload_files_uploadfiles__post",
-                    "required": ["files"],
-                    "type": "object",
-                    "properties": {
-                        "files": {
-                            "title": "Files",
-                            "type": "array",
-                            "items": {"type": "string", "format": "binary"},
-                            "description": "Multiple files as UploadFile",
-                        }
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }