四.unittest介面自動化框架介紹

少壮不努力123發表於2024-03-09
一. unittest常用校驗方法介紹
1.unittest模板基本概念
unittest是python內建的單元測試框架,具備編寫用例、組織用例、執行用例、輸出報告等自動化框架的條件。使用unittest前需要了解該框架的五個概念:
即test case, test suite, testLoader,test runner, test fixture。
test case :一個完整的測試單元,執行該測試單元可以完成對某一個問題的驗證,完整體現在:測試前環境準備(setUp),執行測試程式碼(run),及測試後環境還原(tearDown);
test suite :多個測試用例的集合,測試套件或測試計劃;
testLoader :載入TestCase到TestSuite中的,其中loadTestsFrom__()方法用於尋找TestCase,並建立它們的例項,然後新增到TestSuite中,返回TestSuite例項;
test runner :執行測試用例,並將測試結果儲存到TextTestResult例項中,包括執行了多少測試用例, 成功了多少,失敗了多少等資訊;
test fixture:一個測試用例的初始化準備及環境還原,主要是setUp() 和 setDown()方法;
2.unittest模板基本介紹
1.簡單的unittest的使用
四.unittest介面自動化框架介紹
 #首先匯入unittest
import unittest

class testUnittestOne(unittest.TestCase):

     #編寫測試用例,方法名必須以test開頭
     def test_equals(self):
         self.assertEquals(1,1,msg="相等")

 #執行測試用例
if __name__ == '__main__':
    unittest.main()
View Code

2.testCase多個之間的執行順序,按照測試用例的方法名字母進行排序執行的;每條用例執行前都會執行一下setUp方法,用例執行後都還會在執行一遍tearDown方法

四.unittest介面自動化框架介紹
import unittest

class testUnittestTwo(unittest.TestCase):
#測試用例初始化方法setUp
    def setUp(self):
        print("開始執行測試用例")

#測試用例後置方法tearDown
    def tearDown(self):
        print("執行完測試用例")

    def test_case1(self):
        print("執行case1")
        self.assertEqual(1,1,msg="1等於1")

    def test_aase2(self):
        print("執行case2")
        self.assertEqual(1, 2, msg="1不等於2")

if __name__ == '__main__':
    unittest.main()
View Code
執行結果:
3.setUpClass、tearDownClass類方法分別是該測試類執行前的初始化方法和後置方法
四.unittest介面自動化框架介紹
 import unittest

 class testUnittestTwo(unittest.TestCase):
     #測試用例初始化方法setUp
     @classmethod
     def setUpClass(self):
         print("開始執行測試用例")

     #測試用例後置方法tearDown
     @classmethod
     def tearDownClass(self):
         print("執行完測試用例")

     def test_case1(self):
         print("執行case1")
         self.assertEqual(1,1,msg="1等於1")

     def test_aase2(self):
         print("執行test_aase2")
         self.assertEqual(1, 2, msg="1不等於2")

 if __name__ == '__main__':
     unittest.main()
View Code

執行結果:

3.unittest模板常用校驗方法

二. unittest介面引數化及用例集介紹

1.unittest引數化
四.unittest介面自動化框架介紹
 import unittest
 import requests
 import parameterized  # 資料引數化需要匯入該模組
 import HTMLTestRunner

 class LoginTest(unittest.TestCase):
     url = "http://api.nnzhp.cn/api/user/login"

    # 測試資料進行引數化
     @parameterized.parameterized.expand([
         ["niuhanyang", "aA123456"],
         ["niuhanyang", "aA1234567"],
         ["niuhanyang", "aA1234568"]
     ])
     def test_login(self, username, password):
         data = {"username": username, "passwd": password}
         re = requests.post(self.url, data).text
         self.assertIn("userId", re, "包含userId")


 if __name__ == '__main__':
     # 把測試用例放在測試集合中
     suite = unittest.makeSuite(LoginTest)
     f = open("report.html", "wb")
     # 生成測試報告,需要先匯入HTMLTestRunner模板,放在當前目錄下或python第三方模板安裝的site_package資料夾下
     runner = HTMLTestRunner.HTMLTestRunner(f, description="baogao", title="")
     runner.run(suite)
     f.close()
