Preface

Just examining by testing.

Prerequisites

The App & the Test Suite in a Single Block

import unittest
from typing import Union
from fastapi import FastAPI
from fastapi.testclient import TestClient


app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
#
#
# The Test Suite
#
client = TestClient(app)

class TestFastAPI(unittest.TestCase):

    def test_read_root(self):
        response = client.get("/")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"Hello": "World"})

    def test_read_item_with_query(self):
        response = client.get("/items/42?q=somequery")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"item_id": 42, "q": "somequery"})
    
    def test_read_item_without_query(self):
        response = client.get("/items/42")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"item_id": 42, "q": None})

unittest.main(exit=False)
...
----------------------------------------------------------------------
Ran 3 tests in 0.010s

OK

TestClient module

Can you explanin the main features of TestClient module?

Certainly! The `TestClient` module in FastAPI is a powerful tool
designed to facilitate testing applications built with FastAPI. It is
built on top of Starlette's `TestClient`, which itself wraps around
`requests`, a popular HTTP library in Python. The `TestClient` module
is essential for running tests that simulate HTTP requests to your
application without starting an actual server. Here are the main
features of the `TestClient` module:

### Main Features of TestClient

1. **Simulating HTTP Requests**:
   - `TestClient` allows you to simulate HTTP requests (GET, POST,
     PUT, DELETE, etc.) to your FastAPI application endpoints. This
     helps in verifying the behavior of your API endpoints.

2. **Session Management**:
   - `TestClient` manages sessions, including cookies and headers,
     making it easier to test workflows that depend on session states.

3. **Response Validation**:
   - You can validate the response status codes, headers, and body
     content to ensure they meet the expected outcomes. This ensures
     your API behaves as expected under different conditions.

4. **Asynchronous Support**:
   - `TestClient` supports testing asynchronous endpoints. It
     seamlessly handles both synchronous and asynchronous requests,
     maintaining the same interface for simplicity.

5. **Context Management**:
   - It provides a context manager to handle setup and teardown,
     ensuring clean test environments. This is useful for initializing
     and cleaning up resources needed for tests.

6. **Integration with Testing Frameworks**:
   - `TestClient` can be used in conjunction with various testing
     frameworks like `unittest`, `pytest`, and others, providing
     flexibility in writing and organizing tests.

7. **API Documentation Testing**:
   - It can automatically check that the documentation URLs (like
     Swagger UI and ReDoc) load correctly and contain the expected
     content, ensuring that the API documentation is always up-to-date
     and functional.

### Example Usage of TestClient

Here's a more detailed look at how you can use `TestClient` with
FastAPI:

#### FastAPI Application

```python
from fastapi import FastAPI
from typing import Union

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
```

#### Unit Tests

```python
import unittest
from fastapi.testclient import TestClient
from main import app  # Assuming your FastAPI app is defined in main.py

client = TestClient(app)

class TestFastAPI(unittest.TestCase):

    def test_read_root(self):
        response = client.get("/")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"Hello": "World"})

    def test_read_item_with_query(self):
        response = client.get("/items/42?q=somequery")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"item_id": 42, "q": "somequery"})

    def test_read_item_without_query(self):
        response = client.get("/items/42")
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {"item_id": 42, "q": None})

if __name__ == "__main__":
    unittest.main()
```

### Explanation of Example

1. **Importing TestClient**:
   - `TestClient` is imported from `fastapi.testclient`. This allows
     us to create a client instance to interact with our FastAPI
     application.

2. **Creating an Instance**:
   - We create an instance of `TestClient` by passing in the FastAPI
     `app`. This client will be used to simulate HTTP requests to the
     application.

3. **Simulating Requests**:
   - `GET`, `POST`, `PUT`, `DELETE`, and other HTTP methods are
     available to simulate requests to the application endpoints.
   
4. **Response Validation**:
   - The responses can be checked for status codes, headers, and JSON
     content using the methods and attributes provided by the
     `requests.Response` object returned by `TestClient`.

5. **Handling Asynchronous Endpoints**:
   - The same interface works seamlessly with asynchronous endpoints,
     allowing tests to be written without worrying about the
     underlying asynchronous nature.

### Advanced Features

While the above example covers basic usage, here are some advanced
features you can take advantage of:
- **Context Management**:
  ```python
  with TestClient(app) as client:
      response = client.get("/items/")
      assert response.status_code == 200
  ```

- **Custom Headers and Authentication**:
  ```python
  response = client.get("/items/", headers={"Authorization": "Bearer token"})
  ```

- **Session Management**:
  ```python
  client.cookie_jar.set("session", "session-value")
  response = client.get("/items/")
  ```

### Summary

The `TestClient` module in FastAPI is a powerful and convenient tool
for testing web applications. It provides easy-to-use interfaces to
simulate HTTP requests, manage sessions, validate responses, and
integrate with various testing frameworks, making it an indispensable
part of the FastAPI testing workflow.

Test All Supported HTTP Request's Methods