UI自动化 unittest单元测试框架(1)
一、测试范围:
表单的错误提示信息验证
产品的业务逻辑
页面的各种交互(选项、悬浮)
UI层:可以理解为功能测试;
service:接口测试(API);
Unit(单元测试)。
在Python中,单元测试框架主要是unittest。单元测试是最基本也是最底层的测试类型,单元测试应用于最基本的软件代码,如类,函数、方法等,单元测试通过可执行的断言检查被测单元的输出是否满足预期结果。在测试金字塔的理论上来说,越往下的测试投入资源越高,得到的回报率越大。
unittest属于标准库,只要安装了Python解释器后就可以直接导入使用了import unittest
三、步骤:
初始化 (获取浏览器驱动对象driver,打开网页、最大化浏览器、隐式等待)
测试 步骤
断言
清理(关闭浏览器)
四、单元测试框架包括:
测试用例(TestCase)
测试固件:初始化setUp(),清理tearDown()
测试套件(TestSuite ):组织测试用例。在一个测试套件里面可以包含很多的测试用例,可以把它理解为一个容器。测试用例的集合。
测试执行(TestRunner):测试执行指的是针对测试套件或者是测试用例进行执行的过程
测试报告(TestReport):所有的测试测试用例执行完成后输出的汇总结果报告信息
五、断言:
让程序代替人为判断测试程序执行结果是否符合预期结果的过程。每个自动化测试用例必须得有断言,断言本质上其实就是两个对象的比较。
1.assert为python自带断言方法:

1 import unittest 2 from selenium import webdriver 3 4 class BaiDuTest(unittest.TestCase): 5 def setUp(self) -> None: 6 self.driver=webdriver.Chrome() 7 self.driver.maximize_window() 8 self.driver.get("http://www.baidu.com") 9 self.driver.implicitly_wait(30) 10 11 12 def test_baidu_title(self): 13 '''验证百度首页的title信息''' 14 assert self.driver.title=="百度一下,你就知道" 15 16 if __name__ == '__main__': 17 unittest.main()
在字符串中,两个对象的比较主要是通过: is , in包含 , ==相等 的方式里进行的。
测试用例以test_开头
2.unittest框架中的断言方法:

