Flask-testing(一)—— 模拟登陆

web单元测试

web单元测试可以分为三类:

  1. 测试对象较独立,无需依赖于cookie之类的上下文

  2. 依赖于上下文

  3. web前端的测试。

测试方式推荐:

  1. 第一种类型只需要使用unittest的常规测试即可

  2. 第三种类型可使用selenium,但是编写selenium工作量比较大,且不够直观,且不够只管,建议使用其他方式或者人工测试

  3. 第二种类型,例如对于login_required类型的endpoint,可使用app.test_client()返回测试客户端,同时附带上合适的数据。推荐使用flask-testing插件。同时,由于这类依赖比较常见,所以推荐将其独立成类。

代码组织推荐:

  1. 尽量只再endpoint中编写参数解析与response封装工作,其他代码再独立成为一个逻辑函数

  2. 测试时,依赖于某些数据,除非测试数据的增删改,否则建议编写数据导入函数(后续写),可以减少工作量

flask-testing简介

Flask-testing是对unittest的一个封装,
使用之前需要先用create_app()返回一个app即可使用,可以使用client属性模拟客户端访问,
例如:client.get('/', headers={'Cookie':cookie})
例如:client.post('/', data=parama, follow_redirects=True)
其他使用方式与unittest相似。

登陆

有一些测试实例需要登陆后才能执行,为了方便登陆管理,建议把登陆相关独立成为一个Plugin类。调用该类即可。

  1. 传入unittest实例,通过unittest实例的get,post方法登陆

  2. 先用get方法获得登陆页,在html中提取csrf_token

  3. 再用post方法,将phone,passwod,csrf_token发送,follow_redirects=True跳转

  4. 在判断是否还停留再登陆页

  5. 将cookie提取出来,用于以后登陆携带访问

class LoginPlugin(object):
    def __init__(self, flask_unittest):
        self.unittest = flask_unittest
        self.cookie = None

    def create_app(self):
        www = create_www_app('testing')
        db.init_app(www)
        return www

    def login(self, phone='13800000008', password='123456'):
        # 获取csrf_token
        login_html = self.unittest.client.get(url_for('auth.login')).data
        login_bs = BeautifulSoup(login_html, 'html5lib')
        csrf_token = login_bs.find(id='csrf_token')['value']
        if not re.search('登陆', login_html):
            # 登陆页打不开
            return False

        # 访问数据库
        params = {'phone': phone, 'password': password, 'csrf_token': csrf_token}
        result = self.unittest.client.post(url_for('auth.login'), data=params, follow_redirects=True)
        self.cookie = result.headers['Set-Cookie']
        result_data = result.data

        # True为登陆成功,False未登陆失败
        return not re.search('登陆', result_data)

    def get_cookie(self):
        return self.cookie

    def logout(self):
        return self.unittest.client.post('/logout')

使用例子


    class CartTest(TestCase):
        is_login = None
    
        def create_app(self):
            self.login_plugin = LoginPlugin(self)
            return self.login_plugin.create_app()
    
        def setUp(self):
            self.login_plugin.login()
            self.cookie = self.login_plugin.get_cookie()
    
        def test_show_cart_json(self):
            json_info = self.client.get(url_for('order.show_cart_json'), \
                headers={'Cookie': self.cookie}).data  # order.show_cart_json'依赖于current_user.get_id()所以得先登陆
            result = json.loads(json_info)
            self.assertEqual(len(result['data']), 2)
    原文作者:hymanHu
    原文地址: https://segmentfault.com/a/1190000004285548
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