Data Table With Pydantic & Dataclass Support¶
In the previous chapter, we learnt basics data table supports
but there is more, Turşu is able to map gherkin table to pydantic model, or dataclasses.
It works for Data table and reversed data table.
From the previous example, we list[dict[str, str]] and the dict[str, str] can be replaced by typed object.
Here is wome class definition for the previous example.
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(data_table: list[User]):
...
@given("a user with the following informations:")
def fill_user_profile(data_table: User):
...
And that’s it. Now Turşu will provide data_table mapped to your given models.
Important
Nested model are not implemented in data table in Turşu,
You can achieve it usign a Doc String that use a model. This is the subject of the next chapter.
You may also notive that the blanked gherkin column will not be passed to model constructurors., They will be removed and the default values of the field will be used instead. To get more control of the model construction, you can passed a factory.
So the following step will failed:
Given a user with the following informations:
| username | johndoe |
| password | |
The step above failed because the password is ommited, and there is no default value set on the model, and Turşu will parse the table to User(username=‘johndoe’), of course you can define a field_factory on the model, or you may use a factory, that le you reuse the type for different purpose.
Adding model factory with faker.¶
If the model of the data_table 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, data_table: list[Annotated[User, UserFactory]]):
...
@given("a user with the following informations:")
def fill_user_profile(data_table: Annotated[User, UserFactory]):
...
In that case, the gherkin scenario with empty data, are filled by faker values:
Given the user provides the following informations:
| username | password |
| johndoe | secret123 |
| janedoe | |
| | |
Note
data_table looks like
[
User(username="johndoe", password="secret123"),
User(username="janedoe", password="<random value>"),
User(username="<random value>", password="<random value>"),
]
Union types¶
Union types can’t be used to define a data_table.
A step cannot be a data table or a reversed data table, two steps must be created with their proper types.