lundi 3 février 2020

How to properly clear database using fixtures when testing with pytest

I have a test database. Let's assume there are three tables created in there:

create table users (
    id serial constraint users_pkey primary key,
    name text not null
);
create table roles (
    id serial constraint roles_pkey primary key,
    name text not null
);
create table users_roles (
    user_id int constraint users_roles_users_fkey references users(id),
    role_id int constraint users_roles_roles_fkey references roles(id)
);

Every test starts with filling the database with data using factory_boy factories. Typical test looks like this:

def test_get_user_roles(api_client):
    user = UserFactory.create(id=1)
    role = RolesFactory.create(id=1)
    users_roles = UsersRolesFactory.create(user_id=1, role_id=1)
    response = api_client.get(f"/users/{user.id}/roles")
    assert ...

I could clear table using @pytest.mark.usefixtures("clear_users_roles", "clear_users", "clear_roles"), where "clear_users_roles", "clear_users", "clear_roles" are fixtures that obviously clear tables if there were no relationships between tables. But in the example above there are relationships (foreign keys) between table users_roles and user and between users_roles and roles and the problem is that fixtures run out of order. So when I run my tests I get an integrity error, because, for example, fixture "clear_users" was executed before "clear_users_roles" and my RDBMS cannot delete a record because the record still references to table "users". Is there a proper way to run fixtures in specific order? Or may be there are some patterns/best practices for case like this?

Aucun commentaire:

Enregistrer un commentaire