Djangoã®ãã¹ãã«ã¤ãã¦èãã¦ããã¨ããã以ä¸ã®è¨äºã«åºä¼ãã¾ããã
- Djangoã®ãã¹ãã®æ¸ãæ¹ã«ã¤ãã¦åå¼·ããã®ã§ã¾ã¨ãã - c-bata web
- Django Best Practice ã¸ã®é #2
å¾è
ã®è¨äºã«ãããéããpytest
ã§ã¯ãã¹ãã®å¤±æå
容ãç´°ããåºãããã§ããã
ãã®ãããDjangoåãã®pytestã©ã¤ãã©ãªpytest-django
ã使ã£ã¦ãã¹ãã³ã¼ããæ¸ãã¦ã¿ã¾ããã
ç®æ¬¡
- ç°å¢
- 試ãããã©åãããªãã£ããã¨
- 試ãã¦ãªããã¨
- ãã¹ã対象ã®ã¢ããª
- ã»ããã¢ããã¨ã¢ããªä½æ
- pytest.iniã®ä½æ
- Modelã®ãã¹ã
- URL解決ã®ãã¹ã
- Viewã®ãã¹ã
- Formã®ãã¹ã
- å ¨ä½ã®æµãã®ãã¹ã
- pytest-djangoã§ãDeprecationWarningã®ãã§ãã¯
- ã½ã¼ã¹ã³ã¼ã
ã
ç°å¢
ã
試ãããã©åãããªãã£ããã¨
Djangoã®ãã¹ããæ¸ãä¸ã§ãä¸è¬çã«ã¯ã©ã¡ãã使ãã®ããåãããªãã£ããã®ãæ®ãã¦ããã¾ãã
ããæéãªã©ãããã°æãã¦ããã ããã¨ãããããã§ãã
Viewã®ãã¹ãã§ãªã¯ã¨ã¹ããéä¿¡ããéã
django.test.Client
ã¨RequestFactory
ã®ã©ã¡ãã使ãã®ã- ä»åã¯ãViewã®ãã¹ãã¯RequestFactoryããã以å¤ã®ãã¹ãã¯ããã«ã¦ã§ã¢ãé¢ä¿ããã®ã§Clientã使ã£ã¦ã¿ã
ãã¹ãä¸ã®URLã¯ããã¼ãã³ã¼ãã£ã³ã°ããã®ãã
django.core.urlresolvers.reverse()
ã使ãã®ã- ä»åã¯ãURL解決ã®ãã¹ãã¯ãã¼ãã³ã¼ãã£ã³ã°ããã以å¤ã®ãã¹ãã¯reverse()ã使ã£ã¦ã¿ã
ã
試ãã¦ãªããã¨
ä»åã¯ããã£ã¨è§¦ããã ããªã®ã§ã以ä¸ã®ãã¹ãã³ã¼ãã¯æ¸ãã¾ããã§ããã
- ã¢ãã¯ãªã©ã®ãã¹ãããã«ã使ã£ããã¹ã
- Seleniumã使ã£ããã¹ã
ã
ãã¹ã対象ã®ã¢ããª
以ä¸ã®ãããªæµãã®ãã¹ã対象ã¢ããªã使ãã¾ããã
mysite/create
ã¸ã¢ã¯ã»ã¹ããã¨ãCreateView + ModelFormã使ã£ãç»é²ãã©ã¼ã ã表示- ç»é²ãã©ã¼ã ã«å ¥åãPOST
- POSTãã¼ã¿ãDBã¸ä¿å
mysite/item/<ã¬ã³ã¼ãã®id>
ã¸ãªãã¤ã¬ã¯ãããDetailViewã使ã£ã詳細ç»é¢ã表示
ã
ã»ããã¢ããã¨ã¢ããªä½æ
virtualenvç°å¢ä½æããã¢ããªä½æã¾ã§ãè¡ãã¾ãã
d:\Sandbox\Django_pytest_sample>virtualenv -p c:\python35-32\python.exe env d:\Sandbox\Django_pytest_sample>env\Scripts\activate (env) d:\Sandbox\Django_pytest_sample>pip install django pytest-django (env) d:\Sandbox\Django_pytest_sample>django-admin startproject myproject . # 以ä¸ãåèã«ãã¢ããªã®ãã£ã¬ã¯ããªãå ã«ä½æãã¦ãã # http://stackoverflow.com/questions/33243661/startapp-with-manage-py-to-create-app-in-another-directory (env) d:\Sandbox\Django_pytest_sample>mkdir apps\myapp (env) d:\Sandbox\Django_pytest_sample>python manage.py startapp myapp apps/myapp # ã¢ããªä½æ (çç¥) # ãã¤ã°ã¬ã¼ã·ã§ã³ (env) d:\Sandbox\Django_pytest_sample>python manage.py makemigrations (env) d:\Sandbox\Django_pytest_sample>python manage.py migrate # ãã¹ãã³ã¼ãç¨ã®ãã£ã¬ã¯ããªä½æ (env) d:\Sandbox\Django_pytest_sample>mkdir apps\myapp\tests
ãã®æç¹ã®ã¢ããªã®ã³ã¼ãã¯ã以ä¸ã®éãã§ãã
thinkAmi-sandbox/Django_pytest_sample at b989361d37e24a069167386611be3ceb6165c757
ã
pytest.iniã®ä½æ
pytest-djangoã使ã£ã¦ãã¹ãããããã«ãè¨å®ãã¡ã¤ã«pytest.ini
ã使ããDJANGO_SETTINGS_MODULE
ãè¨å®ãã¾ãã
Getting started with pytest and pytest-django â pytest-django documentation
ã
ãªããä»åããã¸ã§ã¯ãã«ã¼ãä¸ã«virtualenvç°å¢ãä½ã£ãããããã®ã¾ã¾ã§ã¯ã¤ã³ã¹ãã¼ã«ããã©ã¤ãã©ãªããã¹ã対象ã¨ãªã£ã¦ãã¾ãã¾ãã
(env) d:\Sandbox\Django_pytest_sample>py.test ... collected 31 items env\Lib\site-packages\django\contrib\admindocs\tests\test_fields.py ...
ã
ãã®ãããnorecursedirs
ãè¨å®ããenvãã£ã¬ã¯ããªä»¥ä¸ã®ã©ã¤ãã©ãªã¯ãã¹ã対象å¤ã¨ãã¾ãã
Basic test configuration - norecursedirs
ã
æçµçãªpytest.ini
ã¯ä»¥ä¸ã®éãã¨ãªãã¾ãã
[pytest] DJANGO_SETTINGS_MODULE=myproject.settings norecursedirs=env
ã
ããã§ãã¹ãã®æºåãã§ããããããã¹ãã³ã¼ããæ¸ãã¦ããã¾ãã
ã
Modelã®ãã¹ã
models.py
ã«å¯¾ãããã¹ãã³ã¼ãã¨ãã¦ãtest_models.py
ã使ãã¾ãã
Itemã¢ãã«ã®åãã£ã¼ã«ãã«ã¯
- name: 3æå以ä¸255æå以ä¸ã§ãããã¨
- unit_price: 0以å¤ã®10æ¡ã¾ã§ã®æ°åã§ãããã¨
ã¨ããå¶éãæããã¦ãããããããªãã¼ã·ã§ã³ã¨ã©ã¼ã¨ãªã£ãå ´åãValidationError
ä¾å¤ãéåºãã¾ãã
ããã§ããããã®validatorã®åä½ãModel.full_clean()
ã使ã£ã¦ãã¹ããã¾ãã
ã
ããªãã¼ã·ã§ã³ã¨ã©ã¼ã¨ãªããã¹ãã±ã¼ã¹ã«ã¤ãã¦ã¯ã
def test_nameãé·ãããå ´å_ã¨ã©ã¼(self): with pytest.raises(ValidationError): model = Item(name='1'*256, unit_price=100) model.full_clean()
ã®ããã«ãã¦ä¾å¤ãéåºããããããã¹ããã¾ãã
Assertions about expected exceptions - The writing and reporting of assertions in tests
ã
ã¾ããä¾å¤ã«å«ã¾ããã¡ãã»ã¼ã¸ã確èªããå ´åã¯
def test_unit_priceãã¼ãã®å ´å_ã¨ã©ã¼(self): with pytest.raises(ValidationError) as excinfo: model = Item(name='abc', unit_price=0) model.full_clean() assert 'unit_priceã«ã¯ã¼ããè¨å®ã§ãã¾ãã' in excinfo.value.messages
ã®ããã«ãValidationError.value.messages
ã®å¤ã使ãã¾ãã
django/exceptions.py - GitHub
ã
䏿¹ãä¾å¤ãçºçããªããã¨
ã確èªããããã
def test_unit_priceãæ£å¸¸ãªå ´å_ã¨ã©ã¼ã¨ãªããªã(self): model = Item(name='abc', unit_price=10**9) try: model.full_clean() except: pytest.fail()
ã¨ãä¾å¤ãçºçããå ´åã«ã¯pytest.fail()
ã使ã£ã¦ãã¹ãã失æããããã«ãã¾ãã
Pytest API and builtin fixtures
ã
ä»ã«ãpytest.mark.parametrize
ãã³ã¬ã¼ã¿ã使ã£ããã©ã¡ã¿ã©ã¤ãºããã¹ãã試ãã¦ã¿ããã£ããããæ£å¸¸ç³»ã®ãã¹ãã±ã¼ã¹ã§
@pytest.mark.parametrize(['input',],[('a'*3), ('a'*255),]) # parametrizeã使ãå ´åãselfã¯å¼æ°ã¨ãã¦åãåããªãæ¨¡æ§ def test_nameãæ£å¸¸ãªå ´å_ã¨ã©ã¼ã¨ãªããªã(input): model = Item(name=input, unit_price=100) try: model.full_clean() except: pytest.fail()
ã¨æ¸ãã¦ã¿ã¾ããã
@pytest.mark.parametrize: parametrizing test functions - Parametrizing fixtures and test functions
ã
URL解決ã®ãã¹ã
urls.py
ã«å¯¾ãããã¹ãã³ã¼ãã¨ãã¦ãtest_urls.py
ã使ãã¾ãã
ãã¹ãã§ã¯
- URLãåå¨ããå ´åã対å¿ããã¯ã©ã¹ãå¼ã°ãã¦ããã
- URLãåå¨ããªãå ´åã
Resolver404
ä¾å¤ãçºçããã
ã確èªãã¾ãã
def test_åå¨ããªãURLã®å ´_ã¨ã©ã¼(self): with pytest.raises(Resolver404): resolve('/mysite/not-exist') def test_ååç»é²ã®URLã®å ´å_URL解決ããã(self): found = resolve('/mysite/create') assert found.func.__name__ == ItemCreateView.__name__ def test_åå詳細ã®URLã®å ´å_URL解決ããã(self): # DBã«ãã¼ã¿ããªãã®ã§404ãã³ãã¬ã¼ãã使ããããã©ãresolveããã¦ãã found = resolve('/mysite/item/1/') assert found.func.__name__ == ItemDetailView.__name__
ã
Viewã®ãã¹ã
views.py
ã«å¯¾ãããã¹ãã³ã¼ãã¨ãã¦ãtest_views.py
ã使ãã¾ãã
ãã¹ãã§ã¯
- æ£ããã¹ãã¼ã¿ã¹ã³ã¼ãã
- æ£ãããã³ãã¬ã¼ãã使ã£ã¦ããã
ã確èªãã¾ãã
ã
ãªããViewã¸ã®ãªã¯ã¨ã¹ãæ¹æ³ã¨ãã¦ã
ã®2種é¡ããããããããããã使ã£ã¦æ¸ãã¦ã¿ã¾ããã
ã
Clientã使ãå ´å
def test_ç»é²ç»é¢Viewã使ããã¦ãã_Clientç(self): response = self.client.get(reverse('my:item-creation')) self.assertTemplateUsed(response, 'myapp/item_form.html') assert response.status_code == 200 def test_詳細ç»é¢Viewã使ããã¦ãã_Clientç(self): # ãã¼ã¿ãç»é²ããªãã¨è¡¨ç¤ºãããªãã®ã§ãäºåã«ç»é²ãã¦ãã Item(name='abc', unit_price=100).save() response = self.client.get(reverse('my:item-detail', args=(1,))) self.assertTemplateUsed(response, 'myapp/item_detail.html') assert response.status_code == 200
ã
RequestFactoryã使ãå ´å
def test_ç»é²ç»é¢Viewã使ããã¦ãã_RequestFactoryç(self): request = RequestFactory().get(reverse('my:item-creation')) response = ItemCreateView.as_view()(request) # ãã³ãã¬ã¼ãåã¯listã§å ¥ã£ã¦ãã®ã§inã使ã£ã¦ç¢ºèªãã # https://docs.djangoproject.com/ja/1.9/ref/template-response/#django.template.response.SimpleTemplateResponse assert 'myapp/item_form.html' in response.template_name assert response.status_code == 200 def test_詳細ç»é¢Viewã使ããã¦ãã_RequestFactoryç(self): Item(name='abc', unit_price=100).save() request = RequestFactory().get(reverse('my:item-detail', args=(1,))) response = ItemCreateView.as_view()(request) assert 'myapp/item_form.html' in response.template_name assert response.status_code == 200
ã
- åè
ã
Formã®ãã¹ã
ä»åã¯ModelFormã使ã£ã¦ãããããmodel_forms.py
ã«å¯¾ãããã¹ãã³ã¼ãã¨ãã¦ãtest_model_forms.py
ã使ãã¾ãã
é常ãModelFormã¯Modelã¨ç´ä»ãã¦ããé¨åã®ãã¹ãã¯ä¸è¦ã§ãã
unit testing - How to test approriately ModelForms and views in Django - Stack Overflow
ãã ä»åãModelFormã ãã®é
ç®form_only
ã¨ããã«å¯¾ããvalidatorãå®è£
ãã¦ãããããModelForm.is_valid()
ã使ã£ããã¹ããæ¸ãã¾ãã
def test_form_onlyã«å¤ããªãå ´å_ã¨ã©ã¼(self): form = ItemModelForm({'form_only': '', 'name': 'test', 'unit_price': 100}) assert form.is_valid() == False # 以ä¸ç¥
ã
å ¨ä½ã®æµãã®ãã¹ã
å ¨ä½ã®æµãã®ãã¹ãã³ã¼ãã¨ãã¦ã
- æ£å¸¸ç³»
- POSTå¾ãªãã¤ã¬ã¯ããã¦ããã
- ãªãã¤ã¬ã¯ãå¾ã¯æ£ããViewã使ç¨ãã¦ããã
- ãã³ãã¬ã¼ãã«è¡¨ç¤ºããã¦ããå¤ã¯æ£ããã
- ãã¼ã¿ãã¼ã¹ã«ä¿åããã¦ããã
- ç°å¸¸ç³»
- ãã©ã¼ã ã§ã¨ã©ã¼ãçºçãã¦ããã
- ãã¼ã¿ãã¼ã¹ã«ä¿åããã¦ããªãã
ã確èªãããããtest_myapp.py
ã使ãã¾ãã
ã
æ£å¸¸ç³»
ãªãã¤ã¬ã¯ãã®ç¢ºèª
ãªãã¤ã¬ã¯ãããã¦ãããã®ç¢ºèªã«ã¯ãself.assertRedirects()
ã使ãã¾ãã
python - Django : Testing if the page has redirected to the desired url - Stack Overflow
ä»åã®ããã«CreateViewã§ãªãã¤ã¬ã¯ãããå ´åããªãã¤ã¬ã¯ãæã®ã¬ã¹ãã³ã¹ã§ã¯HttpResponseRedirect
ãè¿ããã*1ãã¹ãã¼ã¿ã¹ã³ã¼ãã¯302
ã¨ãªãã¾ãã
Request and response objects - HttpResponseRedirect | Django documentation | Django
ã¾ããä»åã¯1ä»¶ã ãã®ç»é²ãªã®ã§ãurls.pyã«ã¦å®è£
ããpk
ã«1ãæ¸¡ãã¦ãã¾ã(kwargs={'pk': 1})
)ã
self.assertRedirects(response, reverse('my:item-detail', kwargs={'pk': 1}), status_code=302)
ã
ãªããPOSTå¾ã«ãªãã¤ã¬ã¯ããä¼´ãå ´åãdjango.test.Client.post()
ã®å¼æ°ã«follow = True
ãè¨å®ãã¦ããã¨ããªãã¤ã¬ã¯ãå
ã®æ
å ±ãcontextãªã©ã«æ ¼ç´ããã¾ãã
Testing tools - django.test.Client.get | Django documentation | Django*2
response = self.client.post(reverse('my:item-creation'), { 'form_only': 'alphabet', 'name': 'post_test', 'unit_price': 100, }, follow=True)
ã
䏿¹ãããã©ã«ãã®follow=False
ã¨ããå ´åã¯ã
- ã¹ãã¼ã¿ã¹ã³ã¼ãã¯ã
302
- response.contextã¯ã
None
ã¨ãªãããªãã¤ã¬ã¯ãå ã®æ å ±ãå°ãªãã§ãã
ãã®ãããfollow=Falseã§ããªãã¤ã¬ã¯ãæ
å ±ãæ±ãããå ´åã¯ãDjangoã®ã½ã¼ã¹ã³ã¼ãã«å¾ããself.client._handle_redirects(response)
ã使ãã°è¯ãããã§ãã
django/client.py at 21dd98a38660747c781802afca7ca02407964383 · django/django
ã
ãã³ãã¬ã¼ãã«æ¸¡ãcontextã®å¤ã®ç¢ºèª
Response.context
ã«è¨å®ããã¦ããå¤ã確èªãã¾ãã
Testing tools - django.test.Response.context | Django documentation | Django
contextã¸ã¯
object
- (åºå ¸å¿ã)
- DetailViewã®
context_object_name
ã®å¤ããDetailViewã®Modelã®lowercaseå- ä»åã¯context_object_nameãã»ãããã¦ããªããããå¾è
ã®å¤
item
ã¨ãªãã¾ã - Single object mixins | Django documentation | Django
- ä»åã¯context_object_nameãã»ãããã¦ããªããããå¾è
ã®å¤
ãªã©ã§ã¢ã¯ã»ã¹ã§ããããã以ä¸ã®ããã«ãã¦ãã¹ããã¾ãã
assert response.context['object'].unit_price == 100 assert response.context['item'].unit_price == 100
ã
Viewã®ç¢ºèª
response.resolver_match.func.__name__
ã使ãã¾ãã
Testing tools - resolver_match | Django documentation | Django
assert response.resolver_match.func.__name__ == ItemDetailView.as_view().__name__
ã
ãã¼ã¿ãã¼ã¹ã«ç»é²ããã¦ããã
ç»é²ãããä»¶æ°ã¨å 容ã確èªãã¾ãã
actual = Item.objects.all() actual_item = actual[0] assert actual.count() == 1 assert actual_item.name == 'post_test' assert actual_item.unit_price == 100
ã
ç°å¸¸ç³»
ãã©ã¼ã ã§ã¨ã©ã¼ãçºçãã¦ããã
ãã©ã¼ã ã§ã¨ã©ã¼ãçºçãã¦ãããã¯ãassertFormError()
ã使ãã¾ãã
Testing tools - assertFormError | Django documentation | Django
ãªãã第äºå¼æ°ã«ã¯ããã©ã¼ã ãªãã¸ã§ã¯ãã§ã¯ãªãformã®contextåãè¨å®ãã¾ã(é常ã¯form
)ã
self.assertFormError(response, 'form', 'form_only', 'form_onlyã®å¤ 1 ã«ã¢ã«ãã¡ããã以å¤ãå«ã¾ãã¦ãã¾ã')
- åè
ã
ã¹ãã¼ã¿ã¹ã³ã¼ãã®ç¢ºèª
Djangoã§ã¯ãããªãã¼ã·ã§ã³ã¨ã©ã¼ã®å ´åã§ããããã©ã«ãã®ã¹ãã¼ã¿ã¹ã³ã¼ãã¯200
ã§ãã
assert response.status_code == 200
ã
Viewã®ç¢ºèª
Viewã夿´ããã¦ããªããã¨ã確èªãã¾ãã
assert response.resolver_match.func.__name__ == ItemCreateView.as_view().__name__
ã
ãã¼ã¿ãã¼ã¹ã«ä¿åããã¦ããªãã
1ä»¶ãç»é²ããã¦ããªããã¨ã確èªãã¾ãã
assert Item.objects.all().count() == 0
ã
pytest-djangoã§ãDeprecationWarningã®ãã§ãã¯
ããã¾ã§ã®ãã¹ãã³ã¼ãã§Djangoã¢ããªã«åé¡ããªããããã¹ãã§ãã¾ããã
ãã ãDjangoã®ãã¼ã¸ã§ã³ãä¸ããã¨DeprecationWarningãçºçãããã¨ãèãããã¾ãã
Djangoã®DeprecationWarningã確èªãã - åã£ãè¨èªä¿¡è
ã®åãæµã
ããã§ããã¹ãã®å®è¡ã¨åæã«DeprecationWarningã確èªãã¦ã¿ã¾ãã
ã
ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã使ã£ããã§ãã¯
ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã§ããã¹ãã®å®è¡ã¨DeprecationWarningã®ãã§ãã¯ãè¡ãã¾ãã
django-admin and manage.py - check | Django documentation | Django
(env) >python -Wd manage.py check & py.test ... path\to\myproject\urls.py:22: RemovedInDjango20Warning: Specifying a namespace in django.conf.urls.include() without providing an app_name is deprecated. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead. url(r'mysite/', include('apps.myapp.urls', namespace="my")),
ä»ã¾ã§ã®ã½ã¼ã¹ã³ã¼ãä¸ã«ãDeprecationWarningã1ã¤åå¨ãã¦ãããã¨ã確èªã§ãã¾ããã
ã
pytestã®ããã¯ã使ã£ã¦ããã¹ãã¨åæã«ãã§ãã¯
ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã®å ´åãæ¯åpython -Wd manage.py check & py.test
ã¨ããå¿
è¦ãããããããã£ããå¿ããããªæ°ããã¾ããã
ããã§ãpytestã®è¨å®ã§å¯¾å¿ã§ããªãã調ã¹ã¦ã¿ãã¨ãããpy.testã«ããã¯ãããã¾ããã
Writing plugins - pytest hook reference
ããã¯ã¯ããã¤ãããã¾ãããä»åã®DeprecationWarningã®ãã§ãã¯ã¯py.testã®å®è¡ãã¨ã«ä¸åº¦ã ãåãã°ããã®ã§ãpytest_unconfigure
(called before test process is exited)ã使ããã¨ã«ãã¾ãã
ããã¸ã§ã¯ãã®ã«ã¼ãã«conftest.py
ãã¡ã¤ã«ã使ããDeprecationWarningããã§ãã¯ããã³ã¼ããæ¸ãã¾ãã
# d:\Sandbox\Django_pytest_sample\conftest.py import subprocess def pytest_unconfigure(config): print('subprocess') subprocess.run(['python', '-Wd', 'manage.py', 'check'], shell=True)
ã
å度py.testãå®è¡ãã¦ã¿ãã¨ããã
(env) d:\Sandbox\Django_pytest_sample>py.test ... ========================== 19 passed in 1.11 seconds ========================== d:\Sandbox\Django_pytest_sample\myproject\urls.py:21: RemovedInDjango20Warning: Specifying a namespace in django.conf.urls.include() without providing an app_name is deprecated. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead. url(r'mysite/', include('apps.myapp.urls', namespace='my')), System check identified no issues (0 silenced).
ãã¹ãã³ã¼ãã®ä»ã«DeprecationWarningã®ãã§ãã¯ãå®è¡ããã¾ããã
ã
DeprecationWarningã¸ã®å¯¾å¿
DeprecationWarningã1ä»¶åºã¦ããããã対å¿ãã¦ã¿ã¾ãã
ããã¥ã¡ã³ããèªãã¨ãincludeã§ã®namespaceã®æå®æ¹æ³ã夿´ã¨ãªãããã§ããã
django.conf.urls utility functions | Django documentation | Django
URL dispatcher | Django documentation | Django
ã
ãã®ãããããã¸ã§ã¯ãã®urls.pyã以ä¸ã®ããã«ä¿®æ£ãã¾ãã
urlpatterns = [ url(r'^admin/', admin.site.urls), # DeprecationWarning # url(r'mysite/', include('apps.myapp.urls', namespace="my")), # OK url(r'mysite/', include(('apps.myapp.urls', 'my'),)), ]
ã
åå®è¡ãã¦ã¿ã¾ãã
(env) d:\Sandbox\Django_pytest_sample>py.test ============================= test session starts ============================= platform win32 -- Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 django settings: myproject.settings (from ini file) rootdir: d:\Sandbox\Django_pytest_sample, inifile: pytest.ini plugins: django-2.9.1 collected 19 items apps\myapp\tests\test_model_forms.py ... apps\myapp\tests\test_models.py ....... apps\myapp\tests\test_myapp.py .. apps\myapp\tests\test_urls.py ... apps\myapp\tests\test_views.py .... ========================== 19 passed in 1.05 seconds ========================== System check identified no issues (0 silenced).
DeprecationWarningãæ¶ãã¦ãã¾ããã
ã
ã½ã¼ã¹ã³ã¼ã
GitHubã«ä¸ãã¾ããã
thinkAmi-sandbox/Django_pytest_sample
*1:django/edit.py at e429c5186ceed81c4627165518e0c70c58e69595 · django/django
*2:ãªã³ã¯å ã¯get()ã®èª¬æã§ãããä¸èº«ã¯post()ã¨åããªã®ã§ããã詳ããæ¹ã¸ã¨ãªã³ã¯ãã¦ããã¾ã