用简易的unittest框架做自动化测试

用简易的unittest框架做自动化测试,第1张

1.unitest核心有5层,

case:写用例;data:放数据;utils:放工具;setting做设置;runner做运行。

各层之间的关系:

setting:拿到根目录后,再到utils里面去做拼接,并且定义读写方法。

import os
from os.path import dirname  #dirname是找到根目录的一种方法。
BASE_PATH=dirname(__file__)
if __name__=="__main__":
    print(BASE_PATH)

#还有另外一种方法拿到根目录
#import os
#dirname,filename=os.path.split(__file__)
#BASE_PATH=dirname
#if __name__=="__main__":
#    print(BASE_PATH)

utils:定义读写,并且做csv文件拼接。

from settings import BASE_PATH

class Util:
 
    @classmethod            
    def get_data_from_csv(cls, path): 
        '''
        读取csv文件中的数据
        :return:
        '''
        data = []
        with open(path, 'r', encoding='utf8') as f:
            for line in f:
                test_data = line.strip().split(',')  
       '''将csv中的内容以行隔开,并且以“,”隔开,建立列表'''
                data.append(test_data)
        return data

    @classmethod
    def get_data_from_db(cls):
        '''
        读取数据库内的数据
        :return:
        '''
        ...

if __name__ == '__main__':          
'''if__name__=='__main__'可不写的,它的作用是,让下面的代码在本文件中自动运行,别的文件导入该模块,就不会再自动运行。这里写出来,可当作是解释该如何用。'''
    print(Util.get_data_from_csv(BASE_PATH + '/data/login.csv'))

data数据,以逗号隔开。再在case中用util的方法读取data的数据,再用ddt解包,加到

case,用例,用ddt做数据驱动,并用unpack解包data里的内容,依次传参。


import unittest    # 导入unittest框架, 托管框架
from selenium import webdriver
from ddt import ddt, data, unpack
from utils.utils import Util
from settings import BASE_PATH

'''
1. 定义一个继承于unittest.TestCase的类
2。定义测试方法。测试方法必须以test开头,并且每个测试类文件必须至少有一个测试方法。
3. 测试类和测试方法和测试用例对应关系。比如3个模块,每个模块有10条用例,请问应该写多少个测试类,多少个测试方法?
测试用例 -> 测试方法,功能模块 -> 测试类.
4. 在一个测试类或者一个测试方法中,只能包含测试代码,其他任何跟测试无关的 *** 作代码,不能放在测试文件中。
'''

@ddt                                             #导入ddt
class LoginTest(unittest.TestCase):
    def setUp(self):
        '''
        在每个测试方法运行之前会被自动调用一次,它的作用主要用来进行测试的初始化 *** 作,比如初始化driver、数据库连接
        :return:
        '''
        # print('进入了setup方法')
        self.driver = webdriver.Chrome()          #先打开chrome浏览器
        self.driver.implicitly_wait(10)             #暂停10秒
        self.driver.get('http://www.taobao.com/mms/login.html')  # 打开被测页面
        self.imgs = []    # 定义一个专门用于存放报告截图的列表,列表名字必须是imgs
    def tearDown(self):
        '''
        在每个测试方法运行之后会被自动调用一次,它的作用主要用来进行测试的清理 *** 作,比如关闭浏览器窗口、断开数据库连接
        :return:
        '''
        # print('进入了teardown方法')
        self.driver.quit()    # 退出浏览器

    def add_pic(func):            #做一个当断言错误时截图的装饰器。为什么要封装成装饰器?后面可以直接调用装饰器修饰函数。
        def inner(self):
            try:
                func(self)
            except AssertionError:
                self.imgs.append(self.driver.get_screenshot_as_base64())   #driver.get_screenshoot_as base64(),电脑64位截图。
                raise
        return inner

    @add_pic                #调用add_pic装饰器
    def test_login_success(self):
        '''
        定义一个测试方法,所有的测试方法都必须以小写的test开头
        使用正确的用户名和正确的密码,验证是否能够正确登陆
        :return:
        '''
 

    # @data(
    #     ('admin', '', 'password不能为空'),
    #     ('', 'admin123', 'User Id不能为空'),
    #     ('admin', 'admin', '密码错误'),
    #     ('adminx', 'admin123', '没有此用户')
    # )

    @data(*Util.get_data_from_csv(BASE_PATH + '/data/login.csv'))     #调用ddt里面的data,再调用util里面的get_data_from_csv方法获取数据。*表示解包
    @unpack  #再解包一次,分别传参
    def login_failed_1(self, username, password, exp_msg): #三个参数
        '''
        使用正确的用户名和错误的密码,系统应提示密码错误
        :return:
        '''
        self.driver.find_element('id', 'username').send_keys(username)   #所有被读取的参数用形参名即可。
        self.imgs.append(self.driver.get_screenshot_as_base64())
        self.driver.find_element('id', 'password').send_keys(password)
        self.imgs.append(self.driver.get_screenshot_as_base64())   #将截图放到列表
        self.driver.find_element('xpath', "//input[@value='Login']").click()

        actual_msg = self.driver.find_element('xpath', "//div[contains(@class, 'messager-body')]/div[1]").text
        self.imgs.append(self.driver.get_screenshot_as_base64())
        self.assertEqual(exp_msg, actual_msg)        #断言预期结果是否与实际结果一致。
 
    

