单元测试框架、参数化、测试报告
一、单元测试框架——unittest
1、自动化测试的三个维度
1.1、表单的错误提示信息验证
1.2、产品业务逻辑的验证
1.3、页面的各种交互
2、单元测试是
代码为:import unittest
自动化测试的方法是由unittest库下的TestCase类提供的,所以我们写自动化测试用例前必须继承unittest库中的TestCase类。
二、测试用例
2.1、TestSuite
在一个测试套件里面可以包含很多的测试用例,可以把它理解为一个容器
2.2、测试固件
初始化setUp(),清理tearDown()
2.3、TestRunner
测试执行指的是针对测试套件或者是测试用例进行执行的过程
2.4、TestReport
所有的测试测试用例执行完成后输出的汇总结果报告信息
实战操作
以百度为例
from selenium import webdriver import unittest class BaiduTes(unittest.TestCase): def setUp(self) -> None: self.driver=webdriver.Chrome() self.driver.maximize_window() self.driver.get("http://www.baidu.com") self.driver.implicitly_wait(60) def tearDown(self) -> None: self.driver.quit() # 验证断言 def test_baidu_title(self): assert self.driver.title=="百度一下,你就知道" #main():执行测试类中的所有测试用例 if __name__=='__main__': unittest.main()
以新浪邮箱为例:
from selenium import webdriver import unittest import time class SinaTest(unittest.TestCase): def setUp(self) -> None: self.driver=webdriver.Chrome() self.driver.maximize_window() self.driver.get("https://mail.sina.com.cn/") self.driver.implicitly_wait(60) 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() time.sleep(4) divText=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比较两个对象是否相等== self.assertEqual(divText.text,'请输入邮箱名') def test_login_email_format(self):
'''登录:验证账户格式不规范的错误提示信息''' self.driver.find_element_by_id("freename").send_keys("wrnryf") self.driver.find_element_by_id("freepassword").send_keys("sfevg") self.driver.find_element_by_class_name('loginBtn').click() time.sleep(4)
divText=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]") self.assertEqual(divText.text,"您输入的邮箱名格式不正确") if __name__ =="__main__": unittest.main()
3、四种方法:
assertEqual:assertEqual比较两个对象是否相等==
assertIn:比较一个对象是否包含另一个对象in
assertTrue:针对bool类型验证true
asssertFalse:针对bool类型验证false
注意事项:在标题中任意位置右键执行都会仅执行这一个用例,如:def test_login_email_format(self)
类测试固件:指的是不管一个测试类里面有多少个测试用例,测试固件只执行一次
缺点是执行完一个测试用例后,需要回归到页面的初始化
1、在一个测试类里面,每一个测试方法都是以test开头的,test不能在中间或者尾部,必须是开头,建议代码显示为:test_
2、每个测试用例方法都应该名字,也就是有释放信息,这样在测试报告就会显示具体测试点的检查点
3、在自动化测试中,每个测试用例都必须有断言,没有的话表示无效
4、最好一个测试用例方法对应一个业务测试点,不要多个业务检查点写一个测试用例
6、测试用例名称必须规范有约束
5.1、先梳理哪些模块可以做自动化测试
5.2、梳理完成后,和相关的人建议对下计划以及梳理的结果
5.3、编写代码实现梳理的测试模块
5.4、编写完成后,和相关的人进行评审代码(测试场景是否考虑周全,测试断言是否合理,代码编写的是否合理)
5.5、编写完成后,整合到Jekins的持续集成平台
5.6、下个迭代的时候,直接可以应用于产品的回归测试中
6、测试套件
测试套件顾名思义就是相关测试用例的集合。在unittest中主要通过TestSuite类提供对测试套件的支持,执行测试套件用的方法是unittest库下的TextTestRunner()类中的run的方法
6.2、按测试模块执行
import unittest import os if __name__ =="__main__": # 加载所有的测试模块来执行 # start_dir:测试模块的路径 # pattern:通过正则的方式加载所有的测试模块 suite = unittest.TestLoader().discover( start_dir=os.path.dirname(__file__), pattern='test_*.py') unittest.TextTestRunner().run(suite)
6.3、加载所有模块执行
import os import unittest #加载所有的测试模块来执行 #第一种方式: if __name__=="__main__": #start_dir=加载所有的测试模块来执行,pattern通过正则的方式获取到 suite = unittest.TestLoader().discover(start_dir=os.path.dirname(__file__),pattern="test_*.py") unittest.TextTestRunner().run(suite) #第二种方式: def getSuite(): suite = unittest.TestLoader().discover(start_dir=os.path.dirname(__file__), pattern="test_*.py") return suite
if __name__ == '__main__': unittest.TextTestRunner().run(getSuite())
三、参数化
1、参数化
相同的测试步骤,不同的测试数据,那么这样的测试场景我们就可以使用参数化的解决思路来解决。也就是说使用一个测试用例的代码,执行多个测试场景
2、参数化本质:
import unittest from parameterized import parameterized,param from selenium import webdriver import time class SinaTest(unittest.TestCase): def setUp(self)->None: self.driver=webdriver.Chrome() self.driver.maximize_window() self.driver.get("https://mail.sina.com.cn/") self.driver.implicitly_wait(30) def tearDown(self) -> None: self.driver.quit() @parameterized.expand([ param('','','请输入邮箱名'), param('wev','wfg','您输入的邮箱名格式不正确'), param('seefg@sina.com','srbv','登录名或密码错误')]) def test_login(self,w,p,t): # 登录:测试登录不同场景 self.driver.find_element_by_id("freename").send_keys(w) self.driver.find_element_by_id("freepassword").send_keys(p) self.driver.find_element_by_class_name('loginBtn').click() time.sleep(4) divText=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]") self.assertEqual(divText.text,t) if __name__ =="__main__": unittest.main()
四、测试报告
TestReport:所有的测试测试用例执行完成后输出的汇总结果报告信息。unittest生成测试报告需要使用到第三方的HTMLTestRunner的库,下载该库后,把该库放在Python安装目录下的lib目录下。导入的方法为:import HTMLTestRunner
1、获取测试报告的步骤
(1)在当前测试路径下创建一个report文件夹;
(2)加载所有的测试模块;
(3)获取测试报告
import HTMLTestRunner import os import unittest import time #生成自动化测试报告 #加载所有的测试模块:unittest库下的TestLoader()类中的discover的方法 def getSuite(): suite = unittest.TestLoader().discover(start_dir=os.path.dirname(__file__), pattern="test_*.py") return suite #获取当前时间,由于Python格式的限制,当前时间最好采用下面的方式 def getNowTime(): return time.strftime("%y-%m-%d %H_%M_%S",time.localtime(time.time())) #返回当前测试路径 def base_dir(): return os.path.dirname(__file__) #获取测试报告 def Report(): #定义文件名,定义文件名为当前时间+report.html,主要是为了区分不同时间段生成的测试报告。 filename=os.path.join(base_dir(),"report",getNowTime()+"report.html") #把测试报告写入文件中,b是以二进制的方式写入 fp=open(filename,"wb") runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title="UI自动化测试",description="UI自动化测试测试报告") runner.run(getSuite()) if __name__ == '__main__': Report()
在report文件夹中看到当前时间生成的测试报告
2、查找Python路径