1.yaml文件的读取

在xxx.yaml文件中写入以下内容:

-
  method : post
  url : http://***.***.**.**/api/user/login
  data :
    username : ****
    password : 123456
  headers :
    cookie : sdfsdfsdfsf
    user-agent : xxxxx
-
  method : post
  url : http://***.***.**.**/api/user/login
  data :
    username : ***
    password : 123456
  headers :
    cookie : sdfsdfsdfsf
    user-agent : xxxxx

读取xxx.yaml的数据信息代码为:
import yaml

f=open('xxx.yaml')
print(yaml.load(f))

读取到的信息为:
[{'data': {'username': '***', 'password': 123456}, 'url': 'http://***.***.**.**/api/user/login', 'method': 'post', 'headers': {'cookie': 'sdfsdfsdfsf', 'user-agent': 'xxxxx'}}, {'data': {'username': '****', 'password': 123456}, 'url': 'http://***.**.**.**/api/user/login', 'method': 'post', 'headers': {'cookie': 'sdfsdfsdfsf', 'user-agent': 'xxxxx'}}]

总结:只要遇到‘-’就会形成list的一个元素,遇到换行缩进就会形成一个字典元素

2.装饰器

# 装饰器  器指的就是函数,装饰函数的意思
# 在不改变原来函数调用方式、代码情况下,给函数增加新功能
# def taotao(name):
#     print(name)
#
# ahuang=taotao
# 函数即变量,此时taotao没有加括号,即没有调用,把他当做一个变量来传递了
# ahuang('涛涛')和调用taotao(‘涛涛’)是一样的
def timer(func):
    def add(*args,**kwargs): 写通用装饰器时,加上括号里的参数,可以兼容有传参的功能函数
        print('开始挣钱')
        res=func(*args,**kwargs)
        return res  装饰器函数加上返回值,可以兼容有返回值的函数
    return add
@timer 语法糖 效果等同于taotao=timer(taotao)
def taotao():
    print('我是涛涛')
ahuang=timer(taotao)此时taotao=func,开始执行timer,首先定义add,然后返回,此时的ahuang=add
ahuang()调用add函数

那么把ahuang替换成taotao就相当于在不改变原来调用方式的情况下,给函数增加了新功能

3.单元测试unittest
# 测试用例
# 测试用例集合
# testrunner 帮你运行用例的

def calc(a,b):
    return a//b

import BeautifulReport as br
import unittest
from unittest import TestCase
class MyTest(TestCase):#继承TestCase类
    @classmethod
    def setUpClass(cls):#所有用例执行之前运行它
        print('我是setup class')
    @classmethod
    def tearDownClass(cls):#所有用例执行完之后运行它
        print('我是teardown class')
    def setUp(self): #每条用例运行之前都会执行它
        print('setup 什么时候运行我呢')
    def tearDown(self):#每条用例运行之后都会执行它
        print('teardown 什么时候运行我呢')
    def test_calc1(self):
        '''这个用例是测试除法计算器正常的''' 在函数里面三个引号加注释,就是每条用例的描述信息
        print('这是第一条用例')
        res = calc(4,2)
        self.assertEqual(2,res,'预期结果和实际结果不符合 预期结果是 2 实际结果是%s'%res) #预期结果和实际结果比较
    def test_calc2(self):
        '''除法计算器第二个部正常'''
        res = calc(5,1)
        print('第二条运行')
        self.assertEqual(1,res) #断言 #a,b
unittest.main() #它可以帮你当前python文件里面的所有测试用例,测试用例的方法名称中必须以test为开头才会被认为是测试用例,用例的执行顺序以测试用例名称中的ascii码的先后顺序为准
test_suite =  unittest.TestSuite() #定义一个测试集合,是一个list
#test_suite.addTest(MyTest('test_b')) #只加入某一个测试用例
test_suite.addTest(unittest.makeSuite(MyTest))#把类里面所有的用例都加到集合里面
#下面是不好看的报告
import HTMLTestRunner
# f = open('report.html','wb')
# runner = HTMLTestRunner.HTMLTestRunner(stream=f, 写入到那个文件
#                                        title='测试报告', 标题
#                                        description='这个***的测试')  报告描述
# runner.run(test_suite)#运行哪个用例,此时不能用unittest.main(),这是两种运行方式
# f.close()
#下面是好看的报告

report = br.BeautifulReport(test_suite)

report.report(description='***测试',filename='report2.html')可以指定报告描述,报告文件名称(不用提前打开),还可以指定保存路径(如果不指定为当前路径)

print(report.failure_count)  #失败的次数
print(report.success_count)  #成功的次数

同时执行文件夹下多个文件的测试用例:
import unittest
import BeautifulReport as br
test_suite=unittest.TestSuite()  #定义一个测试集合

all_case=unittest.defaultTestLoader.discover('cases','*.py') #指定目录,指定找文件的规则

[test_suite.addTests(case) for case in all_case]  #把每个python文件里面的测试用例加入到测试集合里边
report=br.BeautifulReport(test_suite)
report.report(description='这是xxx测试用例',filename='new_report')

unittest参数化:
import unittest
import ddt,requests
import BeautifulReport as br
def login(username,passwd):
    print(username,passwd)
    return True

@ddt.ddt 如果需要用到参数化,需要在类上边加这个
class Login(unittest.TestCase):
    #如果是一个数组,函数
    @ddt.data(['u1','p1',True],['u2','p2',False],['u3','p3',True])
    @ddt.unpack 将每个数组内的多个参数拆解开
    def test_login(self,username,passwd,check):
        res=login(username,passwd)
        self.assertEqual(check,res)
    @ddt.data(1,2,3,4)
    def test_query(self,key):
        print('run..',key)
    @ddt.file_data('login.yaml') 
    def test_interface(self,**test_data): #代表每一个用例数据的那个字典,写两个星号,代表传过来的数据是字典
        url=test_data.get('url')
        method=test_data.get('method').upper()
        detail=test_data.get('detail','没有用例描述')
        self._testMethodDoc=detail #这个变量就是指定用例描述的
        data=test_data.get('data',{})
        headers=test_data.get('headers',{})
        cookies=test_data.get('cookies',{})
        is_json=test_data.get('is_json',0)#标识入参是否为josn
        check=test_data.get('check')
        if method=='POST':
            if is_json:
                res = requests.post(url, json=data, cookies=cookies, headers=headers).text
            else:
                res=requests.post(url,data=data,cookies=cookies,headers=headers).text
        elif method=='GET':
            res=requests.get(url,params=data,cookies=cookies,headers=headers).text
        for c in check:
            self.assertIn(c,res,'%s不在%s里面'%(c,res))
# unittest.main()
report=br.BeautifulReport(unittest.makeSuite(Login))
report.report('接口测试','Login_report.html')