.. _testing: Testing ======= ``hypothesis`` integration -------------------------- ``hrefs`` uses the `hypothesis `_ library to testing internally, and includes a hypothesis plugin for generating :class:`hrefs.Href` instances. Thanks to the `entry points `_ mechanism, you don't need to do anything except ``import hypothesis`` and start generating hyperlinks: .. testcode:: hypothesis from dataclasses import dataclass from hrefs import Href, Referrable from hypothesis import given, strategies as st @dataclass class Book(Referrable): id: int def get_key(self) -> int: return self.id @staticmethod def key_to_url(key: int) -> str: return f"/books/{key}" @staticmethod def url_to_key(url: str) -> int: return int(url.split("/")[-1]) @given(st.from_type(Href[Book])) def test_hrefs_with_hypothesis(href): assert isinstance(href, Href) assert href.url == f"/books/{href.key}" test_hrefs_with_hypothesis() Using ``hypothesis`` with FastAPI/Starlette ------------------------------------------- Generating URLs for hyperlinks in FastAPI/Starlette normally relies on :class:`hrefs.starlette.HrefMiddleware` to expose the request context to the library. But the middleware doesn't directly work with the ``@given`` decorator, since that would require ``hypothesis`` to run inside your Starlette application. But ``hypothesis`` already wants to generate the data before your test case even takes over. In order to give ``hypothesis`` the context, you can use fixtures. Here is an example using `pytest `_: .. testcode:: pytest from pytest import fixture from fastapi import FastAPI from hrefs import Href, BaseReferrableModel from hrefs.starlette import href_context from hypothesis import given, strategies as st app = FastAPI() class Book(BaseReferrableModel): id: int class Config: details_view = "get_book" @app.get("/books/{id}") def get_my_model(id: int) -> Book: ... @fixture(scope="module", autouse=True) def appcontext(): with href_context(app, base_url="http://example.com"): yield @given(st.from_type(Href[Book])) def test_hrefs_with_hypothesis_and_pytest(href): assert isinstance(href, Href) assert href.url == f"http://example.com/books/{href.key}" The example uses a module-scoped fixture. There is nothing wrong in using function-scoped fixtures, but they are unnecessarily granular and `hypothesis will warn against them by default `_.