Django: Why does this test fail? - django

I an new to Django and to Test Driven Devolopment as well.
After working through the tutorials in the 1.11 official documentation
I am starting my first app: wos_2017_2
This test fails and I cannot figure out why:
import unittest
from django.test import TestCase
from django.test import Client
from .models import *
from .views import *
class SimpleTest(unittest.TestCase):
def test_index(self):
client = Client()
response = client.get('/')
self.assertEqual(response.status_code, 200)
FAIL: test_index (wos_2017_2.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/js/django/wos/wos_2017_2/tests.py", line 16, in test_index
self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200
This link in the browser works without a problem:
http://localhost:8000/wos_2017_2/
In the shell (run from the project root):
>>> from django.test import Client
>>> client = Client()
>>> response = client.get('/')
>>> response = client.get('wos_2017_2/index')
Not Found: /wos_2017_2index
>>> response = client.get('wos_2017_2/')
Not Found: /wos_2017_2
>>> response = client.get('/wos_2017_2/')
>>> response = client.get('/wos_2017_2/index/')
Not Found: /wos_2017_2/index/
>>> response = client.get('/wos_2017_2/')
>>> response.status_code
200
in wos_2017_1.urls.py:
from . import views
from django.conf.urls import url
urlpatterns = [
url(r'^$', views.index, name='index'),
]

client.get('/') is failing because you haven't defined a URL pattern for ^$ in your root url config (the one in the same directory as your settings.py).
You have included your urls with:
url(r'^wos_2017_2/', include('wos_2017_2.urls')),
and in that urls you have
url(r'^$', views.index, name='index'),
Therefore in your test you should use response = client.get('/wos_2017_2/')

Related

I don´t get to see my mistake. Why do I get this error? raise RequestsJSONDecodeError

.........................
.......................
......................
When I execute, python py_client/details.py, I get:
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char
0)
What´s going wrong here?
detail.py
import requests
endpoint = "http://localhost:8000/api/products/1"
get_response = requests.get(endpoint)
print(get_response.text)
this is urls.product
from django.urls import path
from . import views
urlpatterns = [
path('<int:pk>/', views.ProductDetailAPIview.as_view()),
path('', views.ProductCreateAPIview.as_view()),
]
I am getting error Expecting value: line 1 column 1 (char 0)
It doesn´t work in the browser either. It says: Page not found (404)
this is urls.cfehome
from django.contrib import admin
from django.urls import path
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include("new_api.urls")),
path('/api/products/', include("products.urls"))
]
this is my view in the app products
from rest_framework import generics
from .models import Product
from .serializers import Productserializers
class ProductDetailAPIview(generics.RetrieveAPIView):
queryset = Product.objects.all()
serializer_class = Productserializers
class ProductCreateAPIview(generics.CreateAPIView):
queryset = Product.objects.all()
serializer_class = Productserializers
Instead of print(get_response.text) try:
print(get_response.json())

pytest-django RuntimeError : Database access not allowed,

I'm testing my django application using pytest / pytest-django.
my urls.py file contains
from django.urls import include, path
from . import views
urlpatterns = [
path('', include('django.contrib.auth.urls')),
path('users/', views.users, name='users'),
path('add-user/', views.add_new_user, name='add_new_user'),
]
in my tests.py file, I have
import pytest
from django import urls
def test_users_url_resolves_to_users_view(client):
url = urls.reverse('users')
resp = client.get(url)
assert resp.status_code == 200
I get RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it. when i run this.
The error message says you should do either
#pytest.mark.django_db
def test_users_url_resolves_to_users_view(client):
url = urls.reverse('users')
resp = client.get(url)
assert resp.status_code == 200
or
def test_users_url_resolves_to_users_view(client, django_db):
url = urls.reverse('users')
resp = client.get(url)
assert resp.status_code == 200

can't use reverse url function in django

