结论:在使用pytest-django测试期间,我的Django连接对象没有看到第二个数据库的表关系.
概述: 我有一个问题,我的Django连接对象似乎得到错误的数据库信息.我偶然发现了这个问题,当我在"客户" DB查询在桌子上,Django的告诉我的关系不存在.使用settings.py数据库部分设置如下:
DATABASES = {
'default': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.postgres',
'USER': 'postgres_1',
'PASSWORD': 'superS3cret'
},
'customers': {
'NAME': 'customer_data',
'ENGINE': 'django.db.backends.postgres',
'USER': 'postgres_1',
'PASSWORD': 'superS3cret'
}
}
Run Code Online (Sandbox Code Playgroud)
当我在目录上运行'pytest'时,下面的两个游标都从'default'数据库中获取信息:
sql = """SELECT table_name FROM information_schema.tables WHERE table_nameschema='public'"""
default = connections["default"].cursor()
default.execute(sql)
raw_data = default.fetchall()
sql_columns = [col[0] for col in default.description]
df1 = pd.DataFrame(raw_data, columns=sql_columns)
customers = connections["customers"].cursor()
customers.execute(sql)
raw_data = customers.fetchall()
sql_columns = [col[0] for col in customers.description]
df2 = pd.DataFrame(raw_data, columns=sql_columns)
Run Code Online (Sandbox Code Playgroud)
df1和df2的结果完全相同:只有'default'数据库中的表名.
使用pytest-django并使用第二个Postgres数据库会发生这种情况,但有时只会发生. …
我想为 Django REST Framework 应用程序上的视图编写单元测试。测试应该使用 PUT 上传文件,本质上相当于
http -a malkaouri PUT http://localhost:8000/data-packages/upload/ka @tmp/hello.py
到目前为止我写的代码是
factory = APIRequestFactory()
request = factory.put( '/data-packages/upload/ka',
data,
content_type='application/octet-stream',
content_disposition="attachment; filename=data.dump")
force_authenticate(request, user)
view = PackageView.as_view()
response = view(request, "k.py")
Run Code Online (Sandbox Code Playgroud)
显然,它不会上传文件。运行测试时的具体错误是400:
{u'detail': u'缺少文件名。请求应包含一个带有文件名参数的 Content-Disposition 标头。'}
值得注意的是,我使用请求工厂来测试视图而不是完整的客户端。这就是使这个问题中的解决方案对我不起作用的原因。
设置内容处置标头的正确方法是什么?
我的问题是一个波纹管。如果我尝试运行测试,则表明没有数据库权限,因此我必须添加该固定装置。问题是我已将该固定装置添加到我拥有的任何可能方法中,但仍然没有。因此,我假设我不知道在何处添加此标记。
它不应该是我调用这些对象的创建类的方法:test_can_get_page_details?
如果我从将用户分配给那些属性中删除UserFactory,则测试有效。
[pytest]
DJANGO_SETTINGS_MODULE=core.settings_test
Run Code Online (Sandbox Code Playgroud)
import pytest
from bs4 import BeautifulSoup
import datetime
from django.core.urlresolvers import reverse
from interface.tests import factories
class TestPageDetail:
@pytest.fixture
def defaults(self, db):
page = factories.PageFactory()
url = page.get_absolute_url()
return {
'page': page,
'url': url
}
@pytest.mark.integration
def test_can_get_page_details(self, defaults, db, admin_client):
response = admin_client.get(defaults['url'])
assert 200 == response.status_code
Run Code Online (Sandbox Code Playgroud)
import pytest
@pytest.fixture
def initial_data(db):
from interface.management.commands.initial_data import Command as InitialData
InitialData().handle()
@pytest.fixture
def page_and_variable(db, initial_data):
from interface.tests.factories import PageFactory, VariableFactory
page …Run Code Online (Sandbox Code Playgroud) 我正在关注Vagrant (Ubuntu 18.04 / Python3.6.6) 中的python-django教程。运行pip3 install pytest-django配置pytest.ini文件后,运行pytest返回
Command 'pytest' not found, but can be installed with:
apt install python-pytest
Please ask your administrator.
Run Code Online (Sandbox Code Playgroud)
pip3 freeze 输出:
pytest==3.10.0
pytest-django==3.4.3
Run Code Online (Sandbox Code Playgroud)
安装还有其他东西吗?
我一直在尝试使用 @pytest.mark.parametrize 参数化我的测试,并且我有一个营销人员 @pytest.mark.test("1234"),我使用测试标记中的值将结果发布到 JIRA。请注意为每个 test_data 的标记指定的值都会发生变化。本质上,代码如下所示。
@pytest.mark.foo
@pytest.mark.parametrize(("n", "expected"),[
(1, 2),
(2, 3)])
def test_increment(n, expected):
assert n + 1 == expected
Run Code Online (Sandbox Code Playgroud)
我想做类似的事情
@pytest.mark.foo
@pytest.mark.parametrize(("n", "expected"), [
(1, 2,@pytest.mark.test("T1")),
(2, 3,@pytest.mark.test("T2"))
])
Run Code Online (Sandbox Code Playgroud)
考虑到标记的值预计会随着每次测试而变化,如何在使用参数化测试时添加标记?
在pytest文档中,它说您可以自定义assert失败时的输出消息。我想assert在测试返回错误状态代码的REST API方法时自定义消息:
def test_api_call(self, client):
response = client.get(reverse('api:my_api_call'))
assert response.status_code == 200
Run Code Online (Sandbox Code Playgroud)
所以我试图在其中放入一段代码 conftest.py
def pytest_assertrepr_compare(op, left, right):
if isinstance(left, rest_framework.response.Response):
return left.json()
Run Code Online (Sandbox Code Playgroud)
但是问题是left的实际值,response.status_code因此它是int而不是Response。但是,默认的输出消息抛出类似以下内容的消息:
E断言400 == 201 E +其中400 = .status_code
说错误400来自status_code对象的属性Response。
我的观点是,对要评估的变量有一种自省。因此,如何以一种舒适的方式自定义断言错误消息,以获得与上述示例类似的输出?
我是 pytest 的新手,我正在运行一个非常简单的测试来断言模型创建,但运行测试似乎需要大量时间。我大概有 10 件款式的上衣,没有一件是极其复杂的。
4.67 setup
0.69s call
0.09s teardown
Run Code Online (Sandbox Code Playgroud)
这是添加参数的情况(没有参数则超过 30 秒!):
pytest --nomigrations --reuse-db
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?如何减少这个设置时间?设置时间是否取决于模型数量或其他因素?我无法想象一旦应用程序变大,这将需要多长时间。欢迎任何建议。
我在 vs-code 中设置了 PyTest,但是即使从命令行运行 pytest 工作正常,也没有找到任何测试。
(我正在使用 MiniConda 和 Python 3.6.6 虚拟环境在 Win10 上开发 Django 应用程序。VS Code 已完全更新,我安装了 Python 和 Chrome 扩展程序调试器)
pytest.ini:
[pytest]
DJANGO_SETTINGS_MODULE = callsign.settings
python_files = tests.py test_*.py *_tests.py
Run Code Online (Sandbox Code Playgroud)
vs-code 工作区设置:
{
"folders": [
{
"path": "."
}
],
"settings": {
"python.pythonPath": "C:\\ProgramData\\Miniconda3\\envs\\callsign\\python.exe",
"python.unitTest.unittestEnabled": false,
"python.unitTest.nosetestsEnabled": false,
"python.unitTest.pyTestEnabled": true,
"python.unitTest.pyTestArgs": ["--rootdir=.\\callsign", "--verbose"]
}
}
Run Code Online (Sandbox Code Playgroud)
最后,VS 代码中 Python 测试日志的输出:
============================= test session starts =============================
platform win32 -- Python 3.6.6, pytest-4.1.1, py-1.7.0, pluggy-0.8.1
Django settings: callsign.settings (from ini file) …Run Code Online (Sandbox Code Playgroud) 我一直在尝试追踪一些并发代码中的一些错误,并想编写一个并行运行函数的测试。我使用 Django 和 postgres 作为我的数据库,并使用 pytest 和 pytest-django 进行测试。
为了运行我的函数,我使用ThreadPoolExecutor并简单地查询我的数据库并返回对象计数。这是 django shell 中的测试按预期工作:
>>> from concurrent.futures import *
>>> def count_accounts():
... return Account.objects.all().count()
...
>>> count_accounts()
2
>>> with ThreadPoolExecutor(max_workers=1) as e:
... future = e.submit(count_accounts)
...
>>> for f in as_completed([future]):
... print(f.result())
...
2
Run Code Online (Sandbox Code Playgroud)
但是,当我在 pytest 下运行此测试时,线程中的函数似乎返回空查询集:
class TestCountAccounts(TestCase):
def test_count_accounts(self):
def count_accounts():
return Account.objects.all().count()
initial_result = count_accounts() # 2
with ThreadPoolExecutor(max_workers=1) as e:
future = e.submit(count_accounts)
for f in as_completed([future]):
assert f.result() == initial_result …Run Code Online (Sandbox Code Playgroud) 如何在TestCase方法中使用 pytest 固定装置?类似问题的几个答案似乎暗示我的例子应该有效:
import pytest
from django.test import TestCase
from myapp.models import Category
pytestmark = pytest.mark.django_db
@pytest.fixture
def category():
return Category.objects.create()
class MyappTests(TestCase):
def test1(self, category):
assert isinstance(category, Category)
Run Code Online (Sandbox Code Playgroud)
但这总是会导致错误:
TypeError: test1() missing 1 required positional argument: 'category'
Run Code Online (Sandbox Code Playgroud)
我意识到我可以将这个简单的例子转换成一个函数,它会起作用。我更喜欢使用 django,TestCase因为它支持导入传统的“django fixture”文件,这是我的几个测试所需要的。将我的测试转换为函数需要重新实现这个逻辑,因为没有记录的方式使用 pytest(或 pytest-django)导入“django 固定装置”。
包版本:
Django==3.1.2
pytest==6.1.1
pytest-django==4.1.0
Run Code Online (Sandbox Code Playgroud) pytest-django ×10
pytest ×9
python ×9
django ×7
django-tests ×1
factory-boy ×1
python-3.x ×1
rest ×1
testing ×1
unit-testing ×1
vagrant ×1