'''
如何调用测试类来进行测试?有两种方法
一、直接在测试类当前文件通过普通的python文件方式运行unittest.main()方法
二、在其他py文件中以testrunner的方式运行
'''
if __name__ == '__main__':
    print('开始执行unittest框架测试')
    unittest.main()     # 调用unittest的main方法来执行当前测试类的所有测试方法

 run:运行所有文件,并且生成报告。

import unittest, time
from HTMLTestRunner_cn import HTMLTestRunner
from settings import BASE_PATH
import os

if __name__ == '__main__':
    case_dir = '.'   # 指定要运行的测试文件的路径
    dis = unittest.defaultTestLoader.discover(case_dir, pattern='ut_demo.py')  #通过discover()方法实现自动化用例管理,解决批量执行测试脚本的问题
    suite = unittest.TestSuite(dis)     # 根据搜索到的测试方法,组成一个测试集
    # unittest.TextTestRunner().run(suite)    # 调用TextTestRunner执行所有的测试

    # 根据年月日时分秒来生成测试报告
    ymd = time.strftime("%Y%m%d", time.localtime(time.time()))   # 利用当前时间戳,生成年月日    运行结果是20220520这种格式。还有另外一种稍微简单的方法。ymd = time.strftime("%Y%m%d", time.localtime() ,运行结果是一样的
    hms = time.strftime("%H%M%S", time.localtime(time.time()))   # 利用当前时间戳,生成时分秒

    report_path = BASE_PATH + r'\reports\report_{}'.format(ymd)  #建立一个报告存放路径,格式时report_20220520这样的。

    if not os.path.exists(report_path):
        # 创建文件夹
        os.makedirs(report_path)  #makedirs,创建文件夹。

    # 生成htmltestrunner测试报告
    runner = HTMLTestRunner(
        title="自动化测试报告v1.0",
        description="3月份测试结果汇总报告",
        stream=open(report_path + r'\test_{}.html'.format(hms), 'wb'),  #报告生成并写入test_时分秒.html中。
        verbosity=2,     #冗长,1是默认模式,只有.和F,2会显示每个用例的所有相关信息。
        # retry=2,
        # save_last_try=True
    )
    runner.run(suite)

补充说明:

一.断言方法:

assertIn assertNotIn assertEqual assertNotEqual  (期待值in实际值,期待值notin实际值,期待值与实际值相等,期待值与实际值不相等)

二.在unittest框架中使用参数化(数据驱动):

1. 安装ddt:pip install -i https://pypi.douban.com/simple ddt 2. ddt框架的使用,一般会通过辅助方法的形式从指定数据源获取数据。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/916546.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存