1. 程式人生 > >unittest框架擴展(自動生成用例)自動化-上

unittest框架擴展(自動生成用例)自動化-上

sendmail hand 定義 .html 日誌 desktop headers 提示 list

一.思想:

基於數據驅動和代碼驅動結合的自動化測試框架。

二.自動化測試框架步驟:

1.獲取用例,用例格式:.ymal

2.調用接口

3.校驗結果

4.發送測試報告

5.異常處理

6.日誌模塊

三.基於上一篇文章中,使用unittest模塊框架,編寫自動化調用接口測試,拷貝生成用例的python文件作為模板,在conf下新建base.txt,只需每次修改文件中類名:技術分享圖片和文件名:技術分享圖片生成同樣的python文件作為用例即可。

base.txt如下:

技術分享圖片

import unittest,requests
import ddt
from BeautifulReport import BeautifulReport as bf
from BeautifulReport import BeautifulReport as bf
from urllib import parse
from conf.setting import BASE_URL
@ddt.ddt
class %s(unittest.TestCase): #是百分號s指變量class_name
	base_url = BASE_URL
	@ddt.file_data(r‘%s‘)#ddt幫你讀文件,獲取文件內容,循環調用函數 百分號s是指變量file_name
	def test_request(self,**kwargs):
		detail = kwargs.get(‘detail‘,‘沒寫用例描述‘)
		self._testMethodDoc = detail  #動態的用例描述
		url = kwargs.get(‘url‘)#url
		url = parse.urljoin(self.base_url,url)#拼接好url
		method = kwargs.get(‘method‘,‘get‘)#請求方式
		data = kwargs.get(‘data‘,{}) #請求參數
		header = kwargs.get(‘header‘,{})#請求頭
		cookie = kwargs.get(‘cookie‘,{})#cookie
		check = kwargs.get(‘check‘)
		method = method.lower() #便於處理
		try:
			if method==‘get‘:
				res = requests.get(url,params=data,cookies=cookie,headers=header).text
				#因為接口有異常的情況下, 可能返回的不是json串,會報錯
			else:
				res = requests.post(url,data=data,cookies=cookie,headers=header).text
		except Exception as e:
			print(‘接口請求出錯‘)
			res = e
		for c in check:
			self.assertIn(c,res,msg=‘預計結果不符,預期結果:‘+c + ‘實際結果:‘ +res)

四.自動化框架的文件布局:

  技術分享圖片

五.寫代碼:

1.新建用例,舉例:註冊reg.yaml和註冊login.yaml

技術分享圖片

reg.yaml:

技術分享圖片

2.配置setting文件,將所有文件中用到的變量定義在該文件,需要修改的時候,直接在該文件中修改即可。setting:

import os
BASE_PATH = os.path.dirname(   #找到utp的目錄
    os.path.dirname(os.path.abspath(__file__))
)
MAIL_HOST=smtp.163.com
MAIL_USER=[email protected]
MAIL_PASSWRD 
= xxxxxxxxx1 TO = [ [email protected], ] LEVEL = debug #日誌級別 LOG_PATH = os.path.join(BASE_PATH,logs) #存放日誌的路徑 CASE_PATH = os.path.join(BASE_PATH,cases) #存放用例的路徑 YAML_PATH = os.path.join(BASE_PATH,case_data) #存放yaml文件的路徑 CASE_TEMPLATE = os.path.join(BASE_PATH,conf,base.txt) #用例模板的路徑
REPORT_PATH = os.path.join(BASE_PATH,report) #存放報告的目錄 BASE_URL = http://118.xx.xx.xx #接口的地址 LOG_NAME=utp.log #日誌的文件名

3.在lib文件下新建tools.py:首先判斷case_data下的.yaml文件個數,創建對應的python文件。具體:打開並讀取base.txt文件,將文件中的類和文件名替換後,再創建python文件。生成用例-->運行所有用例:

import datetime
import yagmail
from lib.log import utp_log  #要用到日誌文件
from conf import setting  #要用到配置文件中的變量
import os
import unittest  
from BeautifulReport import BeautifulReport as bf  #生成報告
def makeCase():  #生成用例
    all_yaml = os.listdir(setting.YAML_PATH)  #獲取所有的ymal文件
    base_case_str = open(setting.CASE_TEMPLATE,encoding=utf-8).read()#讀取到base.txt文件裏的內容,寫在循環外面
    for yaml in all_yaml:  #判斷讀取的文件是否為.yaml或.yml
        if yaml.endswith(.yaml) or yaml.endswith(.yml):#判斷是否是yml文件
            class_name = yaml.replace(.yml,‘‘).replace(.yaml,‘‘).capitalize()#將文件名的後綴去掉獲取類名,並首字母大寫
            file_name = os.path.join(setting.YAML_PATH,yaml)#拼接生成的ymal文件的絕對路徑
            content = base_case_str %(class_name,file_name)
            py_file_name = os.path.join(setting.CASE_PATH,class_name)#拼好生成python文件的絕對路徑
            open(%s.py%py_file_name,w,encoding=utf-8).write(content)  #以w格式打開,保證每次打開ymal文件都會清空重新寫

