web单元测试能够分为三类:html
测试对象较独立,无需依赖于cookie之类的上下文前端
依赖于上下文html5
web前端的测试。web
测试方式推荐:数据库
第一种类型只须要使用unittest的常规测试便可json
第三种类型可以使用selenium,可是编写selenium工做量比较大,且不够直观,且不够只管,建议使用其余方式或者人工测试flask
第二种类型,例如对于login_required类型的endpoint,可以使用app.test_client()返回测试客户端,同时附带上合适的数据。推荐使用flask-testing插件。同时,因为这类依赖比较常见,因此推荐将其独立成类。cookie
代码组织推荐:app
尽可能只再endpoint中编写参数解析与response封装工做,其余代码再独立成为一个逻辑函数函数
测试时,依赖于某些数据,除非测试数据的增删改,不然建议编写数据导入函数(后续写),能够减小工做量
Flask-testing是对unittest的一个封装,
使用以前须要先用create_app()
返回一个app便可使用,可使用client
属性模拟客户端访问,
例如:client.get('/', headers={'Cookie':cookie})
,
例如:client.post('/', data=parama, follow_redirects=True)
。
其余使用方式与unittest类似。
有一些测试实例须要登录后才能执行,为了方便登录管理,建议把登录相关独立成为一个Plugin类。调用该类便可。
传入unittest实例,经过unittest实例的get,post方法登录
先用get方法得到登录页,在html中提取csrf_token
再用post方法,将phone,passwod,csrf_token发送,follow_redirects=True跳转
在判断是否还停留再登录页
将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)