ν¨μμ μν΄ μμ±λ κ±°λν db μ‘°λͺ
κΈ°λ₯Ό λ‘λν΄μΌ νλ μν©μ΄ μμ΅λλ€. Fixtureλ λͺ¨λ API ν
μ€νΈμ νμν©λλ€. κ·Έλμ conftest.py
μ μΈμ
κ³ μ μ₯μΉλ₯Ό λ§λ€μμ΅λλ€. κ·Έλ¬λ λ¬Έμ λ $# django_db
νμνμμλ λΆκ΅¬νκ³ pytest
λ€μ μμΈκ° λ°μνλ€λ κ²μ
λλ€.
E Failed: Database access not allowed, use the "django_db" mark to enable it.
μλλ λ΄ μ½λ μ€λν«μ
λλ€.
from permission.helpers import update_permissions
pytestmark = [
pytest.mark.django_db(transaction = True),]
@pytest.fixture(scope="session", autouse = True)
def permission(request):
load_time_consuming_db_fixture()
@ludbek μ°λ¦¬λ λν κ·Έλ¬ν κΈ°λ₯μ λμΉκ³ μ΄ κΈ°λ₯μ μν νλ¬κ·ΈμΈμ λ§λ€μμ΅λλ€:
https://github.com/tipsi/pytest-tipsi-django (μ¬μ©λ²: https://github.com/tipsi/pytest-tipsi-django/blob/master/test_django_plugin/app/tests/test_transactions.py)
λ€μκ³Ό ν¨κ»:
https://github.com/tipsi/pytest-tipsi-testing
νΈλμμ
μ μ€μ²©νκ³ μ€ν/μ’
λ£ μμλ₯Ό μμ νλ κΈ°λ₯μ μ 곡ν©λλ€.
@cybergrind λ΅λ³ν΄μ£Όμ μ κ°μ¬ν©λλ€. λλ νμ€ν κ·Έκ²μ νμΈνκ³ μ΄λ»κ² λμλμ§ μλ €μ€ κ²μ΄λ€.
μ΄κ²μ Djangoμ UnitTest ν΄λμ€ κΈ°λ° ν
μ€νΈμμ pytest-djangoμ μ΄λ₯΄λ κ°μ₯ ν° λ¬Έμ μμ΅λλ€. Djangoμμλ setUpTestData
λ₯Ό μ¬μ©νμ¬ κ°λΉμΌ DB μμ
μ ν λ² μ€νν©λλ€(μΈμ
λ²μμ pytest κ³ μ μ₯μΉμ λμΌ). κ·Έλ¦¬κ³ setUp
obj.refresh_from_db()
λ₯Ό μ€ννμ¬ ν΄λμ€ μ°Έμ‘°λ₯Ό μλ‘ κ³ μΉλ κ΅νν νΈλ¦μ΄ μμ΅λλ€.
DB λͺ¨λΈ μΈμ€ν΄μ€λ₯Ό νλλ§ μμ±νκ³ TCλ§λ€ λ€μ λ‘λνλλΌλ κ° ν μ€νΈ μ¬λ‘μμ μμ±νλ κ²λ³΄λ€ κ±°μ νμ λΉ λ¦ λλ€.
κ°λ₯ν κ²½μ° pytest-tipsi-django λ³ν©λ μ μ€νΈλ¦Όμμ μΈμ λ²μ κ³ μ μ₯μΉλ₯Ό κ°μ Έμ¬ μ μλ€λ©΄ μ’μ κ²μ λλ€. μ΄ λ¬Έμ μ μ루μ μ μ°Ύλ λ° μ½κ°μ νκ³ κ° νμνμ΅λλ€.
μλ νμΈμ @paultiplady
pytest-tipsi-djanjo
μ μ κ·Ό λ°©μμ΄ $#$1 pytest
#$ μ λν μΌλ°μ μΈ ν
μ€νΈ λͺ¨λΈμ λ§λμ§ μ λͺ¨λ₯΄κ² μ΅λλ€. κ°μ₯ λμ λλ μ°¨μ΄μ μ μ‘°λͺ
κΈ°μ λ§λ¬΄λ¦¬μ
λλ€. νμ¬ pytest
λ λ λμ λ²μμ λΆνμν μ‘°λͺ
κΈ°λ₯Ό λͺ
μμ μΌλ‘ λ§λ¬΄λ¦¬νμ§ μμ΅λλ€. λ°λΌμ νΉμ μμλ‘ νΈλμμ
μ λͺ
μμ μΌλ‘ μλ£ν΄μΌ νλ©° μΌλ°μ μΌλ‘ μ΄λ λ§€μ° λ€λ₯Έ ν¨κ³Όλ₯Ό μ λ°ν μ μμ΅λλ€(νμ¬ pytest
λ νμ± ν
μ€νΈ λ° ν΄λΉ ν½μ€μ²κ° μ΄λ₯Ό μ ν μꡬνμ§ μλλΌλ ν½μ€μ²λ₯Ό νμ± μνλ‘ μ μ§ν μ μμ).
λλλ‘ λͺ κ°μ§ ν° μλ리μ€λ₯Ό ν μ€νΈν΄μΌ νκ³ λκ·λͺ¨ ν μ€νΈμμ κΈ°μ‘΄ μλ νΈλμμ κ΄λ¦¬λ₯Ό μ½κ° λ λμ κ³ μ μ₯μΉλ‘ κ΅μ²΄νκΈ° λλ¬Έμ νλ‘μ νΈμ ν μ€νΈλ₯Ό μ΄ μ κ·Ό λ°©μμΌλ‘ λ³κ²½ν΄μΌ νμ§λ§ μ¬μ ν μ£Όλ¬Έ ν μ€νΈμ λν μ£Όμκ° νμν©λλ€.
μ§κΈ λΉμ₯μ κ·Έμ λν λ¨ νλμ μ루μ λ§ λ³Ό μ μμ΅λλ€. μΌμ’ μ FAQλ₯Ό λ¬Έμννλ κ²μ λλ€.
@cybergrindμ λν μΆκ° μ 보μ κ°μ¬λ립λλ€. μ‘°κΈ λ νκ³ λ€μμ§λ§ μ€λ μκ°μ΄ λΆμ‘±ν©λλ€. μ¬κΈ°κΉμ§ κ°μΌ ν©λλ€. μ΄ μ κ·Ό λ°©μμ΄ μ μ©νμ§ μ¬λΆμ λν μ¨μ ν νμΈμ ν΄μ£Όμλ©΄ κ°μ¬νκ² μ΅λλ€. pytest λ΄λΆμ μ΅μνμ§ μμ΅λλ€.
λν "pytestλ λ λμ λ²μμ λΆνμν μ€λΉλ₯Ό λͺ μμ μΌλ‘ λλ΄μ§ μμ΅λλ€"λΌλ λ§μ μλ―Έλ₯Ό μ΄ν΄νμ§ λͺ»ν©λλ€. μ’ λ νμ₯ν΄ μ£Όμκ² μ΅λκΉ? μ’ λ£μλ₯Ό κ°λ¦¬ν€λ λ§μ λκΉ? κ·Έκ²μ λ΄κ° μλμ μ΄ λ΄μ©μ μν₯μ λ―ΈμΉ μ μμ΅λλ€.
pytest-django νλ¬κ·ΈμΈμ django_db
νμλ₯Ό μ¬μ©νλ©° μ΄λ plugin.py(https://github.com/pytest-dev/pytest-django/blob/master/pytest_django/plugin.py)μ _django_db_markerμμ μ²λ¦¬λ©λλ€. #L375), ν¨μ λ²μ db
κ³ μ μ₯μΉ(https://github.com/pytest-dev/pytest-django/blob/master/pytest_django/fixtures.py#L142)λ₯Ό νΈμΆν©λλ€. μ΄ κ³ μ μ₯μΉλ Django TestCaseλ₯Ό μΈμ€ν΄μ€ννκ³ _pre_setup
_post_teardown
λ₯Ό λκΈ°μ΄μ λ£μ΅λλ€.
λͺ κ°μ§ μ΅μ μ λ³Ό μ μμ΅λλ€.
_django_db_marker
λ₯Ό νμ₯νμ¬ μ νμ μΌλ‘ ν΄λμ€ λλ μΈμ
μ μνν μ μλμ§ κΆκΈν©λλ€.
κΈ°λ³Έμ μΌλ‘ db
μ λμΌν μμ
μ μννμ§λ§ cls.setUpTestData
λλ λ§ν¬ kwargsμ μ λ¬λ ν¨μμ λμΌν κΈ°λ₯μ νΈμΆνλ λ²μ μ€μ λ μμ΅λλ€.
ν΄λμ€ λ²μμ κ²½μ°, κ·Έλ¦¬κ³ μΈμ
λ²μμ κ²½μ°μλ μμλλ λμμ μ΄νμ DBλ₯Ό λ‘€λ°±νλ κ²μ΄λ―λ‘ κΈ°λ³Έμ μΌλ‘ μ¬λ°λ₯Έ μμλ‘ νΈλ¦¬κ±°νκ³ κ°κ° κ³ μ ν μμμ±μ μ€μ νλ λ²μ μ§μ κ³ μ μ₯μΉκ° νμν©λλ€. κ±°λ. λλ μ΄κ²μ΄ μμμ μ€νλλ λ³λμ κ³ μ μ₯μΉκ° μλλΌ db
κ³ μ μ₯μΉμ λν μμ μ΄ νμνλ€λ κ²μ μλ―Ένλ€κ³ λ―Ώμ΅λλ€.
κ·Έλ κ² νλ©΄ μ§μ λ λͺ¨λ ν΄λμ€/μΈμ
μμ€ μ€μ μ μ¬λ°λ₯΄κ² νΈλ¦¬κ±°νκ³ ν΄λΉ μ€μ μ ν΄λμ€/μΈμ
λΉ ν λ² νΈμΆλ©λλ€. django_db_blocker.unblock()
λ₯Ό μλμΌλ‘ νΈλ¦¬κ±°νλ μΈμ
λ²μ ν¨μλ₯Ό μ€μ νλ©΄ django_db λ§ν¬κ° 첫 λ²μ§Έ νΈλμμ
μ μ€μ ν νμ λ°μνλ κ²μ²λΌ 보μ΄κΈ° λλ¬Έμ λ§ν¬ μ체μ λν μμ μ΄ νμνλ€κ³ μκ°ν©λλ€.
μ΄κ²μ λ€μκ³Ό κ°μ΄ λ³΄μΌ μ μμ΅λλ€( plugin.py _django_db_marker()
):
if marker:
if marker.session_db:
getfixturevalue(request, 'db_session')
if marker.class_db:
getfixturevalue(request, 'db_class')
validate_django_db(marker)
if marker.transaction:
getfixturevalue(request, 'transactional_db')
else:
getfixturevalue(request, 'db')
μ΄κ²μ λ―ΈμΉ μ΄μΌκΈ°μ λκΉ, μλλ©΄ μ΄ μ€λ λκ° λ νꡬν κ°μΉκ° μμ΅λκΉ?
λ§λ¬΄λ¦¬ κ΄λ ¨: https://github.com/tipsi/pytest-tipsi-testing/blob/master/tests/test_finalization.py
μ΄ ν μ€νΈλ κΈ°λ₯ μμ€μ΄ μλ λ°μ΄ν°λ² μ΄μ€ κ³ μ μ₯μΉμ λ§μ°¬κ°μ§λ‘ λͺ μμ μ’ λ£ μμ΄λ μλνμ§ μμ΅λλ€. κ·Έλ¦¬κ³ μ΄κ²μ pytest ꡬνμ κ΄ν κ²μ΄λ―λ‘ pytest-djangoμμ μμ νκΈ° μν΄ ν μΌμ΄ μμ΅λλ€.
#388 λ° #33μ μ€λ³΅
κ°μ¬ν©λλ€. λ«μ΅λλ€.
π κ°μ¬ν©λλ€!
λν μ΄ κΈ°λ₯μ λ§€μ° λμ΄ νκ°ν κ²μ λλ€.
@mkokotovich
μΌλ§λ λ§μ΄? μ€μ€λ‘ μΌμ΄λκΈ°μ μΆ©λΆν©λκΉ? ;)
μ΄μ¨λ , μ¬κΈ°μ μ£Όμ / κ·Όλ³Έμ μΈ λ¬Έμ (μλ μ£Όμμμ)λ μ΄λ―Έ ν μ€νΈ μ€μ DBκ° μ¬μ€μ λλ―λ‘ μΈμ λ²μ κ³ μ μ₯μΉλ₯Ό μ¬μ©νλ κ°λ¨ν λ°©λ²μ΄ μλ€λ κ²μ λλ€.
κ·Έλλ ν¨κ³Όκ° μλ κ²μ λ€μκ³Ό κ°μ΅λλ€.
@pytest.fixture(scope="session")
def django_db_setup(django_db_setup, django_db_blocker):
with django_db_blocker.unblock():
with transaction.atomic(): # XXX: could/should use `TestCase_enter_atomics` for multiple dbs
load_time_consuming_db_fixture()
yield
λͺ¨λ κ²μ μΆκ° μμ λΈλ‘μΌλ‘ λ¬Άλλ€λ μμ΄λμ΄. κ·Έλ¬λ μ΄κ²μ ν
μ€νΈλμ§ μμμΌλ©° μ€μ λ‘ μ΄λ₯Ό μν΄ TransactionTestCase
λ₯Ό μ¬μ©ν΄μΌ ν μλ μμ΅λλ€.
@paultiplady
κ·νμ μ견μ μ’μ κ² κ°μ΅λλ€. μ¦, AFAICSλ₯Ό μΆκ°λ‘ νμν κ°μΉκ° μμ΅λλ€(μ΄μ μ견λ μ°Έμ‘°).
@blueyed μ°λ¦¬λ μ΄λ¬ν μ κ·Ό λ°©μμ 1λ
μ΄μ μ¬μ©νκ³ μμ΅λλ€(λͺ¨λ κ²μ μΆκ° μμ λΈλ‘μΌλ‘ λ¬Άμ). κ½€ μ μλν©λλ€.
κ·Έλ¬λ pytestμλ μΈμ
μμ€(ν
μ€νΈ μ΄μΈμ λ€λ₯Έ μμ€)μ΄ λ«ν κ²°μ μ μΈ μμΉκ° μμΌλ―λ‘ μλ‘λ₯Ό νμλ‘ νλμ§ μ¬λΆμ κ΄κ³μμ΄ db νΈλμμ
μ μ’
μμ±μ μΆμ ν΄μΌ ν©λλ€. .
λ°λΌμ λ€μ ν
μ€νΈ μ μ νΈλμμ
μ€νμ λͺ
μμ μΌλ‘ μΆμ νκ³ μ€μ²©λ νΈλμμ
μ λ«μμΌ ν©λλ€. λ€μκ³Ό κ°μ λ°©μμΌλ‘ μνν μ μμ΅λλ€. https://github.com/tipsi/pytest-tipsi-django/blob/master/pytest_tipsi_django/django_fixtures.py#L46
μ£μ‘ν©λλ€. λμΌν λ¬Έμ κ° λ°μνλ€κ³ μκ°νκΈ° λλ¬Έμ λͺ νν νκ³ μΆμ΅λλ€.
μλ‘μ΄ db κ°μ²΄ μμ±μ μμ‘΄νλ μ‘°λͺ κΈ°λ₯Ό λ§λ€κ³ μΆλ€λ©΄ ν μ μλ€κ³ μκ°νμ΅λλ€.
@pytest.mark.django_db(transaction=True)
@pytest.fixture(scope="session")
def object():
object = Object.create_object(params)
yield object
// or alternatively
object = mixer.blend('myObject')
yield object
κ·Έλ¬λ ν
μ€νΈ μΌμ΄μ€ μ€ν μ λ€μ μ€λ₯κ° λ°μν©λλ€. Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
κ°μ₯ μ μ©ν λκΈ
μ΄κ²μ Djangoμ UnitTest ν΄λμ€ κΈ°λ° ν μ€νΈμμ pytest-djangoμ μ΄λ₯΄λ κ°μ₯ ν° λ¬Έμ μμ΅λλ€. Djangoμμλ
setUpTestData
λ₯Ό μ¬μ©νμ¬ κ°λΉμΌ DB μμ μ ν λ² μ€νν©λλ€(μΈμ λ²μμ pytest κ³ μ μ₯μΉμ λμΌ). 그리κ³setUp
obj.refresh_from_db()
λ₯Ό μ€ννμ¬ ν΄λμ€ μ°Έμ‘°λ₯Ό μλ‘ κ³ μΉλ κ΅νν νΈλ¦μ΄ μμ΅λλ€.DB λͺ¨λΈ μΈμ€ν΄μ€λ₯Ό νλλ§ μμ±νκ³ TCλ§λ€ λ€μ λ‘λνλλΌλ κ° ν μ€νΈ μ¬λ‘μμ μμ±νλ κ²λ³΄λ€ κ±°μ νμ λΉ λ¦ λλ€.
κ°λ₯ν κ²½μ° pytest-tipsi-django λ³ν©λ μ μ€νΈλ¦Όμμ μΈμ λ²μ κ³ μ μ₯μΉλ₯Ό κ°μ Έμ¬ μ μλ€λ©΄ μ’μ κ²μ λλ€. μ΄ λ¬Έμ μ μ루μ μ μ°Ύλ λ° μ½κ°μ νκ³ κ° νμνμ΅λλ€.