Python Pyramid 简明教程
Python Pyramid - Testing
编写测试脚本以确保代码正常工作被认为是一种良好的编程实践。Python 生态系统具有多个测试框架,包括包含在标准库中的 unittest 。 Pytest 是一个流行的测试库。它是 Pyramid 项目的首选库。
我们将使用我们之前在展示 PasteDeploy 配置使用方法时开发的 hello 包。
首先,确保 Pyramid 环境安装了 PyTest 包。
pip3 install pytest
打开 hello 包中的 setup.py 文件并通过添加以粗体显示的行对其进行修改。
from setuptools import setup
requires = [
'pyramid',
'waitress',
]
dev_requires = ['pytest',]
setup(
name='hello',
install_requires=requires,
extras_require={
'dev': dev_requires,
},
entry_points={
'paste.app_factory': [
'main = hello:main'
],
},
)
此处,只要使用以下命令安装(或重新安装),就会将 Pytest 添加为项目依赖项 −
pip3 install -e ".[dev]
将以下 Python 代码存储为 hello 包中的 testing.py。
import unittest
from pyramid import testing
class HelloTests(unittest.TestCase):
def test_hello_world(self):
from . import hello_world
request = testing.DummyRequest()
response = hello_world(request)
self.assertEqual(response.status_code, 200)
要运行测试,请使用以下 Pytest 命令。测试的输出如下所示 −
Env\hello>pytest tests.py
========================== test session starts ==========================
platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0
rootdir: E:\tp-pyramid\hello
collected 1 item
tests.py.
[100%]
=========================== 1 passed in 1.12s ===========================
要检查测试是否失败,请在测试函数中引发错误并重新运行。
(tp-pyramid) E:\tp-pyramid\hello>pytest tests.py
========================== test session starts ==========================
collected 1 item
tests.py F
[100%]
=============================== FAILURES ================================
______________________ HelloTests.test_hello_world ______________________
self = <hello.tests.HelloTests testMethod=test_hello_world>
def test_hello_world(self):
from . import hello_world
request = testing.DummyRequest()
response = hello_world(request)
> self.assertEqual(response.status_code, 404)
E AssertionError: 200 != 404
tests.py:13: AssertionError
======================== short test summary info ========================
FAILED tests.py::HelloTests::test_hello_world - AssertionError: 200 != 404
=========================== 1 failed in 1.53s ===========================
Functional Testing
尽管单元测试在测试驱动开发 (TDD) 方法中广为使用,但对于 Web 应用程序, WebTest 是一个执行功能测试的 Python 包。我们可以对 WSGI 应用程序模拟完整的 HTTP 请求,然后测试响应中的信息。
Example
让我们使用我们在前面示例中使用的 hello 项目。打开 setup.py 并将 WebTest 添加为项目依赖项。
from setuptools import setup
requires = [
'pyramid',
'waitress',
]
dev_requires = ['pytest','webtest',]
setup(
name='hello',
install_requires=requires,
extras_require={
'dev': dev_requires,
},
entry_points={
'paste.app_factory': [
'main = hello:main'
],
},
)
重新安装 hello 包及其新依赖项以进行开发模式。
Env\hello>..\scripts\pip3 install -e ".[dev]"
在 tests.py 文件中包含一个功能测试
import unittest
from pyramid import testing
class HelloTests(unittest.TestCase):
def test_hello_world(self):
from . import hello_world
request = testing.DummyRequest()
response = hello_world(request)
self.assertEqual(response.status_code, 200)
class HelloFunctionalTests(unittest.TestCase):
def setUp(self):
from . import main
app = main({})
from webtest import TestApp
self.testapp = TestApp(app)
def test_hello_world(self):
res = self.testapp.get('/', status=200)
self.assertIn(b'<h1>Hello World!</h1>', res.body)
Output
最后,按照以下命令运行 Pytest −
Env\hello>pytest tests.py
========================== test session starts ==========================
platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0
rootdir: E:\tp-pyramid\hello
collected 2 items
tests.py .. [100%]
=========================== 2 passed in 2.37s ===========================
Tests in Cookiecutter Project
CookieCutter 实用程序自动生成包含功能测试和单元测试的测试包。我们之前曾使用 Cookiecutter 构建名为 testproj 的 Pyramid 项目。在此项目中,我们找到 tests 文件夹。
Example
test_functional py 包含以下测试函数 −
from testproj import models
def test_my_view_success(testapp, dbsession):
model = models.MyModel(name='one', value=55)
dbsession.add(model)
dbsession.flush()
res = testapp.get('/', status=200)
assert res.body
def test_notfound(testapp):
res = testapp.get('/badurl', status=404)
assert res.status_code == 404
test_views.py 定义了以下测试函数来测试视图 −
from testproj import models
from testproj.views.default import my_view
from testproj.views.notfound import notfound_view
def test_my_view_failure(app_request):
info = my_view(app_request)
assert info.status_int == 500
def test_my_view_success(app_request, dbsession):
model = models.MyModel(name='one', value=55)
dbsession.add(model)
dbsession.flush()
info = my_view(app_request)
assert app_request.response.status_int == 200
assert info['one'].name == 'one'
assert info['project'] == 'testproj'
def test_notfound_view(app_request):
info = notfound_view(app_request)
assert app_request.response.status_int == 404
assert info == {}
Output
这些测试由以下命令运行 −
Env\testproj>Pytest
========================== test session starts ==========================
platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0
rootdir: Env\testproj, configfile: pytest.ini, testpaths: testproj, tests
plugins: cov-3.0.0
collected 5 items
tests\test_functional.py .. [ 40%]
tests\test_views.py ... [100%]
=============== 5 passed, 20 warnings in 6.66s ===============