I'm writing Django unit test for Login form. Below is my sample code.
from unittest import TestCase
from django.contrib.auth.models import User
class TestSuite(TestCase):
def setUp(self):
self.credentials = {
'username': 'testuser',
'password': 'secret'}
User.objects.create_user(**self.credentials)
def test_login(self):
# send login data
response = self.client.post('/accounts/login', self.credentials, follow=True)
# should be logged in now
self.assertTrue(response.context['user'].is_active)
But when I'm executing from my console it's throwing the below error.
Traceback
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_login (accounts.tests.test_form.TestSuite)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Django\webapplication\accounts\tests\test_form.py", line 15, in test_login
response = self.client.post('/accounts/login', self.credentials, follow=True)
AttributeError: 'TestSuite' object has no attribute 'client'
----------------------------------------------------------------------
Ran 1 test in 0.502s
The problem is that python unittest module has not client in it; You should use django.test.
Simply change your first line as:
from django.test import TestCase
Read more about different test classes available to use.
You need django.test TestCase, instead of unittest's.
Related
I am new to Django framework & I am trying write some tests for my apps in the project.Currently I have two apps hoardings & clients both have same basic CRUD features.For testing purpose I have created a test directory & it looks like this
clients
- tests
-__init__.py
- test_views.py
That's how I am maintaining my tests for both the apps.My test_views.py has following code,
from django.test import TestCase
from django.urls import reverse
from hoardings.models import State, City
from clients.models import Client
class ClientManagementTest(TestCase):
def setUp(self):
self.state = State.objects.create(desc='West Bengal')
self.city = City.objects.create(state=self.state, desc='Kolkata')
self.client = Client()
def test_client_creation_form_can_be_rendered(self):
response = self.client.get(reverse('clients:create'))
# Check that the response is 200 OK.
self.assertEqual(response.status_code, 200)
# check if csrf token is present
self.assertContains(response, 'csrfmiddlewaretoken')
# Check that the response contains a form.
self.assertContains(response, '<form')
# assert the context values
self.assertIn('url', response.context)
self.assertIn('heading', response.context)
self.assertIn('states', response.context)
self.assertIn('client_types', response.context)
As you can see in the setup method I am creating an object of Client which is used to send the request.But every time I run the tests I get following errors,
ERROR: test_client_creation_form_can_be_rendered
(tests.test_views.ClientManagementTest)
---------------------------------------------------------------------- Traceback (most recent call last): File
"/home/ropali/Development/PythonWorkspace/hms_venv/hms/clients/tests/test_views.py",
line 19, in test_client_creation_form_can_be_rendered response =
self.client.get(reverse('clients:create')) AttributeError: 'Client'
object has no attribute 'get'
As per my understanding It means that client object is not being created so it cannot find the get attribute & I get the similar error for the POST request as well.
But one thing is bugging me that I have similar test setup for the hoardings app it runs perfectly fine.
Can anyone please help me what I am doing wrong here.Let me know if you need other details.
I have a project where I am trying to build an api using flask and python with the following structure:
graph:
-app.py
-server.py
-apis:
-__init__.py
-users.py
-transaction_functions.py
-neo4j_ops.py
In the server.py file I am trying to add authentification to the endpoints of my api which are coded in the users.py file. My server.py file looks like this:
import json
from six.moves.urllib.request import urlopen
from functools import wraps
from flask import Flask, request, jsonify, _request_ctx_stack
from flask_cors import cross_origin
from jose import jwt
AUTH0_DOMAIN = 'mydomain.eu'
API_AUDIENCE = 'https://my_audience.com'
ALGORITHMS = ["RS256"]
APP = Flask(__name__)
# Error handler
class AuthError(Exception):
def __init__(self, error, status_code):
self.error = error
self.status_code = status_code
#APP.errorhandler(AuthError)
def handle_auth_error(ex):
#some code
# Format error response and append status code
def get_token_auth_header():
"""Obtains the Access Token from the Authorization Header
"""
# some code
return token
def requires_auth(f):
"""Determines if the Access Token is valid
"""
#wraps(f)
def decorated(*args, **kwargs):
#some code
return decorated
def requires_scope(required_scope):
"""Determines if the required scope is present in the Access Token
Args:
required_scope (str): The scope required to access the resource
"""
#some code
And I keep getting this error:
Traceback (most recent call last):
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 183, in init_app
app.record(self._deferred_blueprint_init)
AttributeError: 'Flask' object has no attribute 'record'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "app.py", line 16, in <module>
api.init_app(app)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 186, in init_app
self._init_app(app)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 204, in _init_app
self._register_view(app, resource, *urls, **kwargs)
File "C:\Python37\lib\site-packages\flask_restplus\api.py", line 282, in _register_view
resource_func = self.output(resource.as_view(endpoint, self, *resource_class_args,
AttributeError: 'function' object has no attribute 'as_view'
As you can see the result of this printstack is not really useful at all since none of these calls comes from any of my files.
The only file involved in that is app.py and it looks like this:
from flask import Flask
from flask_restplus import Api
from apis import api
import config
import os
app = Flask(__name__)
api.init_app(app)#traceback comes from here.
app.run(host='0.0.0.0', port=8080)
The apis/__init__.py file looks like this:
from flask_restplus import Api, fields
from .users import api as users
from flask import Flask
api = Api(
title='Graph Api',
version='0.2',
)
api.add_namespace(users)
Any idea of what the issue is?
If I import app (the flask instance) from app.py into server.py and use that flask instance created in app rather than creating a new whole flask instance in server.py somehow the error goes away, but the issue is that I would then create a circular call of dependencies, so I cant do that.
You already have an app
APP = Flask(__name__)
And your error handler at least is using that
Yet, you defined a second one
app = Flask(__name__)
And __name__ here is app (the name of the file), which is probably what's breaking things and why the server file isn't broken
The problem stopped existing as soon as I went back to the version of the code of before adding the server.py file, and then I added it again. I have no clue of what the issue was though as the code is actually the same.
Background:
I am trying to setup my first Selenium driven integration test for a Django app. I have developed the following simple code:
from django.test import LiveServerTestCase
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.common.keys import Keys
class DynamicFormsIntegrationTest(LiveServerTestCase):
#classmethod
def setUpClass(cls):
cls.selenium = WebDriver()
cls.selenium.implicitly_wait(3)
super(DynamicFormsIntegrationTest, cls).setUpClass()
#classmethod
def tearDownClass(cls):
super(DynamicFormsIntegrationTest, cls).tearDownClass()
cls.selenium.quit()
def test_basic(self):
""" Uses get to open application page """
self.selenium.get(self.live_server_url + '/woc/')
#Force Test Fail
self.fail("FAIL")
Now, when I run this test using the following command:
python manage.py test test2
I get the following output:
python manage.py test test2^JCreating test database for alias 'default'...
<QueryDict: {}>
F
======================================================================
FAIL: test_basic (test2.tests.test_forms.DynamicFormsIntegrationTest)
Adds a single set via Jquery/Javascript, Submits, and verifies it was rendered and added to Model.Sets
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/usr/path/to/app/test2/tests/test_forms.py", line 42, in test_basic
self.fail("FAIL")
AssertionError: FAIL
----------------------------------------------------------------------
Ran 1 test in 8.901s
FAILED (failures=1)
Destroying test database for alias 'default'...
And when I run through my regular setup:
python manage.py runserver
I get the following output upon page request:
python manage.py runserver
Validating models...
0 errors found
September 01, 2013 - 14:42:34
Django version 1.5.1, using settings 'app.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
<QueryDict: {}>
[01/Sep/2013 14:42:39] "GET /test2/ HTTP/1.1" 200 9372
As you can see, the web page is not recognized when running the test (& no "GET" request is actually made, as is correctly done in the dev environment request). I actually believe the "GET" failure is an just an indicator of the problem that the Application is not correctly set up by the LiveServerTestCase.
Question:
Why is the LiveServerTestCase not recognizing my page urls and how can I resolve the issue?
I do the following:
from google.appengine.ext import deferred
def send_message(client_id, message):
logging.info("sending message...")
class MyHandler(webapp.RequestHandler):
def get(self, field_name):
...
scUpdate = {
'val': value,
'name': field_name_converted
}
message = simplejson.dumps(scUpdate)
deferred.defer(send_message, client_id, message, _countdown=random.randrange(0, 5, 1))
and getting
PermanentTaskFailure: 'module' object has no attribute 'send_message'
What is wrong here?
Upd. looks like the problem is the same as described there - PermanentTaskFailure: 'module' object has no attribute 'Migrate' - but I don't understand how to fix that.
See https://developers.google.com/appengine/articles/deferred:
Limitations of the deferred library
You can't call a method in the request handler module.
The function that is called via deferred.defer must not be in the same
module like the request handler where deferred.defer is called.
I am writing a test for a function that downloads the data from an url with Twisted (I know about twisted.web.client.getPage, but this one adds some extra functionality). Either ways, I want to use nosetests since I am using it throughout the project and it doesn't look appropriate to use Twisted Trial only for this particular test.
So what I am trying to do is something like:
from nose.twistedtools import deferred
#deferred()
def test_download(self):
url = 'http://localhost:8000'
d = getPage(url)
def callback(data):
assert len(data) != 0
d.addCallback(callback)
return d
On localhost:8000 listens a test server. The issue is I always get twisted.internet.error.DNSLookupError
DNSLookupError: DNS lookup failed: address 'localhost:8000' not found: [Errno -5] No address associated with hostname.
Is there a way I can fix this? Does anyone actually uses nose.twistedtools?
Update: A more complete traceback
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/nose-0.11.2-py2.6.egg/nose/twistedtools.py", line 138, in errback
failure.raiseException()
File "/usr/local/lib/python2.6/dist-packages/Twisted-9.0.0-py2.6-linux-x86_64.egg/twisted/python/failure.py", line 326, in raiseException
raise self.type, self.value, self.tb
DNSLookupError: DNS lookup failed: address 'localhost:8000' not found: [Errno -5] No address associated with hostname.
Update 2
My bad, it seems in the implementation of getPage, I was doing something like:
obj = urlparse.urlparse(url)
netloc = obj.netloc
and passing netloc to the the factory when I should've passed netloc.split(':')[0]
Are you sure your getPage function is parsing the URL correctly? The error message seems to suggest that it is using the hostname and port together when doing the dns lookup.
You say your getPage is similar to twisted.web.client.getPage, but that works fine for me when I use it in this complete script:
#!/usr/bin/env python
from nose.twistedtools import deferred
from twisted.web import client
import nose
#deferred()
def test_download():
url = 'http://localhost:8000'
d = client.getPage(url)
def callback(data):
assert len(data) != 0
d.addCallback(callback)
return d
if __name__ == "__main__":
args = ['--verbosity=2', __file__]
nose.run(argv=args)
While running a simple http server in my home directory:
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
The nose test gives the following output:
.
----------------------------------------------------------------------
Ran 1 test in 0.019s
OK