”;
Writing test scripts which ensure that your code works correctly is considered as a good programming practice. Python ecosystem had a number of testing frameworks, including unittest which is bundled in the standard library. Pytest is a popular testing library. It is a preferred library for Pyramid projects.
We shall use the hello package that we developed earlier while demonstrating the use of PasteDeploy configuration.
First, ensure that the Pyramid environment has PyTest package installed.
pip3 install pytest
Open the setup.py file in hello package and modify it by adding the lines shown in bold.
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'' ], }, )
Here, Pytest is added as the project dependency whenever it is installed (or reinstalled) using following command −
pip3 install -e ".[dev]
Store the following Python code as testing.py in hello package.
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)
To run the tests, use following Pytest command. The output of the test is shown below −
Envhello>pytest tests.py ========================== test session starts ========================== platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0 rootdir: E:tp-pyramidhello collected 1 item tests.py. [100%] =========================== 1 passed in 1.12s ===========================
To check if the test fails, induce an error in the test function and run again.
(tp-pyramid) E:tp-pyramidhello>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
Although Unit tests are popularly used in test-driven development (TDD)approach, for web applications, WebTest is a Python package that does functional testing. We can simulate a full HTTP request against a WSGI application, then test the information in the response.
Example
Let us use the hello project that we had used in the earlier example. Open the setup.py and add WebTest as the project dependency.
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'' ], }, )
Reinstall the hello package and its new dependency for development mode.
Envhello>..scriptspip3 install -e ".[dev]"
Include a functional test in tests.py file
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
Finally run Pytest as per the following command −
Envhello>pytest tests.py ========================== test session starts ========================== platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0 rootdir: E:tp-pyramidhello collected 2 items tests.py .. [100%] =========================== 2 passed in 2.37s ===========================
Tests in Cookiecutter Project
The CookieCutter utility auto-generates the tests package containing functional tests and unit tests. We had earlier used Cookiecutter to build Pyramid project named testproj. In this project, we find tests folder.
Example
The test_functional py contains the following test functions −
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
The test_views.py defines following test functions to test the views −
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
These tests are run by the following command −
Envtestproj>Pytest ========================== test session starts ========================== platform win32 -- Python 3.10.1, pytest-7.1.2, pluggy-1.0.0 rootdir: Envtestproj, configfile: pytest.ini, testpaths: testproj, tests plugins: cov-3.0.0 collected 5 items teststest_functional.py .. [ 40%] teststest_views.py ... [100%] =============== 5 passed, 20 warnings in 6.66s ===============
”;