标签: pytest-django

如何使用pytest在Django中测试重定向?

我已经知道可以实现从继承的类SimpleTestCase,并且可以通过以下方法测试重定向:

SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, host=None, msg_prefix='', fetch_redirect_response=True)
Run Code Online (Sandbox Code Playgroud)

但是,我想知道使用pytest检查重定向的方式是什么:

@pytest.mark.django_db
def test_redirection_to_home_when_group_does_not_exist(create_social_user):
    """Some docstring defining what the test is checking."""
    c = Client()
    c.login(username='TEST_USERNAME', password='TEST_PASSWORD')
    response = c.get(reverse('pledges:home_group',
                             kwargs={'group_id': 100}),
                     follow=True)
    SimpleTestCase.assertRedirects(response, reverse('pledges:home'))
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

  SimpleTestCase.assertRedirects(response, reverse('pledges:home'))
Run Code Online (Sandbox Code Playgroud)

E TypeError:assertRedirects()缺少1个必需的位置参数:'expected_url'

有什么方法可以使用pytest来验证与Django的重定向?还是我应该使用继承自的类SimpleTestCase

python django pytest pytest-django

4
推荐指数
2
解决办法
635
查看次数

Pytest 使用 django_db 和 rest 框架

我正在尝试进行一个简单的测试,以django_db使用django rest framework.

基本测试设置:

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

@pytest.mark.django_db
def test_airport_list_real():
    client = APIClient()
    response = client.get(reverse('query_flight:airports-list'))
    assert response.status_code == 200
    assert len(response.json()) > 0
Run Code Online (Sandbox Code Playgroud)

运行这个测试我得到:

___________________________ test_airport_list_real ____________________________

    @pytest.mark.django_db
    def test_airport_list_real():
        client = APIClient()
        response = client.get(reverse('query_flight:airports-list'))
        assert response.status_code == 200