def run_all_case():  #找到所有的python用例文件,並運行
    suite = unittest.TestSuite()  #調用unittest模塊的TestSuite(),實例化
    all_py = unittest.defaultTestLoader.discover(setting.CASE_PATH,*.py)  #在指定目錄下找python文件:以.py結尾的python文件
    #找到所有的python文件
    [ suite.addTests(py) for py in all_py]  #這裏用addTests,是因為py文件裏可能有多個函數,都要添加進來
    #列表生成式,添加文件裏面的case到測試集合裏面
    # for py in all_py:  #等同於上面的列表生成式
    #     suite.addTests(py)
    run=bf(suite)
    today = datetime.datetime.today().strftime(%Y%m%d%H%M%S)  #.strftime將時間格式化取到秒
    title = %s_接口測報告.html%today
    report_abs_path = os.path.join(setting.REPORT_PATH,title) #拼接報告的絕對路徑
    run.report(title,filename=title,log_path=setting.REPORT_PATH)
    return run.success_count,run.failure_count,report_abs_path


def sendmail(title,content,attrs=None):
    try:
        m = yagmail.SMTP(host=setting.MAIL_HOST,user=setting.MAIL_USER
                     ,password=setting.MAIL_PASSWRD
                     )
        m.send(to=setting.TO,subject=title,
               contents=content,
               attachments=attrs)
    except Exception as e:
        msg = 郵件發送失敗,%s%e
        utp_log.error(msg)

4.在bin文件下新建run.py,按照邏輯運行文件。分別調用生成用例,運行用例,發報告的類。

import os,sys
import datetime

BASE_PATH = os.path.dirname(  #因為run.py是入口文件,還沒有加載setting文件,所以不能找到環境變量,需在此定義BASE_PATH找到utp目錄
    os.path.dirname(os.path.abspath(__file__))
)
sys.path.insert(0,BASE_PATH)
from lib import tools

def main():
    tools.makeCase()#自動產生用例的python文件
    pass_count,fail_count,abs_path = tools.run_all_case()#運行所有用例並獲取其返回值
    msg=‘‘‘
    各位好!
        本次接口測試結果如下:
            通過用例:%s條
            失敗用例:%s條
            詳細信息見附件【%s】。
    ‘‘‘%(pass_count,fail_count,os.path.basename(abs_path)) #os.path.basename()獲取絕對路徑的文件名
    today = datetime.datetime.today().strftime(%Y%m%d%H%M%S)
    title = 接口測試報告_%s%today #郵件標題
    tools.sendmail(title,msg,abs_path) #發送郵件,標題,提示信息,附件
main()

5.生成的python文件舉例,Login.py:

import unittest,requests
import ddt
from BeautifulReport import BeautifulReport as bf
from BeautifulReport import BeautifulReport as bf
from urllib import parse
from conf.setting import BASE_URL
@ddt.ddt
class Login(unittest.TestCase): #是百分號s指變量class_name
    base_url = BASE_URL
    @ddt.file_data(rC:\Users\Fancy\Desktop\學習筆記\day11\utp\case_data\login.yaml)#ddt幫你讀文件,獲取文件內容,循環調用函數 百分號s是指變量file_name
    def test_request(self,**kwargs):
        detail = kwargs.get(detail,沒寫用例描述)
        self._testMethodDoc = detail  #動態的用例描述
        url = kwargs.get(url)#url
        url = parse.urljoin(self.base_url,url)#拼接好url
        method = kwargs.get(method,get)#請求方式
        data = kwargs.get(data,{}) #請求參數
        header = kwargs.get(header,{})#請求頭
        cookie = kwargs.get(cookie,{})#cookie
        check = kwargs.get(check)
        method = method.lower() #便於處理
        try:
            if method==get:
                res = requests.get(url,params=data,cookies=cookie,headers=header).text
                #因為接口有異常的情況下, 可能返回的不是json串,會報錯
            else:
                res = requests.post(url,data=data,cookies=cookie,headers=header).text
        except Exception as e:
            print(接口請求出錯)
            res = e
        for c in check:
            self.assertIn(c,res,msg=預計結果不符,預期結果:+c + 實際結果: +res)

6.log.py,生生日誌的文件:

import logging,os
from logging import handlers
from conf import setting
class MyLogger():
    def __init__(self,file_name,level=info,backCount=5,when=D):
        logger = logging.getLogger()  # 先實例化一個logger對象,先創建一個辦公室
        logger.setLevel(self.get_level(level))  # 設置日誌的級別的人
        cl = logging.StreamHandler()  # 負責往控制臺輸出的人
        bl = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, backupCount=backCount, encoding=utf-8)
        fmt = logging.Formatter(%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s)
        cl.setFormatter(fmt)  # 設置控制臺輸出的日誌格式
        bl.setFormatter(fmt)  # 設置文件裏面寫入的日誌格式
        logger.addHandler(cl)
        logger.addHandler(bl)
        self.logger = logger

    def get_level(self,str):
        level = {
            debug:logging.DEBUG,
            info:logging.INFO,
            warn:logging.WARNING,
            error:logging.ERROR
        }
        str = str.lower()
        return level.get(str)


path = os.path.join(setting.LOG_PATH,setting.LOG_NAME) #拼好日誌的絕對路徑
utp_log = MyLogger(path,setting.LEVEL).logger  #日誌級別
#直接在這裏實例化,用的時候就不用再實例化了

總結:

該自動化框架是基於unittest重新封裝的,也是基於數據驅動進行的,只是數據的格式不是excel而是yaml格式的。與第一篇自動化框架相比,不需要自己寫框架。

unittest框架擴展(自動生成用例)自動化-上