首頁 > 軟體

Pytest+Request+Allure+Jenkins實現介面自動化

2022-06-30 14:00:58
  • 利用Pytest+Request+Allure+Jenkins實現介面自動化;
  • 實現一套指令碼多套環境執行;
  • 利用引數化資料驅動模式,實現介面與測試資料分離
  • 使用logger客製化實現自動化測試紀錄檔記錄

實現步驟:

框架結構:

1、介面自動化專案程式碼編寫(先在window實現)

1.1 專案准備

先在window安裝響應的環境依賴

  • 安裝python3.7(要保證pip能用,一般安裝python3.7會自動安裝pip)
  • 安裝pytest框架---- pip install pytest
  • 安裝request庫---- pip install request
  • 安裝openpyxl庫(測試資料儲存在excel中,需要依賴讀取excel的庫)---- pip install openpyxl
  • 安裝pycharm(編寫python指令碼工具)

注意:可能還需要一些依賴的東西,專案步驟裡會依據需要進行安裝

1.2 設計基於pytest的測試框架結構

在pycharm中開發構建專案結構

common:存放公共方法
config:存放環境設定資訊
lib:存放第三方庫
main:框架主入口
report:存放allure測試報告
test_case:存放測試用例
test_data:存放測試資料

1.3 實現介面公共請求傳送能力

從這一步開始正式編寫程式碼

封裝http請求的公共能力(封裝request庫,變成自己的公共處理能力),放到common目錄下。

# encoding: utf-8
 
import requests
import urllib3
# from urllib3.exceptions import InsecureRequestWarning
 
urllib3.disable_warnings()
# 加這句不會報錯(requests證書警告)
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
 
 
class HTTPRequests(object):
    def __init__(self, url):
        self.url = url
        self.req = requests.session()
        # 依據自己公司的請求頭預設值設定
        self.head = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko',
            'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, '
                      'application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, '
                      'application/msword, */*',
            'Accept-Language': 'zh-CN'}
 
    # 封裝自己的get請求,獲取資源
    def get(self, uri='', params='', data='', headers=None, cookies=None, verify=False):
        if headers is None:
            headers = self.head
        # print("請求頭是:{}".format(headers))
        url = self.url + uri
        response = self.req.get(url, params=params, data=data, headers=headers, cookies=cookies, verify=verify)
        return response
 
    # 封裝自己的post請求,獲取資源
    def post(self, uri='', params='', data='', headers=None, cookies=None, verify=False):
        if headers is None:
            headers = self.head
        url = self.url + uri
        response = self.req.post(url, params=params, data=data, headers=headers, cookies=cookies, verify=verify)
        return response
 
    # 封裝自己的put請求,獲取資源
    def put(self, uri='', params='', data='', headers=None, cookies=None, verify=False):
        if headers is None:
            headers = self.head
        url = self.url + uri
        response = self.req.put(url, params=params, data=data, headers=headers, cookies=cookies, verify=verify)
        return response
 
    # 封裝自己的delete請求,獲取資源
    def delete(self, uri='', params='', data='', headers=None, cookies=None, verify=False):
        if headers is None:
            headers = self.head
        url = self.url + uri
        response = self.req.delete(url, params=params, data=data, headers=headers, cookies=cookies, verify=verify)
        return response

1.4 抽離測試環境設定資訊

這個步驟的目的有三個

  • 為了設定三個不同環境(測試、開發、生產)的URL,每個環境介面測試的URL是不一樣的,設定這樣一個列舉類,方便後面的程式根據不同的環境,獲取不同環境的URL,裡面的URL依據自己公司的地址修改,放到config目錄
  • 獲取token需要登入,這裡可以設定一個全域性的賬號密碼,這個賬號密碼獲取的token可以給整個介面自動化使用
  • 設定獲取token的uri,這個uri三個環境的是一致的,登入的介面依據環境只是URL不同,URI還是一致的。

# encoding: utf-8
 
import enum
 
