初学unittest测试框架

本文详细介绍了Python的unittest测试框架,包括测试用例(TestCase)、测试套件(TestSuite)、测试固件(TestFixture)、执行测试(TestRunner)和测试报告。通过实例展示了如何组织测试用例执行、创建测试套件、添加断言、忽略用例以及生成HTML测试报告。此外,还讲解了如何捕获异常并截图,以辅助测试过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

unittest测试框架包括哪几部分

unittest是Python的单元测试框架,其中包括创建测试用例,测试套件,测试固件,执行测试,以及可以输出基于Html的测试报告。当我们安装Python之后,里面就包含了这个单元测试框架,使用的时候,直接import unittest就可以直接使用了。
unittest各部分组成:

在这里插入图片描述

TestCase:单元测试用例,TestCase是一个类,使用TestCase时要继承unittest
TestSuite:存放测试用例,测试方法的一个容器,使用的时候要unittest.TestSuite()来调用。
Test Fixture:测试固件,主要完成初始化和清理工作,比如清除创建临时的数据库,文件和目录等,其中 setUp() 和 setDown()是最常用的方法,setUp()用来初始化浏览器,setDown()用来关闭资源。
TestRunner:执行单元测试
TestReport:生成测试报告

组织测试用例执行

测试脚本test001:

from selenium import webdriver
import unittest
import time
from selenium.common.exceptions import NoAlertPresentException

class testCase1(unittest.TestCase):
    def setUp(self) :
        #初始化
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(3)


    def tearDown(self):
        #关闭浏览器
        self.driver.quit()
#方法以test_开头都会默认去执行
    def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("诸葛亮")
        driver.find_element_by_id("su").click()
        time.sleep(6)
    def test_baidu2(self):
        driver=self.driver
        driver.find_element_by_link_text("新闻").click()
        time.sleep(3)
    def is_alert_exist(self):
        try:
            self.driver.switch_to.alert
        except NoAlertPresentException as e:
            return False
        return True
    if __name__ == '__main__':
        #参数verbosity=0表示打印出每一个测试用例的执行情况
        unittest.main(verbosity=0)

测试脚本test002:

from selenium import webdriver
import unittest
import time
from selenium.common.exceptions import NoAlertPresentException

class testCase2(unittest.TestCase):
    def setUp(self) :
        #初始化
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(3)


    def tearDown(self):
        #关闭浏览器
        self.driver.quit()
#方法以test_开头都会默认去执行
    def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("王俊凯")
        driver.find_element_by_id("su").click()
        time.sleep(6)
    def test_baidu2(self):
        driver=self.driver
        driver.find_element_by_link_text("hao123").click()
        time.sleep(3)
    def is_alert_exist(self):
        try:
            self.driver.switch_to.alert
        except NoAlertPresentException as e:
            return False
        return True
    if __name__ == '__main__':
        #参数verbosity=0表示打印出测试用例的执行情况
        unittest.main(verbosity=0)

组织测试套件

要调用TestSuite方法,要继承unittest,suite=unittest.TestSuite()

添加测试用例的时候,有以下3种方式:

  • addTest():可以一次存放一个测试脚本里的一个类的一个方法(必须要提供方法名)
  • makeSuite()和TestLoader():可以一次性存放一个测试脚本的一个类的所有方法
  • discover():可以把指定文件夹下特定格式命名的测试脚本中类的所有 以test_ 开头的方法全部添加进去。

测试用例的执行顺序:
unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为:0-9,A-Z,a-z。所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。

addTest()方法按照增加顺序来执行测试用例。

import unittest
from src20210805 import test001
from src20210805 import test002

def createSuite():
    #组织测试套件
    suite=unittest.TestSuite()
    #addTest方法添加测试用例,一个一个添加:
    # suite.addTest(test001.testCase1("test_baidu1"))
    # suite.addTest(test001.testCase1("test_baidu2"))
    # suite.addTest(test002.testCase2("test_baidu1"))
    # suite.addTest(test002.testCase2("test_baidu2"))
    
    #makeSuite()方法添加测试用例:
    suite.addTest(unittest.makeSuite(test001.testCase1))
    suite.addTest(unittest.makeSuite(test002.testCase2))
    return suite
    
    #TestLoader添加测试用例:
    # suite1=unittest.TestLoader.loadTestsFromTestCase(test001.testCase1)
    # suite2=unittest.TestLoader.loadTestsFromTestCase(test002.testCase2)
    # suite.addTest(suite1,suite2)
    # return suite

    #discover  把格式相同的脚本全部加进来
    # discover=unittest.defaultTestLoader.discover('../src20210805',pattern='test00*.py',top_level_dir=None)
    # return discover
if __name__ == '__main__':
    suite=createSuite()
    runner=unittest.TextTestRunner(verbosity=1)
    runner.run(suite)

添加断言

