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框架的使用,一般会通过辅助方法的形式从指定数据源获取数据。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)