class URLConf(enum.Enum):
    """環境設定資訊"""
    url_mapping = {
        'dev': 'https://www.dev.com',
        'test': 'https://www.test.com',
        'prod': 'https://www.prod.com'
    }
 
    # token固定的使用者名稱密碼,固定用"/"分割使用者名稱和密碼
    email_user = {
        'dev': 'dev@qq.com',
        'test': 'zidonghua@qq.com/96e79218965eb72c92a549dd5a330112',
        'prod': 'prod@qq.com'
    }
 
    login_uri = r'/api/auth/login/account/v1'

1.5 建立conftest.py放置一些公共的fixture

1、pytest_addoption,設定了只允許輸入dev/test/prod三個引數,以區分測試、開發、生產三個環境
2、get_env的fixture,它的作用是你在命令列執行介面自動化時,可以輸入--env test將對應的環境資訊傳入進去
3、http的fixture,這裡依據--env test傳入的環境資訊,去列舉類裡獲取對應環境的URL,然後返回一個http的session,供測試案例使用
4、get_token_head,依據--env test傳入的環境資訊,呼叫獲取token方法,並將token放置到請求頭head裡返回(token一般放在請求頭裡,這裡依據自己公司的請求,返回對應的token資訊就可以了)

# encoding: utf-8
# 程式碼來源:全棧測開訓練營
 
import logging
import os
 
import pytest
 
from common.http_request import HTTPRequests
from config.url_config import URLConf
 
 
datadir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "test_data")
logger = logging.getLogger('conftest紀錄檔')
 
 
def pytest_addoption(parser):
    # choices 只允許輸入的值的範圍
    parser.addoption(
        "--env", action="store", default='test', choices=['dev', 'test', 'prod'], help="set env"
    )
 
 
# 獲取命令列引數的fixture
@pytest.fixture(scope='session')
def get_env(request):
    # print("fixutre..................")
    return request.config.getoption('--env')
 
# 宣告一個返回http請求物件的fixture,所有用例在一個session中
# @pytest.fixture(scope='module', autouse=True)
@pytest.fixture(autouse=True)
def http(request):
    env = request.getfixturevalue("get_env")
    url_mapping = URLConf.url_mapping.value
    url = url_mapping.get(f'{env}')
    http = HTTPRequests(url)
 
    return http
 
 
@pytest.fixture(scope='session')
def get_token_head(request):
    env = request.getfixturevalue("get_env")
    url_mapping = URLConf.url_mapping.value
    url = url_mapping.get(f'{env}')
    http = HTTPRequests(url)
 
    user = URLConf.email_user.value
    user_list = user.get(f'{env}').split("/")
    username = user_list[0]
    password = user_list[1]
 
    param = {'clientType': 2,
             'language': 'en',
             'loginId': username,
             'loginPassword': password}
 
    logger.info("請求的url=={}".format(url))
    response = http.post(uri=r'/api/auth/login/account/v1', data=param)
    logger.info("獲取的返回值是:".format(response.text))
    token = None
    if response.status_code == 200:
        token = response.json().get('result')['token']
    else:
        token = 'get token fail'
 
    head = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko',
        'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, '
                  'application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, '
                  'application/msword, */*',
        'Accept-Language': 'zh-CN',
        'Authorization': token}
 
    yield head

1.6 將測試資料放到excel中

我們的測試資料是放在excel中,注意,這裡有prodtestdev三個目錄,對應三個環境的測試資料,我這裡只建立了test測試環境的測試資料。這裡的測試資料需要包含兩部分:

  • 你呼叫介面傳入的所有引數;
  • 你要斷言的所有資訊,因為你傳的引數不同,返回的內容就不同,你斷言的內容也就不相同了。

那麼這時候,就需要一個讀取excel的公共方法了,放到common裡

# 建立解析excel的方法
import logging
 
from openpyxl import load_workbook
 
