06:使用WebTest进行功能测试

使用 webtest .

背景

单元测试是测试驱动开发(TDD)的常用方法。然而,在Web应用程序中,网站的模板和整个设备是交付质量的重要组成部分。我们想要一个测试这些的方法。

WebTest 是一个执行功能测试的python包。通过WebTest,您可以编写测试来模拟针对wsgi应用程序的完整HTTP请求,然后测试响应中的信息。为了提高速度,WebTest跳过了实际HTTP服务器的设置/拆卸过程,提供了运行速度足以成为TDD一部分的测试。

目标

  • 编写一个测试来检查返回的HTML的内容。

步骤

  1. 首先,我们复制上一步的结果。

    cd ..; cp -r unit_testing functional_testing; cd functional_testing
    
  2. 添加 webtest 对我们项目的依赖 setup.py 作为一个 Setuptools “额外”:

     1from setuptools import setup
     2
     3# List of dependencies installed via `pip install -e .`
     4# by virtue of the Setuptools `install_requires` value below.
     5requires = [
     6    'pyramid',
     7    'waitress',
     8]
     9
    10# List of dependencies installed via `pip install -e ".[dev]"`
    11# by virtue of the Setuptools `extras_require` value in the Python
    12# dictionary below.
    13dev_requires = [
    14    'pyramid_debugtoolbar',
    15    'pytest',
    16    'webtest',
    17]
    18
    19setup(
    20    name='tutorial',
    21    install_requires=requires,
    22    extras_require={
    23        'dev': dev_requires,
    24    },
    25    entry_points={
    26        'paste.app_factory': [
    27            'main = tutorial:main'
    28        ],
    29    },
    30)
    
  3. 安装我们的项目及其新添加的依赖项。注意,我们使用了额外的说明符 [dev] 为开发安装测试需求,并用双引号将其和周期包围起来。

    $VENV/bin/pip install -e ".[dev]"
    
  4. 让我们扩展 functional_testing/tutorial/tests.py 包括功能测试:

     1import unittest
     2
     3from pyramid import testing
     4
     5
     6class TutorialViewTests(unittest.TestCase):
     7    def setUp(self):
     8        self.config = testing.setUp()
     9
    10    def tearDown(self):
    11        testing.tearDown()
    12
    13    def test_hello_world(self):
    14        from tutorial import hello_world
    15
    16        request = testing.DummyRequest()
    17        response = hello_world(request)
    18        self.assertEqual(response.status_code, 200)
    19
    20
    21class TutorialFunctionalTests(unittest.TestCase):
    22    def setUp(self):
    23        from tutorial import main
    24        app = main({})
    25        from webtest import TestApp
    26
    27        self.testapp = TestApp(app)
    28
    29    def test_hello_world(self):
    30        res = self.testapp.get('/', status=200)
    31        self.assertIn(b'<h1>Hello World!</h1>', res.body)
    

    确保此文件不可执行,或 pytest 可能不包括您的测试。

  5. 现在运行测试:

    $VENV/bin/pytest tutorial/tests.py -q
    ..
    2 passed in 0.25 seconds
    

分析

我们现在有了我们正在寻找的端到端测试。WebTest允许我们简单地扩展现有的 pytest -基于功能测试的方法,在相同的输出中报告。这些新测试不仅覆盖了我们的模板化,而且没有显著增加测试的执行时间。

额外credit

  1. 为什么我们的功能测试使用 b'' 是吗?