View Code

執行結果:

2.unittest透過讀取檔案內容進行引數化

定義user.txt檔案,檔案每行定義三個引數,逗號進行分割;

四.unittest介面自動化框架介紹
 import unittest
 import parameterized
 import requests
 import HTMLTestRunner


 class TestParameFile(unittest.TestCase):
     url = 'http://api.nnzhp.cn/api/user/login'

     """
     透過檔案進行引數化
     """

     def getDataForFile(fileName):
         data = []
         with open(fileName, encoding="utf-8") as fw:
             for line in fw:
                 line = line.strip()
                 if line:
                     data.append(line.split(","))
         return data

     @parameterized.parameterized.expand(getDataForFile("users.txt"))
     def test_login(self, username, password, check):
         # 傳送介面請求
         re = requests.post(self.url, {"username": username, "passwd": password}).text
         self.assertIn(check, re, "沒有返回%s" % check)


 if __name__ == "__main__":
     # 生成測試用例套件
     testSuit = unittest.makeSuite(TestParameFile)

     f = open("testParameFile.html", "wb")
     Runner = HTMLTestRunner.HTMLTestRunner(f, title="測試報告", description="測試報告詳情")
     Runner.run(testSuit)
     f.close()
View Code

執行結果:

3.unittest多個用例集執行
建立case資料夾,在case資料夾下定義多個測試用例類