logger = logging.getLogger("讀取excel")
 
 
class ParseExcel(object):
    def __init__(self, excelPath, sheetName):
        self.wb = load_workbook(excelPath)
        self.sheet = self.wb[sheetName]
        self.maxRowNum = self.sheet.max_row
 
 
    # 依據傳入的數位,決定獲取幾列excel資料
    def getDataFromSheet(self, num):
        dataList = []
        for line in self.sheet.rows:
            tmplist = []
            for i in range(num):
                tmplist.append(line[i].value)
            dataList.append(tmplist)
            print("dadddddd:{}".format(dataList))
 
        return dataList[2:]

這裡,還需要再test_data中,建立一個檔案,為了獲取前面test_data依據環境建立的dev/test或prod檔案目錄

1.7 開始編寫自動化測試案例了

測試案例中有幾個點,需要解釋一下:
1、authBaseDir,這個就是根據test_data/test拼接出來的獲取測試資料的目錄
2、allure.feature,在測試報告中,會展現這個介面名稱,這個名稱最好與你公司的開發寫的介面模組保持一致,方便後續查詢問題
3、allure.story 這裡也要與開發寫的具體某個介面的名稱保持一致。
4、pytest.mark.parametrize,這裡就是運用的DDT資料驅動的模式,從excel中一條一條的獲取資料,然後執行同一條介面測試用例,excel中比如有3條資料,那麼就表示這個案例依據每一條資料的引數,總共執行了三次

# encoding: utf-8
 
"""
 
Account Api模組
"""
import logging
import os
 
import allure
import pytest
 
from common.get_data_url import get_data_url
from common.parse_excel import ParseExcel
 
datadir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "test_data")
data_url = get_data_url()
# 獲取到test_datatest的目錄,如果是prod環境,那麼就是獲取test_dataprod目錄
authBaseDir = os.path.join(datadir, data_url)
 
logger = logging.getLogger("Account Api模組紀錄檔")
 
 
@allure.feature("AccountApi模組")
@pytest.mark.webtest
class TestAccountApi(object):
    """Query Related Achievements: /api/auth/account/achievement/related/query/v1
 
    """
    Query_Related_Achievements_dir = os.path.join(authBaseDir, 'Query_Related_Achievements.xlsx')
    logger.info("Query_Related_Achievements測試資料的路徑是:{}".format(Query_Related_Achievements_dir))
    parse = ParseExcel(Query_Related_Achievements_dir, 'Sheet1')
    Query_Related_Achievements_params = parse.getDataFromSheet(5)
 
    @allure.story("Query Related Achievements(查詢使用者成就資訊)")
    @pytest.mark.parametrize("clientType,language,retCode,istoken,result", Query_Related_Achievements_params)
    def test_001_Query_Related_Achievements(self, get_token_head, http, clientType, language, retCode, istoken, result):
        uri = '/api/auth/account/achievement/related/query/v1'
        params = {"clientType": clientType, "language": language}
 
        if istoken == 'yes':
            header = get_token_head
            response = http.get(uri=uri, params=params, headers=header)
            json_req = response.json()
            logger.info("Query_Related_Achievements有token的返回值是:{}".format(json_req))
 
            assert json_req.get('retCode') == 200
            assert json_req.get('result')[0]['smallImg'] == result
        else:
            response = http.get(uri=uri, params=params)
            json_req = response.json()
            logger.info("Query_Related_Achievements沒有token的返回值是:{}".format(json_req))
 
            assert json_req.get('retCode') == 401
            assert json_req.get('message') == result

1.8 整合allure

寫到這裡,是不是發現前面的allure.feature是不是用不了呢?這是因為我們還沒有整合allure進去。
1、下載allure,放到lib目錄下,使你的工程具備allure的能力。

2、pip install allure-pytest安裝pytest對應的allure包

1.9 這時候就可以建立一些執行策略了

1、先在main中建立一個pytest.ini檔案,設定一些執行引數

