I use django.test.TestCase for my project testing, however altough I’ve read django topic documentation below part is ambigouse for me. below two method for writing LoginTest gets two types of errors:
from django.test import TestCase
class LoginTest(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
User.objects.create_user(username='my_test_user', password='123456')
@classmethod
def tearDownClass(cls):
super().tearDownClass()
def test_index(self):
response = self.client.get('/')
self.assertRedirects(response, "/accounts/login/?next=/")
def test_login(self):
response = self.client.post('/user/login/', {
'username': 'my_test_user',
'password': '123456'
})
self.assertEqual(response.status_code, 302)
for ebove code I get below MySQLdb.OperationalError:
$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified some issues:
WARNINGS:
config.Expert.full_name: (mysql.W003) MySQL may not allow unique CharFields to have a max_length > 255.
HINT: See: https://docs.djangoproject.com/en/4.2/ref/databases/#mysql-character-fields
System check identified 1 issue (0 silenced).
.E
======================================================================
ERROR: test_login (tests.test_routes.test_login.LoginTest.test_login)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1562, in execute_sql
cursor.execute(sql, params)
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 83, in _execute
self.db.validate_no_broken_transaction()
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\base\base.py", line 531, in validate_no_broken_transaction
raise TransactionManagementError(
django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\code\nasim project\nasim\tests\test_routes\test_login.py", line 21, in test_login
response = self.client.post('/user/login/', {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\test\client.py", line 948, in post
response = super().post(
^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\test\client.py", line 482, in post
return self.generic(
^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\test\client.py", line 609, in generic
return self.request(**r)
^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\test\client.py", line 886, in request
response = self.handler(environ)
^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\test\client.py", line 176, in __call__
response = self.get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\core\handlers\base.py", line 140, in get_response
response = self._middleware_chain(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\core\handlers\exception.py", line 57, in inner
response = response_for_exception(request, exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\core\handlers\exception.py", line 140, in response_for_exception
response = handle_uncaught_exception(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\core\handlers\exception.py", line 185, in handle_uncaught_exception
return callback(request)
^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\nasim\core\views.py", line 49, in handler500
response = render(request, "error/500.html", {})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\shortcuts.py", line 24, in render
content = loader.render_to_string(template_name, context, request, using=using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\template\loader.py", line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\template\base.py", line 173, in render
with context.bind_template(self):
File "C:\Users\Info\AppData\Local\Programs\Python\Python312\Lib\contextlib.py", line 137, in __enter__
return next(self.gen)
^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\template\context.py", line 254, in bind_template
updates.update(processor(self.request))
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\nasim\util\context.py", line 48, in template_context_processor
context['logo'] = Resource.objects.filter(name="logo").first()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\query.py", line 1057, in first
for obj in queryset[:1]:
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\query.py", line 398, in __iter__
self._fetch_all()
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\query.py", line 1881, in _fetch_all
self._result_cache = list(self._iterable_class(self))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\query.py", line 91, in __iter__
results = compiler.execute_sql(
^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1565, in execute_sql
cursor.close()
File "C:\code\nasim project\venv\Lib\site-packages\MySQLdb\cursors.py", line 103, in close
self._discard()
File "C:\code\nasim project\venv\Lib\site-packages\MySQLdb\cursors.py", line 95, in _discard
while con.next_result() == 0: # -1 means no more data.
^^^^^^^^^^^^^^^^^
MySQLdb.OperationalError: (2006, '')
----------------------------------------------------------------------
Ran 2 tests in 0.605s
however when I change the `setUpClass()` to `setUp()`
class LoginTest(TestCase):
def setUp(self):
User.objects.create_user(username='my_test_user', password='123456')
def test_index(self):
response = self.client.get('/')
self.assertRedirects(response, "/accounts/login/?next=/")
def test_login(self):
response = self.client.post('/user/login/', {
'username': 'my_test_user',
'password': '123456'
})
self.assertEqual(response.status_code, 302)
I get below TransactionManagementError
======================================================================
ERROR: test_login (tests.test_routes.test_login.LoginTest.test_login)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\code\nasim project\nasim\tests\test_routes\test_login.py", line 8, in setUp
User.objects.create_user(username='my_test_user', password='123456')
File "C:\code\nasim project\venv\Lib\site-packages\django\contrib\auth\models.py", line 161, in create_user
return self._create_user(username, email, password, **extra_fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\contrib\auth\models.py", line 155, in _create_user
user.save(using=self._db)
File "C:\code\nasim project\venv\Lib\site-packages\django\contrib\auth\base_user.py", line 76, in save
super().save(*args, **kwargs)
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\base.py", line 814, in save
self.save_base(
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\base.py", line 877, in save_base
updated = self._save_table(
^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\base.py", line 1020, in _save_table
results = self._do_insert(
^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\base.py", line 1061, in _do_insert
return manager._insert(
^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\query.py", line 1805, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\models\sql\compiler.py", line 1822, in execute_sql
cursor.execute(sql, params)
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\utils.py", line 83, in _execute
self.db.validate_no_broken_transaction()
File "C:\code\nasim project\venv\Lib\site-packages\django\db\backends\base\base.py", line 531, in validate_no_broken_transaction
raise TransactionManagementError(
django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
----------------------------------------------------------------------
Ran 2 tests in 1.314s
FAILED (errors=1)
Destroying test database for alias 'default'...
I know setUp()
method will run before each test_*
method but what is the root cause of raising TransactionalError? does test_* run parallel I know not!
also as I tested if this LoginTest class have a single test_* method everything is fine.
is there any article to explain the order and mechanism of running internal django.test.TestCase
function?