Flask-testing(一)—— 模擬登錄

web單元測試

web單元測試能夠分爲三類:html

  1. 測試對象較獨立,無需依賴於cookie之類的上下文前端

  2. 依賴於上下文html5

  3. web前端的測試。web

測試方式推薦:數據庫

  1. 第一種類型只須要使用unittest的常規測試便可json

  2. 第三種類型可以使用selenium,可是編寫selenium工做量比較大,且不夠直觀,且不夠只管,建議使用其餘方式或者人工測試flask

  3. 第二種類型,例如對於login_required類型的endpoint,可以使用app.test_client()返回測試客戶端,同時附帶上合適的數據。推薦使用flask-testing插件。同時,因爲這類依賴比較常見,因此推薦將其獨立成類。cookie

代碼組織推薦:app

  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)
相關文章
相關標籤/搜索