Python Django—在本地主机上进行单元测试,在主数据库中创建对象,但在方法后面的测试数据库中找不到它们
在django单元测试中遇到一些相当奇怪的行为。我从django.test.testcase继承了一个类,该类验证注册表单是否创建了person对象和user对象,它确实创建了person对象和user对象,但我可以在测试完成后在管理界面中查找并找到这些对象。这就是测试:Python Django—在本地主机上进行单元测试,在主数据库中创建对象,但在方法后面的测试数据库中找不到它们,python,django,Python,Django,在django单元测试中遇到一些相当奇怪的行为。我从django.test.testcase继承了一个类,该类验证注册表单是否创建了person对象和user对象,它确实创建了person对象和user对象,但我可以在测试完成后在管理界面中查找并找到这些对象。这就是测试: import unittest import time from django.test import TestCase from selenium import webdriver from selenium.webdriv
import unittest
import time
from django.test import TestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import User
from apps.persons.models import Person
class NewVisitorTest(TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.quit()
def test_can_sign_up_and_login(self):
# User goes to register url
self.browser.get('http://localhost:8000/register/')
# User can see that she has come to the right page on the website
self.assertIn('Register', self.browser.title)
# User can see that there is a sign up form
signup_form = self.browser.find_element_by_id('id_registration_form')
# User can enter text into the first name field
first_name_input = self.browser.find_element_by_id('id_first_name')
first_name_input.send_keys('Jim')
# User can enter text into the last name field
last_name_input = self.browser.find_element_by_id('id_last_name')
last_name_input.send_keys('bob')
# User can enter text into the username field
username_input = self.browser.find_element_by_id('id_username')
username_input.send_keys('jim_bob')
# User can enter text into the email field
email_input = self.browser.find_element_by_id('id_email')
email_input.send_keys('jim_bob@jimbob.com')
# User can enter text into the first password field
password_input = self.browser.find_element_by_id('id_password')
password_input.send_keys('kittensarecute')
# User can enter text into the second password field
password_1_input = self.browser.find_element_by_id('id_password1')
password_1_input.send_keys('kittensarecute')
# Submit form
signup_form.submit()
time.sleep(20)
persons = Person.objects.all()
print persons
self.assertEqual(len(persons), 1)
users = User.objects.all()
print users
self.assertEqual(len(users), 1)
# Deliberately fail
self.fail('Finish the test!')
if __name__ == '__main__':
unittest.main()
该代码在assertEqual(len(persons),1)上失败。我可以在浏览器中重现相同的行为,没有问题。每次运行测试时,我都必须删除它在主本地数据库中创建的用户,因此我假设它正在将对象保存在settings['databases']中定义的数据库中,但随后在方法中的测试数据库中查找它们。我在终端中看到,测试数据库是在每个测试开始时创建的,所以它肯定在那里,这看起来很混乱。任何帮助都将不胜感激
编辑:一切都在sqlite上
File ".../tests/tests.py", line 60, in test_can_sign_up_and_login
self.assertEqual(len(persons), 1)
AssertionError: 0 != 1
编辑2:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '/Users/me/github/stage/project/data/db.db', # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
}
}
我有一个文件夹,其中包含应用程序,因此要运行这些测试并运行:
python manage.py test tests
您应该使用LiveServerTestCase,这样django就可以运行自己的测试服务器,从而使用自己的测试数据库
您应该使用LiveServerTestCase,这样django就可以运行自己的测试服务器,从而使用自己的测试数据库
没错,django在测试中创建了一个测试数据库。从文档中: 需要数据库的测试(即模型测试)将不会使用 “真实”(生产)数据库。创建单独的空白数据库 为了测试。 这是正确的做法。单元测试应该彼此隔离,以避免肮脏的环境(以前的测试忘记删除它创建的记录/文件/对象,并且会影响其他测试的结果)
你正在做的事叫做。您正在测试web应用程序表单是否在一个测试中提交、验证、保存等。因为这样做意味着许多代码都在运行,所以不认为是单元测试。当您执行这些类型的测试时,您的断言也应该类似:
- 显示“表示感谢/欢迎”消息
- 转到“用户管理”页面并断言新用户在那里
- 检查他们是否可以记录它
- 等
- 将JSON转换为文件
- 作为XML
- 在本地数据库中
- 在云端某处
在您的情况下,您正在使用两种测试方法。Selenium(打开页面、填写页面、提交页面)正在测试应用程序的功能,但您的断言(数据是否保存到数据库)正在测试您如何存储数据(单元) 因此,我建议您更改您的断言以适应测试的其余部分。并将当前测试移到单元测试中:
def test_user_is_save(self):
addUser(...)
users = User.objects.all()
self.assertEqual(len(users), 1)
这将测试您的
addUser
方法是否正常工作(保存到数据库),这就是单元测试的内容。您当前的测试将测试,当您提交表单时,用户会看到正确的东西。没错,django会在您的测试中创建一个测试数据库。从文档中:
需要数据库的测试(即模型测试)将不会使用
“真实”(生产)数据库。创建单独的空白数据库
为了测试。
这是正确的做法。单元测试应该彼此隔离,以避免肮脏的环境(以前的测试忘记删除它创建的记录/文件/对象,并且会影响其他测试的结果)
你正在做的事叫做。您正在测试web应用程序表单是否在一个测试中提交、验证、保存等。因为这样做意味着许多代码都在运行,所以不认为是单元测试。当您执行这些类型的测试时,您的断言也应该类似:
- 显示“表示感谢/欢迎”消息
- 转到“用户管理”页面并断言新用户在那里
- 检查他们是否可以记录它
- 等
- 将JSON转换为文件
- 作为XML
- 在本地数据库中
- 在云端某处
在您的情况下,您正在使用两种测试方法。Selenium(打开页面、填写页面、提交页面)正在测试应用程序的功能,但您的断言(数据是否保存到数据库)正在测试您如何存储数据(单元) 因此,我建议您更改您的断言以适应测试的其余部分。并将当前测试移到单元测试中:
def test_user_is_save(self):
addUser(...)
users = User.objects.all()
self.assertEqual(len(users), 1)
这将测试您的
addUser
方法是否正常工作(保存到数据库),这就是单元测试的内容。您当前的测试将测试在您提交表单时,用户是否看到了正确的内容。您可以使用LiveServerTestCase