这个周末基本上都在研究这玩意儿中度过了,虽然效率不高,英文文档看得晕头转向,但是好歹弄出来了 有个结果测试也通过了现在粗略总结一下有时间补上更多详细的例子。

 

首先使用py.test测试框架,可以做最简单的了解在它们官网上https://pytest.org/

flask现在有个很尴尬的地方,我在github上面clone的最新版的flask 0.11dev上面,关于example里面的flaskr easy_blog_application的测试已经转而使用py.test框架了,但是官网上的和仓库里的文档都还停留在使用自带库unittest框架测试。所以暂时处于一个没有文档参照的情况, 不过好消息是 有代码可以参照。

直接上代码

@pytest.fixture
def client(request):
    app.config['TESTING'] = True
    # 得到测试客户端
    client = app.test_client()

    def teardown():
        app.config['TESTING'] = False
    # 执行回收函数
    request.addfinalizer(teardown)

    return client

这里的decorator @pytest.fixture 是一个类似于unittest框架里面 setup()/teardown()一套的东西,他里面还有个参数scope 默认情况下scope是function也就是每个函数执行的时候都会执行被这个decorator包裹的函数 具体参照 http://pytest.org/latest/fixture.html#fixture 这个文档讲的非常清楚

 

然后这里就是申明一个fixture 叫client 这个client 会帮我打开对应需要测试的app.config['testing']=True 然后帮我得到测试客户端 也就是我的测试上下文。 然后返回这个测试上下文 最后将测试配置恢复原状。request.addfinalizer 在上面那个文档地址里面也有介绍到。大致做一个操作就是在操作函数执行结束之后 调用对应参数里面的函数进行收尾工作。

然后就是具体的test_case:

class TestOrder:
    # 最外层请求头
    _data = {
        'api_key': api_key,
        'version': '1',
        'time': str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
    }

    def test_order_get_success(self, client):
        url = '/order/get'
        value = {
            'tid': '20160104-165157704',
            # 'tid': '12031823'
        }
        self._data['param'] = simplejson.dumps(value)
        self._data['api_sign'] = make_sign(self._data)
        rv = client.post(url, data=self._data)
        assert simplejson.loads(rv.data)['success'] == True, '请求订单失败' # noqa

要特别注意 申明类也必须使用Test打头,不然py.test框架会找不到对应的测试对象,然后申明具体的test case 这里是test_order_get_success同理要使用test作为函数的开头,测试框架才能找到。然后这里传入测试客户端,也就是我们得到的测试上下文对象。 最后进行相应的操作就行了,然后调用断言操作对需要检查的项目进行检查。 返回的数据通通保存在 测试对象的.data里 也就是这里的rv.data。 这里只需要对rv.data里面返回值进行校验就可以达到单元测试的目的了。

流程大致就是这样。这样做的好处是,这样的测试可以放在项目对应的tests目录下,并且可以调用travis-ci这样的持续集成进行测试,无需手动测试。方便而且高效可靠。