>       assert len(response.json()) > 0
E       assert 0 > 0
E        +  where 0 = len([])
E        +    where [] = functools.partial(<bound method Client._parse_json …
Run Code Online (Sandbox Code Playgroud)

django pytest django-rest-framework pytest-django

4
推荐指数
1
解决办法
2956
查看次数

在 DRF 测试中使用 pytest 参数化

现在我有这样的代码:

from rest_framework.test import APITestCase

class MyTestClass(ApiTestCase):
    fixtures = ['some_fixtures.json', ]

    @pytest.mark.parametrize('field, reverse_ordering', [
        ('id', False),
        ('id', True)])
    def test_ordering(self, field, reverse_ordering):
        # some test function
Run Code Online (Sandbox Code Playgroud)

每次因该错误而失败时:

======================================================================
ERROR: test_ordering (my_module.tests.MyTestClass)
----------------------------------------------------------------------
TypeError: test_ordering() missing 2 required positional arguments: 'field' and 'reverse_ordering'
Run Code Online (Sandbox Code Playgroud)

如何@pytest.mark.parametrizeAPITestCaseDRF 测试类中使用装饰器进行测试?
也许有另一种方法来参数化测试(但不是循环)?

django django-testing pytest django-rest-framework pytest-django

4
推荐指数
2
解决办法
2259
查看次数

为什么 pytest-django 找不到 manage.py?

我有一个这样的项目结构:

setup.cfg
integration_tests/
  |----tests.py
src/
  |----manage.py
  |----my_django_app/
Run Code Online (Sandbox Code Playgroud)

还有一个 setup.cfg :

[tool:pytest]
addopts=--tb=short --strict -ra
DJANGO_SETTINGS_MODULE = my_django_app.settings
env = 
    APP_ENV=testing
    USE_SQLITE_DB=True
Run Code Online (Sandbox Code Playgroud)

但是当我导航到该目录结构的顶部并运行时pytest,我得到以下信息:

“pytest-django 找不到 Django 项目(找不到 manage.py 文件)。你必须明确地将你的 Django 项目添加到 Python 路径中才能被选中。”

如果我转而导航到/src/并运行pytest,则测试运行没有问题,但很明显,因为我在一个级别上没有运行任何集成测试。

根据文档,它似乎应该从您运行的位置向下钻取pytest以尝试查找manage.pyhttps : //pytest-django.readthedocs.io/en/latest/managing_python_path.html#automatic-looking-for-of- Django 项目

如果不是这种情况,那么是否有某种方法可以在 setup.cfg 中配置设置以添加src/到 PYTHONPATH?文档src/中使用 pip 以可编辑模式安装的建议在我们的环境中并不能真正站得住脚。

python django pytest pytest-django

4
推荐指数
1
解决办法
980
查看次数

pytest-django:这是使用参数测试视图的正确方法吗?

假设我正在Django应用程序中测试RSS feed视图,这是我应该怎么做的吗?

def test_some_view(...):
    ...
    requested_url = reverse("personal_feed", args=[some_profile.auth_token])
    resp = client.get(requested_url, follow=True)
    ...
    assert dummy_object.title in str(resp.content)
Run Code Online (Sandbox Code Playgroud)
  1. reverse-ing然后将其传递client.get()给正确的测试方法?我认为这比以前简单地.get()设置URL 更干燥,而且更适合未来使用。

  2. 我应该断言这dummy_object就是这种回应吗?

  3. 我在这里使用str响应对象的表示形式进行测试。与使用时相比,selenium什么时候是个好习惯?我知道,例如,可以更轻松地验证obj或属性(如dummy_object.title)是否封装在H1标签中。在另一方面,如果我不关心如何与obj表示,它的速度更快做像上面。

python django django-testing pytest pytest-django

4
推荐指数
1
解决办法
382
查看次数

pytest 和 Django 事务数据库

我使用生产数据库进行测试(实际上是docker中的测试数据库)。问题是:如何在针对该数据库的事务中运行测试。@pytest.mark.django_db(transaction=True)我需要与生产数据库相同的行为。

当前设置:

测试.py

@pytest.fixture(scope='session')
def django_db_setup():
    """Avoid creating/setting up the test database"""
    pass


@pytest.fixture
def db(request, django_db_setup, django_db_blocker):
    django_db_blocker.unblock()


@pytest.fixture
def myfixture(db):
    ...
    return SomeObject
Run Code Online (Sandbox Code Playgroud)

测试示例.py

def test_something(db, myfixture):
    assert ...
Run Code Online (Sandbox Code Playgroud)

django pytest pytest-django

4
推荐指数
1
解决办法
8473
查看次数

使用 WebSocketCommunicator 在 Django Channels v2 测试中进行身份验证

在为我的聊天消费者编写测试的过程中,我遇到了无法使用 WebSocketCommunicator 在测试中进行身份验证的问题。我有自定义 JwtTokenAuthMiddleware,它通过在请求查询中使用令牌来实现套接字中的身份验证,因为据我所知,使用授权标头进行适当的身份验证尚不可能。你们能给我建议或者向我提供我在网上找不到的示例代码吗?顺便说一句,我的聊天工作没有问题。另外测试应该完全没问题,我从官方文档 Django Channels 2.x 测试中获取了指南。

--JwtTokenAuthMiddlewate--

class JwtTokenAuthMiddleware:
    def __init__(self, inner):
        self.inner = inner

    def __call__(self, scope):
        close_old_connections()
        try:
            raw_token = scope['query_string'].decode().split('=')[1]
            auth = JWTAuthentication()
            validated_token = auth.get_validated_token(raw_token)
            user = auth.get_user(validated_token)
            scope['user'] = user
        except (IndexError, InvalidToken, AuthenticationFailed):
            scope['user'] = AnonymousUser()
        return self.inner(scope)


JwtTokenAuthMiddlewareStack = lambda inner: JwtTokenAuthMiddleware(AuthMiddlewareStack(inner))
Run Code Online (Sandbox Code Playgroud)

--测试示例--

@pytest.mark.django_db(transaction=True)
@pytest.mark.asyncio
async def test_trainer_auth_success():
    room = await database_sync_to_async(RoomFactory.create)()
    trainer = room.trainer
    trainer_token = await sync_to_async(get_token_for_user)(trainer.user)
    room_url = f'ws/room/{room.id}/'

    trainer_communicator = WebsocketCommunicator(application, f'{room_url}?t={trainer_token}')
    connected, _ = await trainer_communicator.connect() …
Run Code Online (Sandbox Code Playgroud)

django python-3.x pytest-django django-channels pytest-asyncio

4
推荐指数
1
解决办法
1736
查看次数

获取测试套件中每个测试的 SQL 查询计数概览

我有一个大型 Django 应用程序,其中包含大量需要 SQL 查询优化的测试。

我正在使用 pytest-django 来运行我的测试。

我不想单独添加assertNumQueriesdjango-assert-num-queries针对每个测试,而是生成有关所有测试中的每个测试触发了多少 SQL 查询的概述,以了解哪些代码需要最优化,如下所示:

test                         | number of queries
------------------------------------------------
test_a.py::test_my_function1 |  5
test_a.py::test_my_function3 |  2
test_a.py::test_my_function5 |  7
Run Code Online (Sandbox Code Playgroud)

是否可以在 conftest.py 中配置一个 pytest 钩子,它计算每个 (DB) 测试的 SQL 查询数量并在结果中显示它们 - 无需修改我的测试源(如添加装饰器)?

我天真的方法是使用这些钩子,并以某种方式在每次测试前后访问数据库连接:

def pytest_runtest_call(item):
    pass

def pytest_runtest_teardown(item, nextitem):
    return True

Run Code Online (Sandbox Code Playgroud)

python django pytest pytest-django

4
推荐指数
1
解决办法
567
查看次数

如何使用 pytest-django 测试 Django 查询集是否相等

断言两个查询集相等的最佳/最易读的方法是什么?我想出了一些解决方案:

# option 1
assert sorted(qs1.values_list("pk", flat=True)) == sorted(qs2.values_list("pk", flat=True))

# option 2 (need to assert length first because set might remove duplicates)
assert len(qs1) == len(qs2)
assert set(qs1) == set(qs2)
Run Code Online (Sandbox Code Playgroud)

我知道 Django 有一个方法django.test.TransactionTestCase.assertQuerysetEqual。pytest-django 有类似的东西吗?我在文档中没有看到它。

python django django-testing pytest-django

4
推荐指数
1
解决办法
1150
查看次数

如何在 pytest-django 中模拟 django 设置属性

当使用 Django 默认单元测试时,修补设置属性很简单(@override_settings例如使用装饰器)。

我想覆盖测试方法设置的几个属性。当我使用 pytest-django 时,如何才能实现这一目标?

django pytest pytest-django

3
推荐指数
1
解决办法
1682
查看次数