1 import time 2 import unittest 3 import setuptools.dist 4 from selenium import webdriver 5 6 class SinaTest(unittest.TestCase): 7 def setUp(self) -> None: 8 self.driver=webdriver.Chrome() 9 self.driver.maximize_window() 10 self.driver.get("http://mail.sina.com.cn/") 11 self.driver.implicitly_wait(30) 12 13 def tearDown(self) -> None: 14 self.driver.quit() 15 16 def test_login_email_format(self): 17 '''登录:验证账户格式不规范的错误提示信息''' 18 self.driver.find_element_by_id("freename").send_keys("saffg ") 19 self.driver.find_element_by_id("freepassword").send_keys(" rwerg") 20 self.driver.find_element_by_class_name("loginBtn").click() 21 time.sleep(3) 22 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]") 23 '''assertEqual比较两个对象是否相等,==''' 24 self.assertEqual(divTest.text,"您输入的邮箱名格式不正确") 25 '''assertIn比较一个对象是否包含另外一个对象,in''' 26 self.assertIn(divTest.text,"正确") 27 28 def test_login_isButton(self): 29 '''验证按钮是否被勾选''' 30 divTest=self.driver.find_element_by_id("store1") 31 # divTest.click() 32 time.sleep(2) 33 '''针对bool的类型验证assertTrue''' 34 self.assertTrue(divTest.is_selected()) 35 '''针对bool的类型验证assertFlase''' 36 self.assertFalse(divTest.is_selected()) 37 38 39 if __name__ == '__main__': 40 unittest.main()
(继承unittest下的TestCase类)
① self.assertEqual(A,B)
判断A B两个对象是否相等(类似于字符串的==)。不仅内容相同并且还要类型相同。
(获取文本框的内容和“ ”做比较)
② self.assertIn(a,b)
判断b是否包含a
③assertTrue验证是否为True:如果是True则通过,如果是Flase则不通过
④assertFlase验证是否为假:如果是Flase则通过,如果是True则不通过
在unittest单元测试框架中,测试固件用于处理初始化的操作,例如对百度的搜索进行操作之前,首先需要打开浏览器并且进入到百度首页;测试结束后,需要关闭浏览器。测试固件提供了两种执行形式,一种是每执行一个测试用例,测试固件都会被执行一次;另外一种是不管有多少个测试用例,测试固件只执行一次。
1、测试固件每次均执行
setUp和tearDown
2、测试固件只执行一次
类测试固件:setUpClass和tearDownClass,指的是不管一个测试类里面有多少个测试用例(方法),测试固件只执行一次。需要在方法上面加装饰器@classmethod.
优点:节约了时间。
缺点:执行完一个测试用例后,需要回归到页面的初始化。
(建议使用测试固件setUp和tearDown每次都会打开和关闭浏览器,使得自动化测试用例之间没有关联性,避免一个测试用例执行失败是由上一个测试用例导致。)
六、编写测试用例注意事项
回答写了多少个自动化测试用例: 4-500
1、在一个测试类里面,每一个测试方法都是以test开头的!!!test不能是中间或者尾部,必须是开头,建议test_。
2、每一个测试用例方法都应该有注释信息,这样在测试报告就会显示具体的测试点的检查点
3、在自动化测试中,每个测试用例都必须得有断言,无断言的自动化测试用例是无效的
4、最好一个测试用例方法对应一个业务测试点,不要多个业务检查点写一个测试用例
5、如果涉及到业务逻辑的处理,最好把业务逻辑的处理方法放在断言前面,这样做的目的是不要因为业务逻辑执行错误导致断言也是失败
6、测试用例名称最好规范,有约束
7、是否先写自动化测试的测试代码,在使用自动化测试方式写,本人觉得没必要,毕竟能够做自动化测试的都具备了功能测试的基本水平,所以没必要把一个业务的检查点写多次,浪费时间和人力成本。
七、自动化测试流程:
1、先梳理哪些模块可以做自动化测试
2、梳理完成后,和相关的人(领导)建议核对下计划以及梳理的结果
3、编写代码实现梳理的测试模块
4、编写完成后,和相关的人进行评审代码(测试场景是否考虑周全,测试断言是否合理,代码编写的是否合理)
5、编写完成后,整合到Jekins持续集成平台
6、下个迭代的时候,直接可以应用于产品的回归测试中
八、TestCase测试用例执行顺序详解
在unittest中,测试点的执行顺序是依据ascii码来执行的,也就是说根据ASCII码的顺序加载,数字与字母的顺序为:0-9,A-Z,a-z,所以以A开头的测试用例方法会优先执行,以a开头后执行。也就是根据数字的大小从小到大执行的,切记数字的大小值的是不包含test,指的是test后面的测试点的数字大小。
在自动化测试用例中,编写的测试用例不需要刻意的进行排序,让测试框架内部框架按照它的排序规则去执行。
切记:编写的每一个自动化测试用例都必须是独立的,和其他的测试用例之间没有任何的依赖性。
技巧:在某个测试用例的标题上右键执行,意思是只执行这个测试用例。在类上右键,执行整个类。
九、执行TestSuite测试套件
UnitTest的测试框架中提供了很丰富的测试套件,所谓测试套件其实我们可以把它理解为测试用例的集合,或者可以说理解为一个容器,在这个容器里面可以存放很多的测试用例。
TestLoader类:用来加载TestCase到TestSuite中,即满足条件的测试用例,并把测试用例封装成测试套件(suite)。
分类执行
①按测试类执行
按测试类执行,可以理解为在测试套件中,我们按测试类的方式来进行执行,那么也就不需要在乎一个测试类里面有多少测试用例,我们是以测试类为单位来进行执行,测试类里面有多少的测试用例,我们都会进行执行
②按模块执行
③加载所有的测试模块(重点掌握)
使用unittest.TestLoader类,通过该类下面的discover()方法自动搜索指定目录下指定开头的.py文件,并将查找到的测试用例组装到测试套件(suite)。
两个参数:
star_dir:测试模块的路径(指定目录)
pattern:指定测试模块名(通过*正则的方式,“test_*.py”表示以test_开头的所有模块。所以我们命名测试模块的时候注意格式:test_xxx.py)
执行方法
执行测试套件的方法。
调用类TextTestRunner下的run方法,TextTestRunner后面要带括号表示类实例化。
unittest.TextTestRunner().run(suite)也就是相当于
runner=unittest.TextTestRunner()
runner.run(suite)
一行代码更简洁。
十、参数化:
参数化:
相同的测试步骤,不同的测试数据,那么这样的测试场景我们就可以使用参数化的解决思路来解决。
也就是说使用一个测试用例的代码,执行多个测试场景.
参数化本质:
针对测试数据进行循环,每次循环的时候对列表中的元素的值一一赋值的过程
Parameterized 是 Python 的一个参数化库,同时支持 unittest、Nose 和 pytest 单元测试
框架
cmd中安装pip3 install parameterized
参数化:根据需求动态获取参数并引用的过程。解决相同操作步骤、不同测试数据的问题。
导入包 from parameterized import parameterized;
修饰测试函数@parameterized.expand(列表类型);
在测试函数中使用变量接收传递过来的值,变量的数量必须和数据值的个数相同。
十一、测试报告
执行了测试套件可以看到测试的结果,但是如果希望有一个系统的 完整的测试报告,就需要使用到HTMLTestRunner
11.1 准备工作
1、unittest生成测试报告需要使用到第三方的库HTMLTestRunner,把该库放在Python安装目录下的lib目录下。
2、建report包:用来放测试报告

1 import os 2 import unittest 3 import HTMLTestRunner 4 import time 5 6 def getSuite(): 7 '''获取当前目录下所有需要执行的测试模块''' 8 suite=unittest.TestLoader().discover( 9 start_dir=os.path.dirname(__file__), 10 pattern="test_*.py") 11 return suite 12 13 def getNowTime(): 14 '''获取当前时间,给测试报告命名的时候加上时间,用来区分文件''' 15 return time.strftime("%Y-%m-%d %H-%M-%S",time.localtime()) 16 17 def main(): 18 filename=os.path.join(os.path.dirname(__file__),"report",getNowTime()+"report.html") #定义文件(路径拼接加文件命名) 19 fp=open(filename,"wb") #二进制写入 20 runner=HTMLTestRunner.HTMLTestRunner( 21 stream=fp, 22 title="UI自动化测试报告", 23 description="测试报告" 24 ) #HTMLTestRunner类实例化 对报告进行描述 25 runner.run(getSuite()) #HTMLTestRunner类下的run方法执行 (运行给定测试套件) 26 27 if __name__ == '__main__': 28 main()
11.2步骤:
用到了TestLoader()类的discover()方法,获取当前目录下所有需要执行的测试模块到测试固件;
获取当前时间,用来给测试报告命名;(注意时间格式 命名不能有引号)
对HTMLTestRunner类实例化,进行参数赋值,定义测试报告;
实例化后就可以使用run方法来执行测试套件;
把执行的测试套件结果放入测试报告。
查看测试报告:
(测试用例写注释,测试报告中就会显示)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)