unittest框架
1)测试固件,Test Fixture
1)对一个测试用例环境的搭建和销毁,就是一个fixture,通过覆盖setUp()和tearDown()方法来实现
2)setUp()方法可以进行测试环境的搭建,比如获取待测试浏览器的驱动,或者如果测试中需要访问数据库,那么可以在setUp()中通过建立数据库连接来进行初始化。
3)tearDown()方法进行环境的销毁,可以进行关闭浏览器,关闭数据库连接,清除数据库中产生的数据等操作1)setUp()是用来初始化测试环境所做的工作,做一些测试用例前的准备工作,设置全局变量
2)tearDown()是用来清理环境所做的工作,做测试用例的执行完,测试环境的清理工作,比如说关闭浏览器,清除缓存,重新实例化环境和数据
备注:执行每一个测试用例之前都是需要先执行setUp()方法,每一个测试用例执行完成之后都需要执行tearDown()方法;
2)Test Case就是类里面的测试方法
使用def进行声明函数,并且方法以test_开头
3)测试套件
测试套件就是把多个测试用例放在一起执行,这里面的多个测试用例可能是一个类里面的所有的测试用例,也有可能是不同的类里面,不同的文件里面的测试用例
4)测试用例的要以test_开头
Test Runner
测试的执行也是非常重要的一个概念,在unittest框架中,通过TextTestRunner类提供的run()方法来执行test suite/test case5)如何使用unittest框架
只需要在脚本中定义一个类,继承于unittest.TestCase即可
verbosity是一个选项,表示测试结果的信息复杂度,有0、1、2 三个值 0 (静默模式): 你只能获得总的测试用例数和总的结果 比如 总共10个 失败2 成功8 1 (默认模式): 非常类似静默模式 只是在每个成功的用例前面有个“.” 每个失败的用例前面有个 “F” 2 (详细模式):测试结果会显示每个测试用例的所有相关的信息
创建两个类进行测试:
from selenium import webdriver import unittest import time import os class Baidu1(unittest.TestCase): # 测试固件 def setUp(self): print("-----setUp----") self.driver=webdriver.Edge("C://Users//18947//AppData//Local//Programs//Python//Python310//msedgedriver.exe") self.url="http://www.baidu.com/" self.driver.maximize_window() time.sleep(3) def tearDown(self): print("------tearDown----") self.driver.quit() # 测试用例 忽略测试用例的执行 # @unittest.skip("skipping") def test_hao(self): driver=self.driver url=self.url driver.get(url) driver.find_element_by_link_text("hao123").click() time.sleep(3); def test_hbaidu(self): driver=self.driver url=self.url driver.get(url) driver.find_element_by_id("kw").send_keys("突如其来的假期") time.sleep(3) driver.find_element_by_id("su").submit() print(driver.title) self.savescreenAsPhoto(driver,".jpg") time.sleep(5) def savescreenAsPhoto(self,driver,file_name): if not os.path.exists("./image"): os.makedirs("./image") now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time())) driver.get_screenshot_as_file("./image/"+now+"-"+file_name) time.sleep(3) if __name__ == "__main": unittest.main()
# coding = utf8 from selenium import webdriver import unittest import time # 导入By模块 from selenium.webdriver.common.by import By from selenium.common.exceptions import NoAlertPresentException from selenium.common.exceptions import NoSuchElementException class TestBaiduTwo(unittest.TestCase): def setUp(self): #获得浏览器的驱动 self.driver=webdriver.Chrome() #让浏览器窗口最大化 self.driver.implicitly_wait(3) self.base_url="http://www.baidu.com/" self.driver.maximize_window() self.array=[] self.flag = True def tearDown(self): self.driver.quit() self.assertEqual([],self.array) def test_hao(self): driver=self.driver driver.get(self.base_url) driver.find_element_by_link_text("新闻").click() time.sleep(3) def test_baidusearch(self): driver=self.driver driver.get(self.base_url) driver.find_element_by_id("kw").clear() driver.find_element_by_id("kw").send_keys("庆余年") driver.find_element_by_id("su").click() #选择通过什么方式来进行获取元素,value是什么属性 self.is_element_present(By.ID, "su").click() time.sleep(3) def is_element_present(self,how,what): try: element=self.driver.find_element(by=how,value=what) except NoSuchElementException as e: return element return element def is_alert_present(self): try: self.driver.switch_to.alert() except NoAlertPresentException as e: return False return True def close_alert_and_get_its_text(self): try: #获取到alert弹出框 alert=self.driver.switch_to_alert() #获取到alert弹出框中的文字 alert_text=alert.text if self.flag: alert.accept() else: alert.dismiss() return alert_text finally:self.flag = True if __name__ == "__main__": unittest.main(verbosity=2)
1)以test_开头命名的方法,是测试方法,在运行整个类的时候会默认执行。
2)unittest提供了全局的main()方法,使用它可以方便地将一个单元测试模块变成可以直接运行的测试脚本main()方法搜索所有包含在该模块中以”test"命名的测试方法,并自动执行他们
unittest里面有四个很重要的概念,test fixture,test case,test suite,test runner
Test Fixture
1)对一个测试用例环境的搭建和销毁,就是一个fixture,通过覆盖setUp()和tearDown()方法来实现,setUp()方法可以进行测试环境的搭建,比如获取待测试浏览器的驱动,或者如果测试中需要访问数据库,那么可以在setUp()中通过建立数据库连接来进行初始化
2)tearDown()方法进行环境的销毁,可以进行关闭浏览器,关闭数据库连接,清除数据库中产生的数据等操作;
Test Case
一个TestCase的实例就是一个测试用例,测试用例就是一个完整的测试流程,包括测试前准备环境的搭建(setUp)实现测试过程的代码,以及测试后环境的还原(tearDown)单元测试(unit test)的本质就在这里一个测试用例,就是一个完整的测试单元,可以对某一个功能进行验证TestSuite
一个功能的验证往往需要多个测试用例,可以把多个测试用例集合在一起执行,这个就产生了测试套件TestSuite的概念,Test Suit用来将多个测试用例组装在一起;
test Runner
test Runner测试的执行也是非常重要的一个概念,在unittest框架中,通过TextTestRunner类提供的run()方法来执行test suite/test case
addTest()
1)TestSuite类的addTest()方法可以把不同的测试类中的测试方法组装到测试套件中,但是addTest()一次
2)只能把一个类里面的一个测试方法组装到测试套件中但是上述做法有两个不方便的地方,阻碍脚本的快速执行,必须每次修改testsuite.py:
1)需要导入所有的相关的py文件,比如 import testbaidu1,每新增一个脚本就需要导入一个
2)addTest一次只能增加一个测试方法,如果一个py文件中有10个测试方式,如果都要组装到测试套件中,就需要增加10次import unittest import TestBaiduOne import TestBaiduTwo def createsuite(): suite = unittest.TestSuite() suite.addTest(TestBaiduOne.Baidu1("test_hao")) suite.addTest(TestBaiduTwo.Baidu2("test_baidusearch")) suite.addTest(TestBaiduTwo.Baidu2("test_hao")) return suite if __name__=="__main__": suite= createsuite() runner=unittest.TextTestRunner(verbosity=2) runner.run(suite)
跑测试套件用例步骤:
1)先进行生成测试套件
2)得到跑测试套件的runner
3)用runner去跑测试套件
1)把一个类中的所有测试用例都添加到一个测试套件里面
1)使用unittest.makeSuite()
def createsuite(): suit=unittest.TestSuite suit.addTest(unittest.makeSuite(TestBaiduOne.Baidu1)) suit.addTest(unittest.makeSuite(TestBaiduTwo.Baidu2)) return suite if __name__=="__main__": suite= createsuite() runner=unittest.TextTestRunner(verbosity=2) runner.run(suite)
2)suite=unittest.TestLoader().loadTestsFromTestCase(python文件名字.类名)
# -*- coding: utf-8 -*- import unittest,csv import os,sys import time import testbaidu1 import testbaidu2 #手工添加案例到套件, def createsuite(): #1.将测试用例加入到测试容器(套件)中 suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(testbaidu1.Baidu1)) suite.addTest(unittest.makeSuite(testbaidu2.Baidu2)) return suite #2.将测试用例放入到测试容器(套件)中 suite1 = unittest.TestLoader().loadTestsFromTestCase(testbaidu1.Baidu1) suite2 = unittest.TestLoader().loadTestsFromTestCase(testbaidu2.Baidu2) suite = unittest.TestSuite([suite1, suite2]) return suite ''' if __name__=="__main__": suite=createsuite() runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
2)把一个文件夹下以某种形式命名的所有文件中的测试用例都加载到测试套件中
可以把一个文件夹下面的所有的测试脚本中的测试用例放在测试套件里面
import unittest def createsuite(): discover=unittest.defaultTestLoader.discover("./TestCase",pattern="TestBaiDu*.py",top_level_dir=None) return discover if __name__=="__main__": suite= createsuite() runner=unittest.TextTestRunner(verbosity=2) runner.run(suite)
测试用例的执行顺序:
1)unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为: 0~9,A~Z,a~z 所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。对于测试
2)对于目录与测试文件来说,unittest 框架同样是按照这个规则来加载测试用例
3)addTest方法按照增加顺序来执行忽略测试用例的执行:
@unnittest.skip("skipping")
为什么要学习断言?为啥要有断言?断言的作用是什么?
1)自动化测试用例是依据于手工测试用例的,测试用例的要素
包括测试环境,测试步骤,测试数据,预期结果(看预期结果和实际结果的对比)
2)如果预期结果和实际结果是一致的,那么测试用例通过,否则测试用例不通过,就是根据测试人员的眼睛和大脑来做判断的,但是在自动化脚本里面就需要用断言来进行判断
3)断言就是测试结果和预期结果的对比,在自动化脚本中判断实际结果和预期结果是否一致
测试用例:打开百度输入框,点击新闻链接
from selenium import webdriver import time import unittest class TestBaiDu(unittest.TestCase): def setUp(self): print("开始执行自动化测试") self.driver=webdriver.Edge("C://Users//18947//AppData//Local//Programs//Python//Python310//msedgedriver.exe") self.baseurl="http://www.baidu.com" self.driver.maximize_window() time.sleep(3) def tearDown(self): print("自动化测试执行完毕") self.driver.quit() def testXinWen(self): self.driver.get(self.baseurl) text=self.driver.find_element_by_link_text("新闻") text.click() time.sleep(3) # 在这里面使用断言 print(self.driver.title) self.assertEqual("百度一下,你就知道",self.driver.title,msg="实际结果和预期结果不一致") if __name__=="__main__": unittest.main(verbosity=2)
常见的断言:
判断实际结果和需求的对比
1)AssertEqual(预期结果,实际结果,异常输出)
2)AssertNotEqual(预期结果,实际结果,异常输出)
3)AssertTrue(实际结果==预期结果,异常信息)
4)assertFalse(预期结果==实际结果,异常信息)
self.assertTrue("百度一下,你就知道"==self.driver.title,msg="预期结果与实际结果相等") self.assertFalse("百度一下,你就知道"==self.driver.title,msg="预期结果与实际结果相等")