UnitTest-单元测试4.11
单元测试是最基本的也是最底层的测试类型,单元测试应用于最基本的软件代码。
测试金字塔:
单元测试的3种维度
1、表单的错误提示信息验证
2、产品的业务逻辑
3、页面的各种交互
在Python中,单元测试框架主要是unittest
unittest属于标准库,只要安装了Python解释器后就可以直接导入使用了
import unittest
一个完整的自动化测试:
初始化 测试步骤 断言 清理
TestCase 测试用例
TestSuite 在一个测试套件里面可以包含很多的测试用例,可以把它理解为一个容器
测试固件:初始化setUp(), 清理tearDown()
TestRunner:测试执行指的是针对测试套件或者是测试用例进行执行的过程
TestReport:所有的测试测试用例执行完成后输出的汇总结果报告信息
每个自动化测试用例必须得有断言 断言本质上其实就是两个对象的比较,在字符串中,两个对象的比较主要是通过:is,in,==的方式里进行的。
每个测试用例前面必须要有测试的信息
类测试固件:指的是不管一个测试类里面有多少个测试用例,测试固件只执行一次
测试固件的缺点:
是执行完一个测试用例后,需要回归到页面的初始化
测试用例的排序:
测试的执行是依据ascill码来执行的,也就是说根据ascill码的顺序加载,数字与字母的顺序为:0-9,A-Z,a-z,所以以A开头的测试用例方法会优先执行,切记数字的大小值的是不包含test,值的是test后面的测试点的数字大小
测试用例的编写规则:
在自动话测试用例中,编写的测试用例不需要刻意的进行排序,让测试框架内部框架按照它的排序规则去执行。切记:编写的每个自动化测试用例都必须是独立的,和其他的测试用例之间没有任何的依耐性
自动化测试的流程:
1、先梳理哪模块可以做自动化测试
2、梳理完成后,和相关的人建议对下计划以及梳理的结果
3、编写代码实现梳理的测试模块
4、编写完成后,和相关的人进行评审代码(测试场景是否考虑周全,测试断言是否合理,代码编写是否合理)
5、编写完成后,整合到Jekins的持续集成平台
6、下个迭代的时候,直接可以应用于产品的回归测试中
import unittest
from selenium import webdriver
# 测试类集成了unittest模块中的TestCase类,依据继承的这个类来设置一个新的测试用例类和测试方法
class BaiduText(unittest.TestCase):
# 初始化 测试固件
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(60)
self.driver.get('https://www.baidu.com/')
# 清理 测试固件
def tearDown(self) -> None:
self.driver.quit()
def test_baidu_title(self):
# 验证百度首页的title 信息
assert self.driver.title=='百度一下,你就知道'
if __name__ == '__main__':
unittest.main()
import unittest
from selenium import webdriver
import time as t
class SinaTest(unittest.TestCase):
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(30)
self.driver.get('https://mail.sina.com.cn/')
def tearDown(self) -> None:
self.driver.quit()
def test_login_null(self):
# 登陆:验证登陆密码为空的错误提示信息
self.driver.find_element_by_id('freename').send_keys('')
self.driver.find_element_by_id('freepassword').send_keys('')
self.driver.find_element_by_class_name('loginBtn').click()
t.sleep(5)
divTest=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
# assertEqual 断言的一种比较2个对象是否相等
self.assertEqual(divTest.text,'请输入邮箱名')
def test_login_email_format(self):
# 验证登陆格式规范的错误提示信息
self.driver.find_element_by_id('freename').send_keys('qwe')
self.driver.find_element_by_id('freepassword').send_keys('asd123')
self.driver.find_element_by_class_name('loginBtn').click()
t.sleep(5)
divTest=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
# assertIn比较一个对象是否包含另外一个对象
self.assertIn(divTest.text,'您输入的邮箱名格式不正确')
def test_login_isButton(self):
# 验证自动登陆是否默认勾选
divTest=self.driver.find_element_by_id('store1')
#针对bool类型的验证 assertTrue 与 assertFalse is_selected() 判断是否勾选
# divTest.click()
# self.assertFalse(divTest.is_selected())
self.assertTrue(divTest.is_selected())
if __name__ == '__main__':
# 测试套件 按测试类来执行
# suite=unittest.TestLoader.loadTestsFromTestCase(testCaseClass='SinaTest')
# 按测试模块来执行
suite=unittest.TestLoader.loadTestsFromModule(module='自己练习页面.py')
unittest.TextTestRunner.run(suite)
# unittest.main()
# 测试固件
# class BaiduTest(unittest.TestCase):
# # 初始化
# @classmethod
# def setUpClass(cls) -> None:
# cls.drvice=webdriver.Chrome()
# cls.drvice.maximize_window()
# cls.drvice.get('https://mail.sina.com.cn/')
# cls.drvice.implicitly_wait(30)
# # 清理
# @classmethod
# def tearDownClass(cls) -> None:
# cls.drvice.quit()
# # 测试运行
#
# def test_login_null(self):
# self.drvice.refresh()
# # 验证登陆;验证账户密码为空的错误提示信息
# self.drvice.find_element_by_id('freename').send_keys('')
# self.drvice.find_element_by_id('freepassword').send_keys('')
# self.drvice.find_element_by_class_name('loginBtn').click()
# t.sleep(3)
# divTest=self.drvice.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
# # assertEqual比较两个对象是否相等,==
# self.assertEqual(divTest.text,'请输入邮箱名')
#
# def test_login_email_format(self):
# # 登陆:验证账户格式不规范的错误提示信息
# self.drvice.find_element_by_id('freename').send_keys('1234')
# self.drvice.find_element_by_id('freepassword').send_keys('asd')
# self.drvice.find_element_by_class_name('loginBtn').click()
# t.sleep(3)
# divTest=self.drvice.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
# self.assertEqual(divTest.text,'您输入的邮箱名格式不正确')
#
#
#
# if __name__=='__main__':
# unittest.main()
参数化:
相同的测试步骤,不同的测试数据,那么这样测试场景我们就可以使用参数化的思路解决思路。也是说使用一个测试用例的代码,执行多个测试场景
参数化的本质:
针对测试数据进行循环,每次循环的时候对列表中的元素的值一一赋值的过程
import time as t
from selenium import webdriver
import unittest
from parameterized import parameterized,param
class SinaTest(unittest.TestCase):
# 初始化
def setUp(self) -> None:
self.drvice=webdriver.Chrome()
self.drvice.maximize_window()
self.drvice.get('https://mail.sina.com.cn/')
self.drvice.implicitly_wait(30)
# 清理
def tearDown(self) -> None:
self.drvice.quit()
@parameterized.expand([
param('','','请输入邮箱名'),
param('asd','123qwe','您输入的邮箱名格式不正确'),
param('sdfgg@sina.com','asdaqww','登录名或密码错误')
])
def test_login(self,username,password,result):
# 登陆:测试登陆不同场景
self.drvice.find_element_by_id('freename').send_keys(username)
self.drvice.find_element_by_id('freepassword').send_keys(password)
self.drvice.find_element_by_class_name('loginBtn').click()
t.sleep(3)
divTest=self.drvice.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
# assertEqual比较两个对象是否相等,==
self.assertEqual(divTest.text,result)
if __name__ == '__main__':
unittest.main()
import HTMLTestRunner
import unittest
import os
import time
# if __name__ == '__main__':
# # 加载所有的测试模块来执行
# # start_dir:测试模块的路径
# #pattern:通过正则的方法加载所有的测试模块
# # print(os.path.dirname(__file__))
# suite=unittest.TestLoader().discover(
# start_dir=os.path.dirname(__file__),
# pattern='test_*.py')
# unittest.TextTestRunner().run(suite)
def getSute():
suite=unittest.TestLoader().discover(
start_dir=os.path.dirname(__file__),
pattern='test_*.py')
return suite
def getNowTime():
return time.strftime('%y-%m-%d %H_%M_%S',time.localtime(time.time()))
def main():
filename=os.path.join(os.path.dirname(__file__),'report',getNowTime()+'report.html')
# filename = os.path.join(os.path.dirname(__file__), 'report','report.html')
fp=open(filename,'wb')
runner=HTMLTestRunner.HTMLTestRunner(
stream=fp,
title='UI自动化测试报告',
description='UI自动化测试报告'
)
runner.run(getSute())
if __name__ == '__main__':
main()
作业:针对注册页3个模拟测试
import time as t
import unittest
from selenium import webdriver
class Sina_register(unittest.TestCase):
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('https://mail.sina.com.cn/register/regmail.php')
self.driver.implicitly_wait(30)
def tearDown(self) -> None:
self.driver.quit()
def test_register_address_null(self):
# 注册:验证邮箱名为空的错误提示信息
self.driver.find_element_by_name('email').send_keys('')
t.sleep(5)
divTest=self.driver.find_element_by_xpath('/html/body/div[2]/div/div/div/div/form[1]/div[2]/ul/li[1]/div[3]/p/abbr')
self.assertEqual(divTest.text,'4-16个字符,可使用英文小写、数字、下划线,下划线不能在首尾')
def test_register_email_format(self):
# 注册:验证邮箱名错误的提示信息
self.driver.find_element_by_name('email').send_keys('asd')
self.driver.find_element_by_link_text('立即注册').click()
t.sleep(5)
divTest=self.driver.find_element_by_class_name('tipInfor')
self.assertEqual(divTest.text, '邮箱名必须是4-16个字符之间(包括4、16)')
def test_register_isButton(self):
# 注册:验证注册页面是否默认勾选
divText=self.driver.find_element_by_id('agreement1')
# divText.click()
# 针对bool类型的验证 assertTrue 与 assertFalse
self.assertFalse(divText.is_selected())
# self.assertTrue(divText.is_selected())
if __name__ == '__main__':
unittest.main()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律