Doc String With Pydantic & Dataclass Support¶
In the chapter before the previous one, we learnt basics doc string supports
but as we learnt in the advanced data table,
docstring also support complex model types.
Dataclass¶
from dataclasses import dataclass
@dataclass
class User:
username: str
password: str
Pydantic¶
If you prefer go with pydantic, it also works.
from pydantic import BaseModel
class User(BaseModel):
username: str
password: str
Usage of model based class.¶
After the type has been devined, we can replace it in step definitions, like this:
@given("the user provides the following informations:")
def fill_user_table(doc_string: list[User]):
...
@given("a user with the following informations:")
def fill_user_profile(doc_string: User):
...
And that’s it. Now Turşu will provide doc_string mapped to previous given models.
So the following step will failed:
Given a user with the following informations:
"""json
{"username": "john", "password": "pass"}
"""
Adding model factory with faker.¶
If the model of the doc_string argument is Annotated, then the factory will be used to contruct the model, it can be usefull to inject the data you need for you expectation, or random data.
Here is an example with factory-boy:
import factory
from pydantic import BaseModel
class User(BaseModel):
username: str
password: str
class UserFactory(factory.Factory[User]):
class Meta:
model = User
username = factory.Faker("user_name")
password = factory.Faker("password")
@given("the user provides the following informations:")
def a_set_of_users(app: DummyApp, doc_string: list[Annotated[User, UserFactory]]):
...
@given("a user with the following informations:")
def fill_user_profile(doc_string: Annotated[User, UserFactory]):
...
In that case, the gherkin scenario with empty data, are filled by faker values:
Given the user provides the following informations:
"""json
[
{"username": "johndoe", "password": "secret123"},
{"username": "janedoe"},
{},
]
"""
Note
doc_string looks like
[
User(username="johndoe", password="secret123"),
User(username="janedoe", password="<random value>"),
User(username="<random value>", password="<random value>"),
]
Union types¶
The union type is not supported on doc_string casting.
The returned value will be python literals.
Example:
@then("the API respond")
def assert_api_response_json_as_any(
doc_string: list[dict[str, str]] | dict[str, str],
):
...
Important
A docstring can’t have union types of pydantic models or dataclass, they will be ignored and the returned value is a python literals (dict, list, str, …).
Doc String With AST literals¶
Docstring can also be pure python literals, in that case they will be parsed with the ast.literal_eval function.
This is limitted to python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis.
It cab be convenience for small structures to avoid extra schema, such as:
Given a set of super power:
"""python
{"foo", "bar"}
"""
@given("a set of super power:")
def a_set_of_users(doc_string: set[str]):
...