手工执行测试用例的时候,肯定会有一个预期的结果,测试人员会将预期结果和测试结果进行对比,观察执行程序执行的正确性。
自动化测试执行的时候,则通过添加断言,让机器来将预期结果与实际运行结果进行对比。

添加的断言大体分为等价性, 逻辑比较以及其他, 如果给定的断言通过, 测试会继续执行到下一行的代码, 如果断言失败, 对应的case测试会立即停止或者生成错误信息( 一般打印错误信息即可) ,但是不要影响其他的case执行。

常用的断言的方法:

序号断言方法断言描述
1assertEqual(arg1, arg2, msg=None)验证arg1=arg2,不等则fail
2assertNotEqual(arg1, arg2, msg=None)验证arg1 != arg2, 相等则fail
3assertTrue(expr, msg=None)验证expr是true,如果为false,则fail
4assertFalse(expr,msg=None)验证expr是false,如果为true,则fail

在下面的test_baidu1方法中,添加断言,验证搜索的结果的标题和预期的结果标题是否一致,相等则成功,否则断言失败。

 def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("王俊凯")
        driver.find_element_by_id("su").click()
        time.sleep(6)
        print(driver.title)
        #添加断言,判断实际结果和预期的结果是否一致
        self.assertEqual(driver.title,"百度搜索",msg="not equals!")

忽略用例的执行

当一个脚本中测试方法特别多的时候,而我们只想执行特定的几个测试用例的时候,只需要在不想执行的测试用例前面加上@unittest.skip(“skipping”),在执行的时候它就不会运行了。

 @unittest.skip("skipping")

HTML报告输出

当测试用例特别少的时候,我们可以通过控制台打印出来的信息查看脚本的执行情况,但是当脚本特别多的时候,直接在控制台查看打印信息会显得特别慢,比较混款,效率低,还容易出错,所以当测试用例特别多的时候,可以使用unittest框架的TestReport方法来打印测试用例的执行情况;

使用unittest框架输出测试报告的时候,需要在python安装目录Lib目录下添加一个HTMLTestRunner.py文件,通过这个链接进行下载HTMLTestRunner.py下载链接

用Chrome浏览器打开生成的html测试报告,报告上会显示测试全部测试用例的执行情况,总数,执行成功或者失败。

import unittest
from src20210805 import test001
from src20210805 import test002

import os,sys
import HTMLTestRunner
import time

def createSuite():
    discover = unittest.defaultTestLoader.discover('../src20210805',
                                                   pattern='test00*.py', top_level_dir=None)
    print(discover)
    return discover

if __name__ == '__main__':
    # 获取当前脚本文件所在的文件路径
    #路径集,path[0]表示当前路径
    curpath=sys.path[0]
    print(curpath)
    # 如果文件不存在,则创建一个文件夹resultReport
    if not os.path.exists(curpath+"/resultReport"):
        os.makedirs(curpath+"/resultReport")
    #根据时间来命名。可以很清晰的区分不同时间执行的测试
    # 格式化时间,把时间戳转换成当地时间
    now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))
    #给测试报告设置标题,测试情况执行情况展示详细程度设置
    filename=curpath+"/resultReport/"+now+"-"+"resultReport.html"
    with open(filename,'wb') as fp:
        #"测试报告"前面加u,是防止乱码,以utf-8的形式进行展示
        #参数verbosity表示测试用例执行结果展示的详细程序,0的时候表示的不太详细,
        # 为2的时候,测试用例执行成功或者失败的原因都会详细的打印出来
        runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u"测试报告",
                                             description=u"用例执行情况",verbosity=2)
        suite=createSuite()
        runner.run(suite)

测试用例全部执行成功时候的报告:
在这里插入图片描述
有一个测试用例执行失败的时候,会用其他颜色进行标注,并展示执行失败的原因,描述特别清晰。
在这里插入图片描述

捕获异常并截图

我们在添加断言判断某个测试用例是否执行成功的时候,可能执行成功,也可能执行失败,所以在失败的时候,就需要我们保存一下错误截图。

例:测试是否打开百度页面,使用打开百度界面的标题与我们预期的结果进行比较,失败的话,将错误截图进行保存

    def test_baidu2(self):
        driver=self.driver
        self.driver.get(self.url)
        # 判断到底有没有打开百度页面
        try:
        #正确的打开百度页面的标题为,百度一下,你就知道,但是这里我们将标题改错,
        #验证我们写的代码能否保存错误截图的图片
            self.assertEqual(driver.title,"百度,你就知道",msg="判断失败,没有打开百度页面")
        except:
            #创建一个文件存放错误截图
            self.save_error_image(driver,"baidu.png")
        time.sleep(6)

    def save_error_image(self,driver,name):
        if not os.path.exists("./errorImage"):
            os.makedirs("./errorImage")
        now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
        #存到到./errorImage的目录下面,要加/
        self.driver.get_screenshot_as_file("./errorImage/"+now+"-"+name)

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI小艾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值