pytest核心測試平臺落地初體驗

dongfanger發表於2021-02-03

測試平臺,有人說它雞肋,有人說它有用,有人說它輪子,眾說紛紜,不如從自身出發,考慮是否要做測試平臺:

  • 第1階段,用Python+requests寫介面自動化。
  • 第2階段,選擇unitttest或pytest,更熟悉pytest選了pytest。
  • 第3階段,快速搭建pytest專案腳手架,封裝tep測試工具。
  • 第4階段,通過Git管理測試指令碼,多分支合併程式碼。
  • 第5階段,去除本地環境同步麻煩,方便團隊共享指令碼。

需要有個測試平臺。

使用篇

環境變數

環境變數是字串鍵值對,全域性作用域。比如不同環境不同域名:

使用:env_vars.name

fixtures

fixtures即pytest的fixture,可以新增自定義函式,供測試用例使用。比如封裝登入介面返回token:

tep.fixture提供了url fixture,自動拼接環境變數env_vars.domain + uri

測試用例

在前端網頁寫程式碼,1條用例對應1個pytest的test_name.py檔案。比如呼叫login fixture登入:

本地編寫

PyCharm寫程式碼體驗更好,正確姿勢是從平臺下載包含環境變數和fixtures等專案結構程式碼,本地編寫用例,除錯,跑通後,貼上到平臺上共享和維護:

本地和平臺環境一致,省去前期搭建,關注tests用例。

擴充套件能力

用例是Python程式碼,理論上所有Python能寫出來的,平臺都能支援,比如HTTP、WebSocket、Protobuf等協議。

原理篇

pytest核心

  1. vue2-ace-editor作為前端程式碼編輯元件。
  2. 前端把程式碼通過HTTP請求傳給後端。
  3. 後端把程式碼存入MySQL資料庫。
  4. 執行用例,從資料庫取出程式碼,生成pytest檔案。
  5. Shell命令呼叫pytest -s test_name.py,執行測試。
  6. 後端把執行結果日誌返給前端展示。

之所以要折騰資料庫,是因為每次部署後docker容器裡面的檔案會被清掉,只能動態生成。

tep腳手架

測試平臺功能是從tep專案腳手架中抽取出來的:

  • fixture_env_vars.py做成了環境變數功能。
  • fixture_login.py等做成了fixtures功能。
  • tests做成了測試用例功能。

執行用例

整體流程如下:

pytest核心測試平臺落地初體驗

tep startproject project_name

執行用例時,判斷專案目錄是否存在,如果不存在就呼叫tep startproject project_name建立專案腳手架。

更新conf.yaml中env

把前端傳的當前執行環境更新到conf.yaml檔案中:

env: qa

動態生成或更新fixture_env_vars.py檔案

根據環境變數功能模組的資料,動態生成fixture_env_vars.py檔案:

#!/usr/bin/python
# encoding=utf-8

from tep.dao import mysql_engine
from tep.fixture import *


@pytest.fixture(scope="session")
def env_vars(config):
    class Clazz(TepVars):
        env = config["env"]

        """Variables define start"""
        # Environment and variables
        mapping = {
            "qa": {
                "domain": "https://qa.com",
            },
            "release": {
                "domain": "https://release.com",
            }
            # Add your environment and variables
        }
        # Define properties for auto display
        domain = mapping[env]["domain"]
        """Variables define end"""

    return Clazz()

動態生成或更新fixtures目錄下所有檔案

根據fixtures功能模組的資料,動態生成fixture_login.py等所有檔案:

from tep.client import request
from tep.fixture import *


def _jwt_headers(token):
    return {"Content-Type": "application/json", "authorization": f"Bearer {token}"}


@pytest.fixture(scope="session")
def login(url):
    # Code your login
    logger.info("Administrator login")
    response = request(
        "post",
        url=url("/api/users/login"),
        headers={"Content-Type": "application/json"},
        json={
            "username": "admin",
            "password": "123456",
        }
    )
    assert response.status_code < 400
    response_token = jmespath.search("token", response.json())

    class Clazz:
        token = response_token
        jwt_headers = _jwt_headers(response_token)

    return Clazz

conftest.py會自動查詢後import,tests用例直接使用。

動態生成或更新tests某個test_檔案

從資料庫拿到用例程式碼,動態生成test_檔案。

Shell執行pytest命令

從上一步拿到case_path,呼叫pytest -s case_path執行測試。

計劃後續新增suite和marker兩種批量執行用例方式。

小結

本文介紹了我第一次做的測試平臺的使用和原理,技術棧為Vue+Django+Django REST Framework+JWT+MySQL+pytest+Git+BitBucket+Drone+Nginx+Docker+K8S,已在公司落地,還未大規模產出,由於服務端有較多磁碟IO讀寫,大量使用後不知道效能如何,目前來看問題不大,需要持續觀察和優化。測試平臺底層是pytest,用到了tep,那就叫teprunner

參考資料:

https://github.com/dongfanger/tep

相關文章