Flask 单元测试

2016-09-12 Monday     webserver

在 Python 中,有各种各样的测试框架,包括了 unittest、testtools、subunit、coverage、testrepository、nose、mox、mock、fixtures、discover 等等。而 unittest 是 Python 标准库中的一个模块,是其它框架和工具的基础。

unittest 简介

其时最好的资料是参考官方文档 unittest — Unit testing framework,其中包含了一些常见的概念。

在开始就是介绍四个重要的概念:test fixture、test case、test suite、test runner。

一个 test case 实例就是一个测试用例,包括了一套完整的测试流程:测试前准备环境的搭建 (setUp),执行测试代码 (run),以及测试后环境的还原 (tearDown)。多个测试用例组合到一起,就是 test suite;当然 test suite 可能会是 test suite 以及 test case 的组合。

接下来直接看一个示例,用来测试 random 库中的部分函数。

# -*- coding:utf-8 -*-
import random
import unittest

class TestSequenceFunctions(unittest.TestCase):
    def setUp(self):          # 初始化设置
        self.seq = range(10)
    def tearDown(self):       # 测试完成后的清理
        pass
    def test_shuffle(self):   # 将序列随机化,需要保证没有丢失元素
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))
        # should raise an exception for an immutable sequence
        self.assertRaises(TypeError, random.shuffle, (1,2,3))
    def test_choice(self):    # 随机选择其中一个元素
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)
    def test_sample(self):    # 选择n个随机且独立的元素
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

if __name__ == '__main__':
    unittest.main()

flask 单元测试

简单测试

假设当我们访问应用的根 URL 时应该显示 “Helle World\n”,新增了一个新的测试用例来测试:

注意,我们的调试函数都是以 test 开头的,也就是 unittest 定义的标准,用于测试的函数并运行它们。

# -*- coding:utf-8 -*-
import os
import foobar
import unittest

class FoobarTestCase(unittest.TestCase):
    def setUp(self):
        foobar.app.config['TESTING'] = True
        self.app = foobar.app.test_client()
        foobar.init()             # 调用应用中的命令
    def tearDown(self):
        pass
    def test_check_entry(self):
        rv = self.app.get('/')
        assert '401 Unauthorized' in rv.data

if __name__ == '__main__':
    unittest.main()

在如上的测试用例中,通过使用 self.app.get 向应用的指定 URL 发送一个 HTTP GET 请求,该函数调用会返回一个 Flask.response_class 对象;然后,可以使用 data 属性来检查应用的返回值。

登录和注销

很多应用的功能必须登录以后才能使用,因此必须测试应用的登录和注销,因为登录和注销后会重定向到别的页面,因此必须告诉客户端使用 follow_redirects 追踪重定向。

def login(self, username, password):
    return self.app.post('/login', data=dict(
        username=username,
        password=password
    ), follow_redirects=True)
def logout(self):
    return self.app.get('/logout', follow_redirects=True)

def test_login_logout(self):
    rv = self.login('admin', 'default')
    assert 'You were logged in' in rv.data
    rv = self.logout()
    assert 'You were logged out' in rv.data
    rv = self.login('adminx', 'default')
    assert 'You should log in' in rv.data

使用 pytest

实际上 Python 中使用比较多的是 nose 以及 pytest,据说 nose 要更加好用一些,不过在 flask 示例中使用的是 pytest,为了便于参考,我们还是直接使用 pytest 。

参考

在源码的 examples 中,有个 minitwit 示例,使用 pytest 进行测试,可以参考。



如果喜欢这里的文章,而且又不差钱的话,欢迎打赏个早餐 ^_^


About This Blog

Recent Posts

Categories

Related Links

  • RTEMS
    RTEMS
  • GNU
  • Linux Kernel
  • Arduino

Search


This Site was built by Jin Yang, generated with Jekyll, and hosted on GitHub Pages
©2013-2018 – Jin Yang