2、在main中建立執行策略

  • 先在run_pytest方法中,執行案例並生成allure的json格式的報告檔案,這裡可以帶--env prod將對應環境資訊傳入,這裡沒有傳是因為預設是test環境,不傳入的話就是執行的test環境測試資料
  • general_report方法時將生成的json格式的報告,最終生成html檔案放置到report下面的目錄中
  • 建立一個執行緒,先執行run_pytest,再執行general_report,避免json檔案沒有生成,這樣生成html檔案的報告資料可能不全,甚至沒有。

# encoding: utf-8
 
 
"""
所有案例執行並生成allure測試報告的執行策略
"""
 
import os
import sys
import threading
import pytest
 
 
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../')
from common.report import Report
 
 
project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
report_dir = os.path.join(project_root, 'report')
# 存放測試結果的目錄,會生成一推json檔案
result_dir = os.path.join(report_dir, 'allure_result')
allure_report = os.path.join(report_dir, 'allure_report')
 
report = Report()
 
#  定義搜尋條件,搜尋所有以test開頭的用例
tag = 'test'
 
 
def run_pytest():
    # --clean-alluredir
    # pytest.main(['-vv', '-s', '-m', 'webtest', f'--alluredir={result_dir}', '--clean-alluredir'])
    # 執行前清除allure_result資料,避免生成報告時,會把上次執行的資料帶進去
    pytest.main(['-vv', '-s', '-k', f'{tag}', f'--alluredir={result_dir}', '--clean-alluredir'])
 
 
def general_report():
    # 呼叫cmd方法 report.allure,根據windows或linux環境判斷
    # 然後執行生成報告的方法generate
    # --clean 覆蓋路徑,將上次的結果覆蓋掉
    cmd = "{} generate {} -o {} --clean".format(report.allure, result_dir, allure_report)
    # 執行命令列命令,並通過read()方法將命令的結果返回
    print(os.popen(cmd).read())
 
 
if __name__ == '__main__':
    # 建立兩個執行緒,分別執行兩個方法
    run = threading.Thread(target=run_pytest)
    gen = threading.Thread(target=general_report)
    run.start()
    # 先執行第一個執行緒,這個執行緒執行完才會執行下面的執行緒和主執行緒
    run.join()
    gen.start()
    gen.join()

1.10 自動化執行生成結果

在windows下,右鍵執行main下面的run_test_allure_html.py(就是上一個步驟的python檔案),然後開啟report/allure_report/index.html看看報告是否生成成功

2. jenkins環境搭建(linux環境)

好了,到這一步,在windows下我們已經執行成功,現在我們要整合到jenkins環境去,並搭建在linux環境下。
1、將程式碼上傳到公司的git(沒有git的自己搭建一套吧)
2、找一臺linux機器(自己去自己公司找資源)
3、在linux下安裝jenkins(我是放到tomcat中)、python3、pytest、allure、openpyxl(這些步驟在網上可以搜尋到,這裡不贅述了)
4、啟動linux下的tomcat,然後在window下開啟jenkins的服務地址

5、建立一個自由風格的job

6、Job需要填寫的具體內容有:

A、選擇丟棄舊的構建(保留的構建天數依據自己的情況選擇)

B、“限制專案的執行節點”依據自己的情況選擇(我這裡給我的jenkins主伺服器取了一個叫linux的標籤,我的機器也是linux機器)

C、git--將git上的程式碼拉下來

D、“執行shell”,這裡把程式碼從git拉到了jenkins的執行目錄裡,一般在linux下的root/.jenkins裡,在執行shell時,最好chmod修改下整個工程的目錄許可權,因為有可能因許可權問題執行不了

E、構建後的操作:這裡需要再jenkins裡安裝allure外掛才能看到allure Report,第一個Path,這裡寫的是allure生成的json檔案的目錄,所以是report/allure_result,第二個Report path指的是生成的index.html檔案的目錄,所以是report/allure_report

立即構建並檢視報告

上面的job建成後,就可以點選立即構建,執行了。執行完後,點選allure Report檢視最終的報告。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com