unittest和pytest是Python的2個強大的測試框架,經常用來做UI自動化或介面自動化。unittest是PyCharm的預設整合工具,也是我們大多數人入門自動化的首選框架。pytest提供了更豐富的功能,相對的上手難度也要高一點。如果學了pytest後,想快速用pytest寫專案,用於工作實踐,那麼可以試試我寫的這款測試工具:tep
,try easy pytest。
tep簡介
在Google中輸入python tep
:
tep是一款測試工具,不是測試框架,它做的事情只是幫助你更輕鬆的使用pytest寫專案程式碼,主要功能如下:
- 專案腳手架
- pytest用例組織
- 輸出HTML測試報告
- 基於fixture管理環境變數
- 基於fixture共享公共函式
- 訪問MySQL資料庫
- 整合常用第三方包
- 登入介面示例程式碼
工具安裝
安裝
tep已經上傳到了PyPI(Python Package Index):
可以使用pip
命令安裝:
pip install tep
外網速度慢,pandas
可能安裝失敗,推薦用國內映象:
pip --default-timeout=6000 install -i https://pypi.tuna.tsinghua.edu.cn/simple tep
由於整合了第三方包,安裝可能會花幾分鐘,請耐心等待。
Python版本
3.6+
檢查
安裝完成後,檢查是否安裝成功:
tep -V
0.5.3
或者:
tep --version
0.5.3
升級
使用-U
引數:
pip install -U tep
或者指定版本:
pip install tep==0.5.3
快速建立專案
tep提供了腳手架,預置了專案結構和程式碼,開啟cmd,使用startproject
命令快速建立專案:
cd some_directory
tep startproject project_name
建立後的專案結果如下:
當前版本主要用來做介面自動化,建議把不同業務系統建成多個專案。
1個檔案2處修改完成登入請求
tep已經預置了登入相關程式碼,只需要開啟fixtures\fixture_admin.py
,修改2個地方的程式碼,就可以完成登入請求。
修改環境變數
編輯fixtures/fixture_admin.py
:
@pytest.fixture(scope="session")
def env_vars(config):
class Clazz:
def __init__(self):
env = config["env"]
self.mapping = {
"qa": {
"domain": "https://qa.com",
"mysql_engine": mysql_engine("127.0.0.1", # host
"2306", # port
"root", # username
"123456", # password
"test") # db_name
},
"release": {
"domain": "https://release.com",
"mysql_engine": mysql_engine("127.0.0.1",
"2306",
"root",
"123456",
"release")
}
# Add your env and variables
}
self.domain = self.mapping[env]["domain"]
self.mysql_engine = self.mapping[env]["mysql_engine"]
# Add properties
def add(self, env, key, value):
self.mapping[config["env"]][key] = value
return Clazz()
mapping
是個字典,預置了2個環境:qa
和release
,每個環境預置了2個變數:domain
和mysql_engine
。
domain
url = domain +uri
,例如https://qa.com/api/users/login/
的domain是``https://qa.com,uri是
/api/users/login/`。
首先把qa
環境的domain
值改為你的測試域名。
修改登入程式碼
繼續編輯fixtures/fixture_admin.py
:
def _jwt_headers(token):
return {"Content-Type": "application/json", "authorization": f"Bearer {token}"}
@pytest.fixture(scope="session")
def login():
# 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
在# Code your login
處開始修改程式碼,替換API路徑/api/users/login/
和請求引數json
。如果你的登入介面不會返回token,那麼修改jmespath.search("token", response.json())
為實際響應取值。
tep預置登入返回了2個值:
token
和jwt_headers
。
測試登入
開啟tests/login_test.py
:
from loguru import logger
def test_login(login):
logger.info(login.token)
執行後就會呼叫登入介面發起請求。
遇到問題無法解決請留言或加群。
編寫測試用例
用例組織
測試用例全部放在tests
目錄下:
每個.py
模組以test_
字首或_test
字尾命名,每個test
函式以test
字首命名。只要遵循這個規則,目錄層次不影響。示例:
建議每個
.py
模組只包含1個test
函式,也就是1條測試用例。
介面請求設計
每條測試用例可以包含單個或多個介面請求。tep預置了1個POST請求示例程式碼,開啟tests/post_test.py
:
import jmespath
from loguru import logger
from tep.client import request
def test_post(faker_ch, url, login):
# description
logger.info("test post")
# data
fake = faker_ch
# request
response = request(
"post",
url=url("/api/users"),
headers=login.jwt_headers,
json={
"name": fake.name()
}
)
# assert
assert response.status_code < 400
# extract
user_id = jmespath.search("id", response.json())
每個請求由5部分組成,從上往下分別是描述、資料、請求、斷言和提取。
借鑑了JMeter元件和引數化關聯的設計思想。
描述
描述這個請求是幹嘛的。
資料
初始化區域性變數,例如使用faker庫造測試資料。
請求
如果需要列印請求日誌,可以from tep.client import request
,tep.client.request
對requests.request
除了記錄日誌外,沒有做任何修改。
如果請求報錯了,那麼很可能是程式碼寫錯了。
也可以直接使用原生request
,from requests import request
。
不同請求方法的程式碼如下:
request("get", url="", headers={}, json={})
request("post", url="", headers={}, params={})
request("put", url="", headers={}, json={})
request("delete", url="", headers={})
# 上傳excel
request("post",
url="",
headers={},
files={
"file": (
file_name,
open(file_path, "rb"),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)
},
verify=False
)
更多用法參考
requests.request
。
斷言
斷言使用Python標準斷言assert 表示式
,表示式跟if
語句表示式一模一樣。
提取
推薦使用jmespath
提取JSON資料,也可以使用Python[]
中括號提取。
HTML測試報告
批量執行用例
單個測試用例,在PyCharm中執行就可以了。多個測試用例批量執行,需要開啟左下角的Terminal
,輸入命令來執行:
# 先進入tests目錄
cd tests
# 批量執行
pytest
只收集不執行
如果只想統計用例條數,不執行程式碼,那麼可以使用以下命令:
pytest --co
HTML測試報告
tep提供了--tep-reports
引數來生成allure測試報告:
pytest --tep-reports
報告檔案存放在根目錄的reports/
中:
右鍵index.html
選擇:
就會開啟瀏覽器顯示測試報告了:
預設allure報告右上角的
TREND
是無法顯示資料的,--tep-reports
修復了這個問題,根據history資料生成TREND
走勢圖。
自定義環境變數
靜態新增
編輯fixtures/fixture_admin.py
,在mapping
字典中# Add your env and variables
處新增環境變數,在# Add properties
處新增屬性,參考domain
和mysql_engine
。示例:
動態新增
使用add()
方法動態新增環境變數:
env_vars.add("my_var", 789)
使用環境變數
env_vars
返回了類物件例項,通過.
運算子來使用環境變數:
env_vars.domain
env_vars.mysql_engine
env_vars.my_var
不需要import,而是給test函式新增引數,如
def test(env_vars):
切換環境
在conf.yaml
檔案中配置:
env: qa
預設為qa
環境。
團隊共享公共函式
通過fixture技術,我們可以把重複程式碼提取出來,在團隊間進行復用。tep重度使用了這個技術,在fixtures
目錄中,除了預置的fixture_admin.py
,可以繼續新增團隊成員的fixture:
新新增的fixture_your_name.py
需要到根目錄的conftest.py
中註冊才能生效:
# Import fixtures
exec("from .fixtures.fixture_admin import *")
exec("from .fixtures.fixture_your_name import *")
conftest.py模組中建議全部定義成fixture,不對外提供function。
為了避免命名衝突和程式碼跟蹤,團隊成員的公共函式命名建議加上_yourname
字尾。
訪問MySQL資料庫
首先在fixtures\fixture_admin.py
中修改mysql_engine
:
"mysql_engine": mysql_engine("127.0.0.1", # host
"2306", # port
"root", # username
"123456", # password
"test") # db_name
依次填寫主機名、埠、使用者名稱、密碼、資料庫名。
接著使用pandas來訪問資料庫,tests\mysql_test.py
預置了示例程式碼:
from loguru import logger
def test_mysql(pd, env_vars):
logger.info(pd.read_sql("select 1 from dual", env_vars.mysql_engine))
返回的資料可以通過data["列名"]["行號"]
的方式讀取。
如果想在console中以表格方式顯示錶資料,可以使用tep.dao.print_db_table()
函式,如:
from loguru import logger
from tep.dao import print_db_table
def test_mysql(pd, env_vars):
data = pd.read_sql("select 1 from dual", env_vars.mysql_engine)
logger.info(print_db_table(data))
第三方包整合說明
tep使用了Poetry來管理包和依賴:
目前已整合:
# 造測試資料
faker = "^4.1.1"
# 提取JSON資料
jmespath = "^0.10.0"
# 遮蔽HTTPS警告
urllib3 = "^1.25.9"
# HTTP/HTTPS請求
requests = "^2.24.0"
# HTML測試報告
allure-pytest = "^2.8.16"
allure-python-commons = "^2.8.16"
# 列印日誌
loguru = "^0.5.1"
# 訪問資料庫
pandas = "^1.1.0"
# 配置檔案
pyyaml = "^5.3.1"
# 為pandas訪問資料庫提供engine
sqlalchemy = "^1.3.22"
# 把資料庫表列印成表格
texttable = "^1.6.3"
# 支援sqlalchemy使用
pymysql = "^0.10.1"
東方說
最早寫這個工具的想法是以專案工程方式使用pytest,並結合第三方包完成介面自動化落地。如果你也有類似的想法,那麼可以參考tep的做法。tep使用者手冊是針對於tep工具本身的使用說明,不包含pytest框架搭建和基本使用,如果想入門pytest並深度學習,可以閱讀我寫的pytest系列文章,共8篇。tep的最新版本是0.5.3
,還不夠穩定,也存在bug,我會堅持維護下去,既是實用工具,也是技術沉澱。對tep有任何建議或問題,歡迎公眾號後臺回覆“加群”討論哦:
參考資料: