polyfactory icon indicating copy to clipboard operation
polyfactory copied to clipboard

Factory doesn't pick up `faker_session_locale` fixture changes, generates data with default settings

Open Rub1kCube opened this issue 6 months ago • 3 comments

Description

Issue Description

When running tests and modifying Faker settings within the faker_session_locale fixture to generate data in a specific language (e.g., Russian), any Factory does not recognize these changes and continues generating data based on the default Faker object settings. As a result, data is generated with default settings instead of the expected Russian localization.

Proposed Solution

This issue can be resolved by creating a project-level fixture that replaces the Faker object instantiated when creating Factory objects. Since the problem manifests at the test level, the solution should be implemented at the same level.

MCVE

To write minimal code, you need to create several files and download several libraries:

uv init \
&& mkdir tests \
&& touch ./tests/conftest.py ./tests/test_example.py \
&& uv add polyfactory==2.21.0 pydantic pytest

# If not UV
python -m venv .venv \
&& source .venv/bin/activate \
&& mkdir tests \
&& touch ./tests/conftest.py ./tests/test_example.py \
&& pip install polyfactory==2.21.0 pydantic pytest

tests/conftest.py

import pytest

@pytest.fixture(scope='session', autouse=True)
def faker_session_locale():
    return ['ru_RU']

tests/test_example.py

import re

from polyfactory.factories.pydantic_factory import ModelFactory
from polyfactory import Use
from pydantic import BaseModel
from faker import Faker


class ExampleModel(BaseModel):
    field: str


class ExampleFactory(ModelFactory[ExampleModel]):
    field = Use(ModelFactory.__faker__.word)


def test_exmaple(faker: Faker):
    factory = ExampleFactory.build()
    assert bool(re.search(r'[а-яёА-ЯЁ]', factory.field)), (factory.field, faker.word())

This test will fail because the answer will consist of English letters.

Release Version

2.21.0

Platform

  • [x] Linux
  • [ ] Mac
  • [ ] Windows
  • [ ] Other (Please specify in the description above)

Rub1kCube avatar Jun 19 '25 16:06 Rub1kCube

How would this be expected to interact with non-session level scope described here?

adhtruong avatar Jun 21 '25 12:06 adhtruong

I think I didn't express myself clearly - what I meant was: it would be convenient if setting global Faker configurations through the faker_session_locale fixture would automatically update all Faker instances created in each individual Factory's __faker__ attribute. This way, there would be no need to create a base Factory with the __faker__ = Faker(locale=["ru_RU"]) configuration.

Or is it possible to implement a global Faker configuration before running tests through a fixture for Factory for Polyfactory?

Rub1kCube avatar Jun 21 '25 13:06 Rub1kCube

This makes sense as a use case to try and support.

Somes things to consider,

  1. This is a backwards breaking change if enabled by default. If want to enable by default then this should be left to v3 with appropriate migration note
  2. How is this being set per factory? Currently this fixture is coming from pytest fixture so lifecycle is within a pytest scope. Would this revert when outside pytest fixture scope
  3. There may places where random/faker differ or issues if bound already e.g. Use(MyFactory.__faker__.pystr won't use this faker instance if set. This is a separate issue but nice to resolve to avoid unexpected results

adhtruong avatar Jun 23 '25 21:06 adhtruong