2020年06月12日--12----python单元测试unittest框架(下)

1.test_1_login.py文件
'''
==================================
cooding:utf-8
@Time    :2020/6/12 20:00
@Author  :henry
@Email   :yinpingwei@gmail.com
@File    :test_1_login.py
@Software:PyCharm
===================================
'''

# 单元测试
"""
单元测试:就是对单个模块或者是单个类或者是单个函数进行测试
自动化的测试:
代码实现的用例,代码执行用例,代码判断结果,代码生成测试报告

单元测试框架类型有:
1.pytest框架
2.unittest框架——4大核心概念
        TestCase(测试用例)   
        TestSuite(测试套件)
        TextTestRunner(执行用例/呈现结果)
        Fixture(前置后置条件)

    表达用例-》收集用例-》执行用例-》生成报告

1.TestCase(测试用例) 
    用例编写格式步骤:
    1. import unittest   # 导入unittest模块,被测文件或者其中的类
    2. class xxxx(unittest.TestCase)   # 创建一个测试类 ,继承unittest.TestCase
    3. def Testxxx(self)       # 在定义一个测试函数,以test_开头,定义测试函数。
        def test_xxx(self):     # 每一个test_开头的函数,就是一个测试用例。
    4. 测试用例中:
        1、测试数据、期望结果
        2、测试步骤 
        3、断言:预期结果与实际结果的比对
            AssertionError: 断言失败 - 用例失败
            assert 表达式(True表示通过,False表示失败)
            self.assertXXXXX()
        4、前置后置(Fixture)-前置条件、后置工作
            自动化用例:1.前置后置(可有可无) 2、步骤 3、断言

        unittest用例断言方法:
            1.assertEqual(a,b)      检查:a==b   
            2.assertNotEqual(a,b)   检查:a!=b
            3.assertTrue(x)         检查:boxl(x)is True
            4.assertFalse(x)        检查:boxl(x)is False
            5.assertis(a,b)         检查:a is b
            6.assertisNot(a,b)      检查:a is not b
            7.assertin(a,b)         检查:a in b
            8.assertNotin(a,b)      检查:a not in b
            AssertionError: 断言失败,是unittest框架,识别用例识别的标识

2.Fixture(前置后置条件)可要可不要
    1、setup,teardown  -  类下面的每一条用例在执行之前,会执行setup(前置条件)
                              在每一条用例执行之后,会执行teardown(后置工作)
        setup  测试用例  teardown
        
    2、setupClass,teardownClass  - 类里面的第一个用例执行之前执行,会执行setupClass
                                   类里面最后一个用例执行之后,会执行teardownClass
        stupClass  测试类  teardownClass
        
3.TestSuite/TestLoader(测试套件/用例收集)
    1.用例套件 TestSuite: 测试用例集合(了解均可)
        unittest.TestSuite    实例化套件
        方法一:addTest(类名('用例名'))     添加一个测试用例
        方法二:addTests([])    添加一个测试用例的列表
    
    2.TestLoader:测试用例收集(专门用这个)
        可通过类目,模块名,目录三种方式去收集用例,我们只用方法一即可
        方法一:目录(最常用)
            unittest.TestLoader().discover(搜索目录)  
            搜索标准:
                1.从指定目录
                2.文件过滤标准:以文件名匹配,test*.py的文件
                3.在文件当中去过滤用例:继承了unittest.TestCase类的测试类,类当中以test_开头的测试函数
        方法二:类名(了解)
            unittest.TestLoader().loadTestFromTestCase(测试类名)  测试类名不需要加引号
        方法三:模块名(了解)
            unittest.TestLoader().loadTestFromModule(模块名)   模块名不需要加引号(注意要导入模块)
            
4.执行用例+生产测试报告
    运行用例,并生成测试报告到txt,html中
        1.TextTestRunner   运行结果以text呈现(是自带的)
        2.HtmlTestRunner   运行结果以html呈现(第三方,需要安装)
            先实例化,在生成html报告
        3.BeautifulIReport   运行结果以html呈现(第三方,需要安装)
            安装:pip install BeautifulIReport
            先实例化,在生成html报告

    用例的执行顺序:ASCII码顺序,从小到大
        1.ASCII码大小规则:0-9 < A-Z < a-z
        2.如果想自己指定执行顺序,在文件名或者用例名称上做文章
        
5.设计思维(参数化):ddt   data driven test      数据驱动
            一个测试流程,N个测试用例  流程不变,只是数据和断言不一样
模块名:ddt   第三方库 pip install ddt
    将多组测试数据,依次传递给一个测试流程
    
0、引入ddt
    import ddt
1、在测试类名上面,用@ddt.ddt
    @ddt.ddt
2、在测试函数上面,用@ddt。data(*列表)
    在测试函数的参数中,定义一个参数来接收每一组测试数据
    
    
    
总结:
表达用例           - 收集用例                                    - 执行用例生+成报告
setup                TestSuite                                      TextTestRunner (不用)
teardown             TestLoader().disover(搜索路径)                 HtmlTestRunner--实例化后调用run方法,html报告
setupClass           用例搜索原则:目录(test*.py)-测试用例        BeautifulIReport--实例化后,report生成html报告
teardownClass

用例的执行顺序:ASCII码顺序,从小到大
ddt:一个测试流程,N个测试用例 
1、列表 = 准备好N组测试数据

2、
import ddt
类名上:@ddt.ddt
测试流程函数上:@ddt.data(*列表)
测试流程函数:用一个变量接收每一组测试数据

"""
# 引入unittest单元测试
import unittest