tests.py
from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from .models import User
class UserCreateAPIViewTestCase(APITestCase):
def setUp(self):
super().setUp()
self.url = reverse("admins")
def test_user_creating(self):
user_data = {}
response = self.client.post(self.url, user_data, format="json")
self.assertEqual(response.status_code,
status.HTTP_403_FORBIDDEN)
2.urls.py
from django.urls import path
from django.conf.urls import include
from rest_framework_nested.routers import SimpleRouter
from apps.users.views import (
CreateProviderViewSet,
LoginViewSet,
UserViewSet,
ProviderViewSet,
ClientViewSet,
LoginAsViewSet
)
app_name = 'users'
router = SimpleRouter(trailing_slash=False)
router.register("admins", UserViewSet, base_name='admins')
router.register("providers", ProviderViewSet, base_name='providers')
router.register("clients", ClientViewSet, base_name='clients')
router.register("login", LoginViewSet, base_name='auth')
router.register("login-as", LoginAsViewSet)
urlpatterns = [
path('', include(router.urls)),
]
when I run python .\manage.py test apps.users.tests
This error occurs
ERROR: test_user_creating (apps.users.tests.UserCreateAPIViewTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\vu.tran\Desktop\kona-server\apps\users\tests.py", line 19, in setUp
self.url = reverse("admins")
File "C:\Users\vu.tran\Desktop\kona-server\env\lib\site-packages\django\urls\base.py", line 90, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "C:\Users\vu.tran\Desktop\kona-server\env\lib\site-packages\django\urls\resolvers.py", line 668, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'admins' not found. 'admins' is not a valid view function or pattern name.
my structure folders like this my folders
I wonder why cannot get reverse("admins")
Do you have any idea?
According to the documentation, if you want to access the list view, the name for the url should be admins-list. The name of the argument for your register function may also be basename instead of base_name.

host-specific request breaks unrelated test cases

I have the following tests:
from django.test import TestCase
from django.core.urlresolvers import reverse
class TestA(TestCase):
def test_a(self):
reverse('view1')
class TestB(TestCase):
def test_b(self):
self.client.get('/view2/', HTTP_HOST='second.test.net')
class TestC(TestCase):
def test_c(self):
reverse('view1')
TestA and TestB run successfully, but TestC breaks with
..E
======================================================================
ERROR: test_c (dhtest.tests.test_view2.TestC)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/phihag/dhtest/dhtest/tests/test_view2.py", line 14, in test_c
reverse('view1')
File "/home/phihag/.local/share/virtualenvs/dhtest---IwXRQ3/lib/python3.6/site-packages/django/urls/base.py", line 91, in reverse
return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/home/phihag/.local/share/virtualenvs/dhtest---IwXRQ3/lib/python3.6/site-packages/django/urls/resolvers.py", line 497, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'view1' not found. 'view1' is not a valid view function or pattern name.
----------------------------------------------------------------------
Ran 3 tests in 0.006s
FAILED (errors=1)
But when I comment out TestB, TestC works! How do I fix this problem?
I'm using django-hosts with the following configuration:
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns(
'',
host(
r'second\.test\.net',
'dhtest.secondurls',
name='second'
),
host(
r'(\w+)',
'dhtest.urls',
name='default'
),
)
and fairly simple URL files:
# dhtest/urls.py
from django.conf.urls import url
from django.http import HttpResponse
urlpatterns = [
url(r'^view1/', lambda _: HttpResponse('This is view1'), name='view1'),
]
# dhtest/secondurls.py
from django.conf.urls import url
from django.http import HttpResponse
urlpatterns = [
url(r'^view2/', lambda _: HttpResponse('view2 on another host')),
]
For reference, here is the full project.
This is a bug in Django-hosts. In its response middleware, django-hosts clobbers the thread-wide urlconf to that of the request.
In production, that is not a problem, because Django resets the urlconf to the default for every request, or the request-specific one.
But during the tests, after TestB there are no more requests coming, and reverse (and a bunch of other URL-related functions) are using the urlconf for a different host.
To work around this, restore the urlconf after any requests to specific hosts, like this:
class TestB(TestCase):
def test_b(self):
self.client.get('/view2/', HTTP_HOST='second.test.net')
def tearDown(self):
from django.urls.base import set_urlconf
set_urlconf(None)

Simple Tests in Django failed

I'm trying to do simple tests in Django (v. 2.0.5). Since I can not see why I'm getting the '404 != 200' error, I post all relevant data.
test.py
from django.urls import resolve, reverse
from django.test import TestCase
from .views import home, board_topics
from .models import Board
class HomeTests(TestCase):
def test_home_view_status_code(self):
url = reverse('home')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_home_url_resolves_home_view(self):
view = resolve('/home/')
self.assertEqual(view.func, home)
class BoardTopicsTests(TestCase):
def setUp(self):
Board.objects.create(name='Django', description='Django discussion board')
def test_board_topics_view_success_status_code(self):
url = reverse('board_topics', kwargs={'pk': 1})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_board_topics_view_not_found_status_code(self):
url = reverse('board_topics', kwargs={'pk': 99})
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_board_topics_url_resolves_board_topics_view(self):
view = resolve('/boards/1/')
self.assertEqual(view.func, board_topics)
urls.py
from django.contrib import admin
from django.urls import include, path
from boards import views
urlpatterns = [
path('boards/<int:pk>/', views.board_topics, name='board_topics'),
path('home/', views.home, name='home'),
path('admin/', admin.site.urls),
]
views.py
...
def board_topics(request, pk):
try:
board = Board.objects.get(pk=pk)
except Board.DoesNotExist:
raise Http404
return render(request, 'topics.html', {'board': board})
Traceback
FAIL: test_board_topics_view_success_status_code (boards.tests.BoardTopicsTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/.../boards/tests.py", line 25, in test_board_topics_view_success_status_code
self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200
I wonder why I'm getting this error because I can call the views and I also get a 404 error when I try to call a page that does not exist (except Board.DoesNotExist). Is there a way to make the tests different (easier)? Thanks in advance for help.
You could try to adjust your test to automatically pickup the ID of the created object.
class BoardTopicsTests(TestCase):
def setUp(self):
self.board = Board.objects.create(name='Django', description='Django discussion board')
def test_board_topics_view_success_status_code(self):
url = reverse('board_topics', kwargs={'pk': self.board.id})
Maybe the database is not properly cleared between the tests?
Use resolve('/') instead of resolve('/home/')
def test_home_url_resolves_home_view(self):
view = resolve('/')
self.assertEquals(view.func, home)