λ΄ ν μ€νΈ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
import pytest
pytestmark = pytest.mark.django_db
from handy.db import do_sql, fetch_val
def setup_module(fetch_val):
print 1
do_sql('''
create table test (
id int primary key,
tag int not null
);
insert into test values (1, 10), (2, 20);
''')
print 2
def test_fetch_val():
print 3
assert fetch_val('select min(id) from test') == 1
κ·Έλ¦¬κ³ DatabaseError: relation "test" does not exist
μμ test_fetch_val()
λ°μ΅λλ€. λλ λν μ»λλ€
2
Creating test database for alias 'default'...
3
μΊ‘μ²λ μΆλ ₯. λ°μ΄ν°λ² μ΄μ€κ° μμ±λκΈ° μ μ setup_module()
κ° νΈμΆλ κ² κ°μ΅λλ€.
django_db λ§ν¬λ ν½μ€μ²λ₯Ό κΈ°λ°μΌλ‘ νλλ°, ν½μ€μ²μ setup_* λ©μλ μ¬μ΄μ μ΄λ»κ² ν΅μ ν΄μΌ νλμ§ μ λͺ¨λ₯΄κ² μ΅λλ€.
λμΌν κ²μ λ¬μ±νκΈ° μν΄ λμ λͺ¨λ λ²μ κ³ μ μ₯μΉλ₯Ό μ¬μ©ν μ μμ΅λκΉ? μ¦, λκ°
pytestmark = pytest.mark.usefixture('test_table')
@pytest.fixture(scope='module')
def test_table(db):
do_sql('create table ...')
def test_fetch_val():
assert fetch_val('...') == 1
λ°©κΈ μλνμ΅λλ€. μλνμ§ μμμ΅λλ€. μ§κΈ Database access not allowed, use the "django_db" mark to enable
λ°μ΅λλ€.
λν test_table()
κ° μ€νλμ§ μμ΅λλ€(μ¬κΈ°μ μμΈλ₯Ό λ°μμν€λ €κ³ νμ΅λλ€)
μ£μ‘ν©λλ€. Fixtureκ° μλλΌ Fixtureλ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
μ΄μ ScopeMismatchError: You tried to access the 'function' scoped funcarg 'db' with a 'module' scoped request object, involved factories
μ»μ΅λλ€.
맀κ°λ³μμμ db
맀κ°λ³μλ₯Ό μ κ±°νλ©΄ κ³ μ μ₯μΉκ° μ€ν¨νκ³ scope='module'μ μ κ±°νλ©΄ μλνλ€κ³ μκ°νμ§λ§ λͺ¨λ ν
μ€νΈμ λν΄ test_table()
κ° μ€νλλ―λ‘ μνμ§ μμ΅λλ€.
λλ λν μλνλ€
pytestmark = pytest.mark.django_db
@pytest.fixture(scope='module')
def test_table():
do_sql('''
create table test (
id int primary key,
tag int not null
);
insert into test values (1, 10), (2, 20);
''')
def test_fetch_val(test_table):
assert fetch_val('select min(id) from test') == 1
def test_fetch_val2(test_table):
assert fetch_val('select min(id) from test') == 1
κ±°μ μλνμ§λ§ λ λ²μ§Έ ν
μ€νΈλ DatabaseError: relation "test" does not exist
μ΄λ»κ²λ μ€ν¨ν©λλ€. λμκ² μμ ν λ―Έμ€ν°λ¦¬.
Djangoμ django_db λ§μ»€λ κ° ν μ€νΈ μΌμ΄μ€κ° μ체 νΈλμμ μμ μ€νλλ λ°©μμΌλ‘ μλνλ―λ‘ λ°μ΄ν°λ² μ΄μ€μ λ°μ΄ν°λ₯Ό μ½μ νλ λͺ¨λ μμ€ κ³ μ μ₯μΉμ ν¨κ» django_dbλ₯Ό μ¬μ©νλ κ²μ μ€μ λ‘ μλ―Έκ° μμ΅λλ€.
μ¬κΈ°μ μ¬μ© μ¬λ‘λ 무μμ λκΉ? Djangoκ° μλ ν μ€νΈμμ "μμΌλ‘" λ°μ΄ν°λ² μ΄μ€ ν μ΄λΈμ λ§λλ μ΄μ λ 무μμ λκΉ? νμ§λ§ μ¬μ ν Djangoμ ν μ€νΈ λ°μ΄ν°λ² μ΄μ€/ν μ€νΈ λ°μ΄ν°λ² μ΄μ€ 컀μλ₯Ό μ¬μ©νκ³ μΆμ΅λκΉ?
μΌλ° λ°μ΄ν°λ² μ΄μ€ 컀μλ₯Ό ꡬμ±νλ κ²λ§μΌλ‘λ μνλ κ²μ μ»μ μ μμ΅λκΉ?
(λ§μ§λ§ μμ λ ScopeMismatchErrorλ₯Ό νΌνμ§λ§ 첫 λ²μ§Έ ν μ€νΈ νμ νΈλμμ μ΄ λ‘€λ°±λμ΄ ν μ€νΈ ν μ΄λΈμ λ‘€λ°±νκΈ° λλ¬Έμ λμ ν μ€νΈμμ μ€ν¨ν©λλ€.)
λ΄λΆμ μΌλ‘ django 컀μλ₯Ό μ¬μ©νλ λͺ κ°μ§ μ μμ€ db μ νΈλ¦¬ν°λ₯Ό ν μ€νΈνλ €κ³ ν©λλ€. - https://github.com/Suor/handy/blob/master/handy/db.py#L40
κ·Έλ¦¬κ³ models.py
λ‘ λͺ¨λΈμ μ μν λ€μ μ΄λ₯Ό ν
μ€νΈνκΈ° μν΄ μΌλΆ django νμμ κ³ μ μ₯μΉλ₯Ό μ μνλ κ²μ΄ ν¨μ¬ λ 볡μ‘ν κ²μ
λλ€. κ½€ κΈ°λ³Έμ μΈ κΈ°λ₯μ ν
μ€νΈνλ €λ©΄ μ΄ 3κ°μ νμΌμ΄ νμν©λλ€.
ν μ€νΈλ₯Ό μ€ννκΈ° μ μ λͺ κ°μ§ λ°μ΄ν°λ₯Ό κ°μ§κ³ λ μ μλλ‘ μ΄κΈ°ν μ½λλ₯Ό μ€ννκ³ μΆμ΅λλ€.
μ€, ν΄λμ΄! μ΄κΈ°ν SQLμ begin; ... commit;
λ‘ λννλ κ²μ΄ λμμ΄ λμμ΅λλ€.
μ 곡ν λͺ¨λ νμ κ°μ¬λ립λλ€.
κ·Έκ²μ λμκ² μ½κ° μ·¨μ½ν΄ 보μ΄λ ν΄νΉμ λλ€. λλ μλ§λ λΉμ μ΄ κ·Έ κΈ°λ₯μ μ€ννλ λ° μ¬μ©ν μ μλ κ°λ¨ν λͺ¨λΈμ΄ μλ ν μ€νΈμλ§ μ¬μ©λλ μΆκ° μ±μ μ€μ ν κ²μ λλ€. κ·Έλ° λ€μ Djangoμ ORMμ μ¬μ©νμ¬ ν μ€νΈμ λ°μ΄ν°λ₯Ό μ½κ² μ±μΈ μ μμ΅λλ€. μ½κ° λ λ§μ μ λ ₯κ³Ό λͺ κ°μ μΆκ° νμΌμ΄ νμνμ§λ§ λμ€μ νμλ κ²½μ° μμ ν΄μΌ ν©λλ€.
λ€λ₯Έ μ¬λμ΄ μ΄ λ¬Έμ λ₯Ό λ°κ²¬νλ©΄: pytest-djangoμ λ°μ΄ν°λ² μ΄μ€ μ€μ μ΄ κ³ μ μ₯μΉλ₯Ό κΈ°λ°μΌλ‘ νκΈ° λλ¬Έμ setup_function/setup_class/setup_moduleμμ λ°μ΄ν°λ² μ΄μ€ μ€μ μ μννλ κ²μ μ€μ λ‘ μ§μλμ§ μκ±°λ μ’μ λ°©μμΌλ‘ κ°λ₯νμ§ μμ΅λλ€.
ν΄κ²°μ±
μ db κ³ μ μ₯μΉλ₯Ό μ μ νκ² μμ²νλ κ³ μ μ₯μΉλ₯Ό μ¬μ©νλ κ²μ
λλ€.
http://pytest-django.readthedocs.org/en/latest/helpers.html#db
@ν λ©
db
κ³ μ μ₯μΉλ₯Ό μ¬μ©νλ©΄ ν΄λμ€, λͺ¨λ λλ μΈμ
μ΄ μλ ν¨μ λ²μμμλ§ μ΄λ¬ν μ€μ μ μ€νν μ μμ΅λλ€. μλ₯Ό λ€μ΄ ν΄λμ€ ν
μ€νΈκ° μ€νλκΈ° μ μ μΌλΆ λ μ½λλ₯Ό λ°μ΄ν°λ² μ΄μ€μ μ±μμΌ νλ κ²½μ°μ
λλ€.
==================================== ERRORS ====================================
___________ ERROR at setup of TestHistoryAlerts.test_one_point_data ____________
ScopeMismatch: You tried to access the 'function' scoped fixture 'db' with a 'session' scoped request object, involved factories
tests/conftest.py:140: def ts(db)
../../../../.virtualenvs/app/lib/python2.7/site-packages/pytest_django/fixtures.py:158: def db(request, _django_db_setup, _django_cursor_wrapper)
μ²λ¦¬ν μ μλ λ€λ₯Έ λ°©λ²μ΄ μμ΅λκΉ?
λ€, νμ¬ κ΅¬νλμ΄ μλ db Fixtureμ νκ³μ λλ€. PR #258μλ ν΄λμ€/λͺ¨λ/μΈμ λ²μμ μν΄ λ¬ΆμΈ λ°μ΄ν°λ² μ΄μ€ μνλ₯Ό μμ±ν μ μλλ‘ νκΈ° μν μμ μ΄ μμμ΅λλ€.
μ΄λ €μ΄ μ΄ λ¬Έμ λ κ½€ μ€λλμμ§λ§ pytest
λ° pytest-django
λ¬Έμ μ λν ν΄κ²°μ±
μ μ°Ύλ κ²μ΄ μ μ©νλ€λ κ²μ μμμ΅λλ€. pytest 3.5.0
μ΄ν django_db
λ§ν¬μ module
λ 벨 λΉνμ μ¬μ©ν λ λ¬Έμ κ° μμ΅λλ€.
μλλ 3.5.0
μ΄μ μ μλνμ΅λλ€(μ μ΄λ λ¬Έμ λ₯Ό μΌμΌν€μ§ μμμ΅λλ€).
@pytest.fixture(scope='module')
def user():
return User.objects.create(...)
@pytest.mark.django_db
def test_some_case(user):
pass
3.5.0
μλ
Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
ν΄κ²°μ±
μ scope='module'
λ₯Ό μ κ±°νλ κ²μ
λλ€.
+1 μ μκ²λ μΌλΆ μ΄κΈ° Djano λ¨μ ν μ€νΈμμ μ ννλ κ²λ§μΌλ‘λ API ν μ€νΈ μ¬λ‘μ λν λ°μ΄ν°λ² μ΄μ€λ₯Ό μ΄κΈ°νν λ μ£Όμ λ¨μ μ λλ€. μ€μ λ‘ μ§μνλ μΈμ /λͺ¨λ λ°μ΄ν°λ² μ΄μ€ κ³ μ μ₯μΉλ κΈ°λ³Έ κΈ°λ₯μ΄μ΄μΌ ν©λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²μ λν μ μ μ¬νμ΄ μμ΅λκΉ?
+1
κ°μ₯ μ μ©ν λκΈ
+1 μ μκ²λ μΌλΆ μ΄κΈ° Djano λ¨μ ν μ€νΈμμ μ ννλ κ²λ§μΌλ‘λ API ν μ€νΈ μ¬λ‘μ λν λ°μ΄ν°λ² μ΄μ€λ₯Ό μ΄κΈ°νν λ μ£Όμ λ¨μ μ λλ€. μ€μ λ‘ μ§μνλ μΈμ /λͺ¨λ λ°μ΄ν°λ² μ΄μ€ κ³ μ μ₯μΉλ κΈ°λ³Έ κΈ°λ₯μ΄μ΄μΌ ν©λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²μ λν μ μ μ¬νμ΄ μμ΅λκΉ?