# 从导入(class_work_two)包.(new_class)模块 导入(login_check)函数
from class_work_two.login import login_check

# 引入ddt模块
import ddt

 # 给定一个列表里面放不同的用例参数和预期结果
datas = [
    {'user':'woshijinyao300','password':'lemonbanpy30','check':{"code": 0, "msg": "登录成功"}},
    {'user':'woshijinyao300','password': 'lemonban','check':{"code": 1, "msg": "账号或密码不正确"}},
    {'user':'woshijinya','password': 'lemonbanpy30','check':{"code": 1, "msg": "账号或密码不正确"}}
]

@ddt.ddt
class TestLogin(unittest.TestCase):         # 定义测试类,继承unittest.TestCase
# 第一种使用ddt:
    @ddt.data(*datas)   # 拆包传参
    def test_0_succ(self,case):    # 顶一个变量接收
        res = login_check(case['user'],case['password'])    # 给与测试数据账号与密码
        self.assertEqual(res,case['check'])   # 断言:判断预期结果与实际结果是否一致

# 第二种使用for循环:
#     def test_lo(self):
#         for data in datas:
#             res = login_check(data['user'], data['password'])  # 给与测试数据账号与密码
#             self.assertEqual(res, data['check'])  # 断言:判断预期结果与实际结

    @classmethod   # 装饰器,声明为类方法
    def setUpClass(cls):   # 这是类方法,意思是继承了类,这里重写了,只会执行一次
        print('*********** TestLogin类下面的用例开始执行 ************')

    @classmethod   # 装饰器,声明为类方法
    def tearDownClass(cls):   # 这是类方法,意思是继承了类,这里重写了,只会执行一次
        print('*********** TestLogin类下面的用例结束执行 ************')

    def setUp(self):       # 这是前置条件,定义了每个测试用例都会执行
        print('======= 单个用例开始执行 ========')

    def tearDown(self):    # 这是后置条件,定义了每个测试用例都会执行
        print('======= 单个用例结束执行 ========')

    # def test_1_error_password(self):   # 错误的密码登录
    #     res1 = login_check('woshijinyao300', 'lemonbanpy')       # 给与测试数据,正确的账号与错误的密码
    #     self.assertNotEqual(res1, {"code": 1, "msg": "账号或密码不正确"})  # 断言:判断预期结果与实际结果是否一致
    #
    # def test_2_error_account(self):    # 错误的账号登录
    #     res2 = login_check('woshijinyao', 'lemonbanpy30')      # 给与测试数据,错误的账号与正确的密码
    #     self.assertEqual(res2, {"code": 1, "msg": "账号或密码不正确"})  # 断言:判断预期结果与实际结果是否一致
    #
    # def test_3_no_account(self):       # 账号为空
    #     res3 = login_check('lemonbanpy30')       # 给与测试数据,空的账号与正确的密码
    #     self.assertEqual(res3, {"code": 1, "msg": "所有的参数不能为空"})  # 断言:判断预期结果与实际结果是否一致
    #
    # def test_4_no_password(self):    # 密码为空
    #     res4 = login_check('woshijinyao300')  # 给与测试数据,正确的账号与空密码
    #     self.assertEqual(res4, {"code": 1, "msg": "所有的参数不能为空"})  # 断言:判断预期结果与实际结果是否一致



2.getter_main.py文件
'''
==================================
cooding:utf-8
@Time    :2020/6/13 9:22
@Author  :henry
@Email   :yinpingwei@gmail.com
@File    :getter_main.py
@Software:PyCharm
===================================
'''
# 1.用例收集

# 引入unittest单元测试
import unittest