四.unittest介面自動化框架介紹
 import unittest
 import HTMLTestRunner
 import time
 import BeautifulReport


 class RunManyTestCase(unittest.TestCase):

     def runTestCase(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb")
         runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集報告", description="xxx系統測試報告")
         runCase.run(caseSuite)
         f.close()

     def runTestCaseReport(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         bf = BeautifulReport.BeautifulReport(caseSuite)
         bf.report(description='查詢測試用例的', filename='discover%s.html' % (time.time()))


 if __name__=="__main__":
     c = RunManyTestCase()
     c.runTestCase()
     c.runTestCaseReport()
View Code

4.unittest透過HTMLTestRunner進行生成報告

四.unittest介面自動化框架介紹
 import unittest
 import HTMLTestRunner
 import time
 import BeautifulReport


 class RunManyTestCase(unittest.TestCase):

     def runTestCase(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb")
         runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集報告", description="xxx系統測試報告")
         runCase.run(caseSuite)
         f.close()

     def runTestCaseReport(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         bf = BeautifulReport.BeautifulReport(caseSuite)
         bf.report(description='查詢測試用例的', filename='discover%s.html' % (time.time()))


 if __name__=="__main__":
     c = RunManyTestCase()
     c.runTestCase()
View Code

執行結果:

5.unittest透過BeautifulReport進行生成報告

四.unittest介面自動化框架介紹
 import unittest
 import HTMLTestRunner
 import time
 import BeautifulReport


 class RunManyTestCase(unittest.TestCase):

     def runTestCase(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         f = open("manyReport%s.html" % (time.strftime("%y%m%d")), "wb")
         runCase = HTMLTestRunner.HTMLTestRunner(f, title="用例集報告", description="xxx系統測試報告")
         runCase.run(caseSuite)
         f.close()

     def runTestCaseReport(self):
         # 將測試用例載入到caseSuite中
         caseSuite = unittest.defaultTestLoader.discover("case", "*")
         # 生成測試報告,需要先匯入BeautifulReport模板,放在當前目錄下或python第三方模板安裝的site_package資料夾下
         bf = BeautifulReport.BeautifulReport(caseSuite)
         bf.report(description='查詢測試用例的', filename='discover%s.html' % (time.time()))


if __name__=="__main__":
     c = RunManyTestCase()
     c.runTestCaseReport()
View Code

執行結果:

附件:HTMLTestRunner.py檔案和BeautifulReport.zip壓縮吧

6.unittest建立有關聯關係的介面
四.unittest介面自動化框架介紹
import unittest
import parameterized


class Case(unittest.TestCase):


    def login(self,userid):
        return userid

    @parameterized.parameterized.expand([
        [222],
        [333]
    ])
    def test_login(self,userid):
        "ss"
        userid=self.login(userid)

        return self.assertEqual(userid,222,'成功')

suite=unittest.makeSuite(Case)

import BeautifulReport.BeautifulReport

bf=BeautifulReport.BeautifulReport(suite)
bf.report(description="測試報告",filename='關聯關係的.html')
View Code
三. unittest封裝介面自動化框架
1.需求分析
utp介面自動化框架:
a.介面自動化測試用例放在cases目錄下且case開頭進行命名,涉及到有關聯關係的介面可以先定義基類
b.介面自動化測試用例需要與介面分離,因此需要進行引數化,資料放在datas目錄下
c.查詢所有測試介面進行執行,執行成功後傳送郵件
2.程式碼編寫
a.先分別建立bin、cases、configs、datas、libs、logs、reports資料夾,bin目錄進行存放程式主入口,cases目錄下
存放介面測試用例;configs目錄下進行存放配置檔案;datas目錄下進行存放介面測試資料;libs目錄下進行存放常用功能;logs目錄下進行存放日誌檔案;reports進行存放介面自動化測試報告

b.libs資料夾下定義toos.py

四.unittest介面自動化框架介紹
import os

import jsonpath
from configs.Settings import T0,CC,EMAIL_INFO,LOG,DATAS_PATH
import traceback,time,yagmail

def get_value(d,k):
    # 透過jsonpath.jsonpath來取字典中key所對應的值
    result=jsonpath.jsonpath(d,'$..%s'%k)
    # 如果取到了返回第一個值,否則返回空字串
    if result:
        return result[0]
    return ''

def send_email(pass_count,fail_count,file_name):
    LOG.debug("開始傳送報告了,檔名是%s"%file_name)
    content='''
各位好:
    本次介面自動化測試結果如下,總共執行%s條用例,透過%s條,失敗【%s】條。
    詳情請檢視附件。
    '''%((pass_count+fail_count),pass_count,fail_count)

    subject='%s-介面測試報告'%time.strftime("%Y-%m-%d %H%M%S")

    email=yagmail.SMTP(**EMAIL_INFO,encoding="GBK")

    try:
        email.send(to=T0,cc=CC,subject=subject,contents=content,attachments=file_name)
    except Exception as e:
        LOG.error("傳送報告失敗,具體失敗原因是%s"%traceback.format_exc())
    else:
        LOG.debug("報告傳送成功")

def get_data_from_text(file_name):
    """獲取引數化資料"""
    data=[]
    file_name=os.path.join(DATAS_PATH,file_name)
    with open(file_name,encoding='utf-8') as fr:
        for line in fr:
            line=line.strip()
            if line:
                data.append(line.split(","))
    return data

def get_data_from_excel(file_name):
    """獲取引數化資料"""
    pass


def get_data_from_db(file_name):
    """獲取引數化資料"""
    pass

def get_data_from_redis(file_name):
    """獲取引數化資料"""
    pass
View Code

c.configs資料夾下定義Settings.py檔案

四.unittest介面自動化框架介紹
import os


# 傳送郵件
EMAIL_INFO={
    "user":"13424210282@163.com",
    "password":"HLXWWGTUWGNAAAEA",
    "host":"smtp.163.com",
}
# 郵件接收人
T0=["974219141@qq.com"]
# 郵件抄送人
CC=['751462075@qq.com']

# 介面請求url地址配置
host_map={
    "fat":"http://127.0.0.1:8787",
    "uat":"",
    "pro":""
}
default="fat"

HOST=host_map.get(default)

# 自動化專案父目錄
BASE_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 測試用例目錄
CASE_PATH=os.path.join(BASE_PATH,'cases')
# 日誌檔案目錄
LOG_PATH=os.path.join(BASE_PATH,"logs",'utp.log')

import nnlog
LOG=nnlog.Logger(LOG_PATH)
# 測試報告目錄
REPORT_PATH=os.path.join(BASE_PATH,'reports')

# 查詢用例
DATAS_PATH=os.path.join(BASE_PATH,'datas')
View Code
d.cases資料夾下定義case_login.py檔案(沒有關聯關係)
1.沒關聯關係的介面
四.unittest介面自動化框架介紹
import unittest
import parameterized
from libs.tools import get_data_from_text
import requests
from configs.Settings import HOST
from urllib.parse import urljoin

class CaseTestLogin(unittest.TestCase):
    # 拼接介面請求url
    url=urljoin(HOST,"/login")

    # 進行引數,透過get_data_from _text獲取login.txt檔案
    @parameterized.parameterized.expand(get_data_from_text("login.txt"))
    def test_login(self,user,password,check):
        data={"username":user,"password":password}
        headers={"Content-Type":"application/json"}
        # 傳送介面請求
        r=requests.post(self.url,json=data,headers=headers).text
        # 校驗check引數的值是否在介面返回的字串中
        self.assertIn(check,r,"%s在%s中"%(check,r))
View Code

2.有關聯關係的介面,先在BaseCase.py檔案中定義基類Base_Case

四.unittest介面自動化框架介紹
import unittest
import requests
from configs.Settings import HOST
from urllib.parse import urljoin
from libs.tools import get_value

class Base_Case(unittest.TestCase):

    def login(self,user,password,check):
        data = {"username": user, "password": password}
        headers = {"Content-Type": "application/json"}
        # 傳送介面請求
        r = requests.post(urljoin(HOST,"/login"), json=data, headers=headers)
        # 校驗
        self.assertIn(check, r.text, "%s在%s中" % (check, r.text))
        # 獲取介面請求返回的tokenId並進行返回
        tokenId=get_value(r.json(),'tokenId')
        return tokenId
View Code

在定義case_pay.py檔案中Case_Pay類繼承Base_Case類

四.unittest介面自動化框架介紹
import unittest

import requests

from cases import BaseCase
from configs.Settings import HOST
from urllib.parse import urljoin
from parameterized import parameterized
from libs.tools import get_data_from_text

class Case_Pay(BaseCase.Base_Case):

    @parameterized.expand(get_data_from_text("pay.txt"))
    def test_pay(self,user,password,check,money):
        """支付成功"""
        tokenId=self.login(user,password,check)
        data={"username":user,"money":money}
        headers={"tokenId":tokenId}
        r=requests.post(urljoin(HOST,"/pay"),json=data,headers=headers)
        self.assertIn("支付成功",r.text,)
View Code

e.datas資料夾下定義login.txt和pay.txt檔案

f.bin目錄下定義程式執行start.py檔案

四.unittest介面自動化框架介紹
import sys,os
import time

BASE_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,BASE_PATH)

import unittest
import BeautifulReport
from libs.tools import send_email
from configs.Settings import REPORT_PATH,CASE_PATH

def run():
    suite=unittest.defaultTestLoader.discover(CASE_PATH,"case*.py")
    bf=BeautifulReport.BeautifulReport(suite)
    filename="utp報告%s.html"%(time.strftime("%Y%m%d%H%M%S"))
    report_path=os.path.join(REPORT_PATH,filename)
    bf.report(description="utp測試報告",filename=filename,log_path=REPORT_PATH)
    send_email(bf.success_count,bf.failure_count,report_path)

if __name__ == '__main__':
    run()
View Code

最後執行bin目錄下的start.py檔案,可以正常看到測試報告

相關文章