# 导入(from 包名.模块名 import 函数/变量)
from class_work_two.test_1_login import TestLogin   # 第一个用例
from class_work_two.test_0_modex import TestDemo    # 第二个用例

# 方法一:
# 1.实例化套件TestSuite
# s = unittest.TestSuite()

# 有2个方法,了解下就好
# 添加一个用例   格式是:函数名(用例名称)
# s.addTest(TestLogin('test_success'))
# 添加一个测试用例的列表
# s.addTests([TestLogin('test_success'),TestLogin('test_error_password')])

# 方法二:
# 2.实例化套件TestLoader
# 从start_directory这个目录下开始,搜索所有的目录,搜索所有的测试用例,并加载到测试套件中
# 搜索标准:
# 1.从指定目录
# 2.文件过滤标准:以文件名匹配,test*.py的文件
# 3.在文件当中去过滤用例:继承了unittest.TestCase类的测试类,类当中以test_开头的测试函数
s = unittest.TestLoader().discover(r'E:\Python-workspace\py30')   # 搜索目录
print(type(s))   # 类型是:<class 'unittest.suite.TestSuite'>
print(s)


# 2.TextTestRunner(执行用例+生成测试报告)

# 第一种:TextTestRunner模块
# 运行测试用例并生成结果
# runner = unittest.TextTestRunner()  # 调用函数
# runner.run(s)    # 生成结果

# 第二种:HtmlTestRunner模块
# 运行测试用例并生成结果
# 导入这个包
from HTMLTestRunnerNew import HTMLTestRunner
# 创建一个html文件,以写入的模式打开,支持中文
with open('report.html','wb') as fs:
    # 运行测试用例,将结果写入html当中
    runner = HTMLTestRunner(fs,title='py30期单元测试报告',tester='henry')   # 实例化之后运行这个对象.可以指定给参数
    runner.run(s)    # 调用run方法

# 第三种:BeautifulIReport模块
# 导入这个包
# from BeautifulReport import BeautifulReport
# 实例化之后运行这个对象
# br = BeautifulReport(s)
# 给到名称和创建html文件
# br.report('py30单元测试报告','br_report.html')

3.login.py文件
'''
==================================
cooding:utf-8
@Time    :2020/6/138:35 
@Author  :henry
@Email   :yinpingwei@gmail.com
@File    :login.py
@Software:PyCharm
===================================
'''

# 功能逻辑
def login_check(username=None, password=None):
    """ 登录校验的函数
    :param username: 账号
    :param password: 密码
    :return: dict type
    """
    if username != None and password != None:
        if username == 'woshijinyao300' and password == 'lemonbanpy30':
            return {"code": 0, "msg": "登录成功"}
        else:
            return {"code": 1, "msg": "账号或密码不正确"}
    else:
        return {"code": 1, "msg": "所有的参数不能为空"}

'''
1.账号密码正确
入参:账号:woshijinyao300     密码:lemonbanpy30
预期结果:{"code": 0, "msg": "登录成功"}
实际结果:

2.账号正确,密码错误
入参:账号:woshijinyao300     密码:lemonban
预期结果:{"code": 1, "msg": "账号或密码不正确"}
实际结果:

3.账号错误,密码正确
入参:账号:woshijinya       密码:lemonbanpy30
预期结果:{"code": 1, "msg": "账号或密码不正确"}
实际结果:

4.账号为空
入参:账号为空          密码:lemonbanpy30
预期结果:{"code": 1, "msg": "所有的参数不能为空"}
实际结果:

5.密码为空
入参:账号:woshijinyao300     密码为空
预期结果:{"code": 1, "msg": "所有的参数不能为空"}
实际结果:

'''

# s = login_check("python27","lemonban")
# # 比对期望和实际
# if s == {"code": 0, "msg": "登录成功"}:
#     print("用例通过!")
# else:
#     print("用例失败!")
#
#
# s = login_check("python27","lemonban")
# # 比对期望和实际
# if s == {"code": 0, "msg": "登录成功。。"}:
#     print("用例通过!")
# else:
#     print("用例失败!")

# 用例之间是独立的。你失败或者成功,跟另外一个用例的执行+结果都是没有关系的。


4.test_0_modex.py文件
'''
==================================
cooding:utf-8
@Time    :2020/6/139:13 
@Author  :henry
@Email   :yinpingwei@gmail.com
@File    :test_0_modex.py
@Software:PyCharm
===================================
'''
import unittest

class TestDemo(unittest.TestCase):

    def test_hello(self):
        self.assertTrue(True)

if __name__ == '__main':    # 单独想要运行这个文件
    unittest.main()


在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值