• 12
  • 12
分享
  • 如何使用Unittest编写自动化测试用例——软件测试圈
  • 曼倩诙谐 2021-04-13 10:13:54 字数 9034 阅读 2179 收藏 12

  前言

  我们编写自动化的测试用例,通常会编写在单元测试框架中。python的单元测试有自带的unittest和第三方的pytest,今天主要介绍下我们在python中如何通过unittest编写自动化测试用例。

  unittest介绍

  unittest属于python自带的单元测试框架,类似与java的junit。unittest支持编写测试自动化用例,多个用例中共享一个前置和后置内容,有多种执行测试用例的方法,支持生成独立的测试报告内容。

  官方文档:https://docs.python.org/2/library/unittest.html

  unittest常用方法

  无论是什么单元测试框架,都会有一些常用的方法,安静先介绍下unittest框架中一些常用的方法。

  Test Case

  Test Case通常用来创建测试用例,编写的测试用例标准是以test进行开头的(当然这个是官方定义的,其实可以通过修改unittest的源码进行修改的。)测试用例的执行顺序是通过ASCII值排序来执行的。

  Test Suite

  Test Suite属于一个测试套件,可以把我们的测试用例进行都放在这个里面进行执行。

  Test Fixture

  Test Fixture表示编写的测试用例的初始化准备及环境还原,主要是setUp() 和 setDown()方法。

  Test Runner

  TestRunner通常用来执行测试用例,会把我们执行的测试的结果通过HTMLTestRunner的形式展现在测试报告中。

  unittest简单使用

  前面介绍了unittest的常用方法,介绍下unittest的简单使用。这里需要先导入unittest库,需要在类中继承unittest中的TestCase方法,编写用例时用例名需要已test开头。

import unittest
class Test(unittest.TestCase):
    
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
if __name__ == '__main__':
    unittest.main()

   

  通过执行可以看到,一共编写了2条用例都全部执行完成了,其中如果执行程序则用"."表示,失败的话会用"F"表示。

1-1.png

  前置和后置

  功能测试中执行用例有前置条件,那么我们编写自动化用例的时候也有前置和后置,其中前置通过setup后置通过teardown进行操作。

import unittest
class Test(unittest.TestCase):
    def setUp(self):
        print('执行前置操作--->打开浏览器。')
        
    def tearDown(self):
        print('执行后置操作--->关闭浏览器。')
        
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
if __name__ == '__main__':
    unittest.main()

   

  通过执行结果发现每条用例都会进行执行前置操作和后置操作。如果我们的用例顺序是固定的,那么就不需要多次进行前置操作,那么我们就可以通过另一种方法进行使用。

  classmethod

  classmethod是unittest的一个装饰器方法,通常和setupclass,teardownclass进行结合使用,多数用来执行一个class中只执行一次测试用例前置和后置操作。

import unittest
class Test(unittest.TestCase):
    
    @classmethod
    def setUpClass(cls):
        print('执行前置操作--->打开浏览器。')
        
    @classmethod
    def tearDownClass(cls):
        print('执行后置操作--->关闭浏览器。')
        
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
if __name__ == '__main__':
    unittest.main()

   

  通过执行结果可以看出来,用例01和用例02都只执行了一次操作。

1-2.png

  unittest断言

  每条测试用例都需要一个断言来判断是否成功,在unittest中有特定的断言方法,其实和python自带的类似,只是有一点改动。安静给大家距离介绍。

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('判断a是否存在b中')
        a = '安静'
        b = '测试安静'
        self.assertIn(a, b)
        
    def test_02(self):
        print('判断a是否等于b')
        a = '111'
        b = '111'
        self.assertEqual(a, b)
        
    def test_03(self):
        print('a是否等于为True')
        a = True
        self.assertTrue(a)
        
    def test_04(self):
        print('失败用例')
        a = '测试安静'
        b = '测试-安静'
        self.assertIs(a, b)
        
if __name__ == '__main__':
    unittest.main()

   

  通过执行操作会发现,前3个测试用例都通过了,第4个执行失败,并提示错误出现在哪里。方便我们查看错误信息。

1-3.png

  断言方法

  其实unittest的断言方法不仅仅只有这几种,安静给大家列举了一些常用的。

1-4.png

  verbosity

  肯定有小伙伴们会问什么是verbosity?这个和unittest有什么关系,其实这个也是属于unittest的中一个参数,通常用来表示我们的用例的执行情况和详细信息,其中verbosity一共有3个值分别是0,1和2。

  verbosity=0

  当verbosity等于0时表示:执行用例的时候,只能获取用例的测试结果和测试用例数量。当然用例中的打印,肯定是会显示的

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
if __name__ == '__main__':
    unittest.main(verbosity=0)

   

  通过执行结果发现,当我们把verbosity=0设置在main函数中,执行后就会进行只打印一些简单的内容,执行了多少个用例,用例的打印内容,已经测试结果。

1-5.png

  verbosity=1

  verbosity=1时表示:在0的基础上,每个成功的用例前面有个".",失败的用例前面有个"F"(是不是很熟悉?其实这个就是默认操作。verbosity默认为1)。

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
if __name__ == '__main__':
    unittest.main(verbosity=1)

   

  执行结果发现,用例的前面都存在一个"."表示执行成功。

1-6.png

  verbosity=2

  verbosity=2表示:每条用例都会输出详细的相关信息。

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
if __name__ == '__main__':
    unittest.main(verbosity=2)

   

  通过执行结果可以看出来,这个比前面2个都详细。

1-7.png

  参数值具体什么时候使用,这个就要看大家在项目中的需求了。

  加载用例的方法

  在unittest中执行测试用例的方法有很多种。比如:想要执行特定的用例,想要批量执行某模块的用例,这个时候就会有不同的方法来执行更加方便。

  TestCase

  用例测试集合,将相同模块下的用例可以都写在一起,执行的时候直接通过main方法或者当前方法的文件名执行。

import unittest
class Test(unittest.TestCase):
    
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
if __name__ == '__main__':
    unittest.main()

   

  testsuite

  testsuite简称测试套件,就是可以将不同的用例都添加到这个套件中,然后通过执行套件,然后完成执行测试用例。

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
        
if __name__ == '__main__':
    #创建测试套件 
    suite = unittest.TestSuite()
    # 测试用例加入到测试套件中
    suite.addTests([Test('test_01'), Test('test_03')])
    # 执行测试用例
    run = unittest.TextTestRunner()
    run.run(suite)

   

  通过执行结果可以看出来,我们的test_02没有执行,只执行了用例1和用例3。

1-8.png

  discover

  discover可以通过文件夹的形式进行执行,在实际项目中,测试用例都会存放在测试用例对应的目录下,用例量比较多,我们就可以通过discover的方法进行执行。

  其中discover有3个参数:

  ·start_dir:表示用例路径

  ·pattern:用例匹配规则

  ·top_level_dir:项目目录名称

import unittest
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
        
if __name__ == '__main__':
    # 用例路径
    case_path = 'E:\\web'
    # 批量执行当前文件夹下的执行文件
    discover = unittest.defaultTestLoader.discover(case_path,
                                                   pattern='w5.py',
                                                   top_level_dir=None)
    run = unittest.TextTestRunner()
    run.run(discover)

   

  通过执行结果,我么的文件夹w5.py下的用例已经全部执行完了,当我们在真是项目中,可以将pattern的参数改成“t*.py”这样就可以将当前文件下的所有t开通的文件全部执行。

1-9.png

  跳过用例

  当我们执行用例时候,知道该用例存在bug,再bug没修改前不想要执行,我们可以通过unittest中的skip方法进行跳过,跳过分为两种,强制跳过和条件跳过。

  无条件跳过skip

  skip为无条件跳过。需要给一个跳过的理由reason参数。

import unittest
class Test(unittest.TestCase):
    @unittest.skip(reason='该功能存在bug跳过')
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
        
if __name__ == '__main__':
    unittest.main(verbosity=2)

   

  通过执行结果发现,用例01已经跳过了。只执行了2和3。

1-10.png

  有条件跳过skipif

  skipif表示条件为True的时候进行跳过,条件如果为False就会继续执行。

import unittest
import sys
class Test(unittest.TestCase):
    @unittest.skipIf(True, reason='该功能存在bug跳过')
    def test_01(self):
        print('---用例01---')
        
    @unittest.skipIf(sys.platform=='win32', reason='只能在mac上进行运行')
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
        
if __name__ == '__main__':
    unittest.main(verbosity=2)

   

  通过执行用例,会发现用例1和用例2都跳过了,因为判断的条件为True,所以进行了跳过。

1-11.png

  有条件跳过skipunless

  上面介绍了条件为True的时候跳过,那么肯定会有条件为False的时候进行跳过,刚好skipunless就是属于这个需求了,当条件为False的时候进行跳过。

import unittest
import sys
class Test(unittest.TestCase):
    @unittest.skipUnless(False, reason='该功能存在bug跳过')
    def test_01(self):
        print('---用例01---')
        
    @unittest.skipUnless(sys.platform=='Linux', reason='只能在Windows上执行')
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
if __name__ == '__main__':
    unittest.main(verbosity=2)

   

  通过执行结果发现,同样条件为False的用例1和2都已经跳过了。

1-12.png

  测试报告

  无论是功能测试还是自动化测试还是接口测试,做完测试后肯定想编写一份完整的测试报告,unittest中没有自带的报告生成,需要通过导入unittest的扩展库HTMLTestRunner。

  下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

  使用方法:下载完成后,直接放到执行的目录中,需要的时候进行导入即可。其中在源码中也详细的介绍了调用方法。

# output to a file
    fp = file('my_report.html', 'wb')
    runner = HTMLTestRunner.HTMLTestRunner(
                stream=fp,
                title='My unit test',
                description='This demonstrates the report output by HTMLTestRunner.'
                )
    # Use an external stylesheet.
    # See the Template_mixin class for more customizable options
    runner.STYLESHEET_TMPL = '<link rel="stylesheet" href="my_stylesheet.css" type="text/css">'
    # run the test
    runner.run(my_test_suite)

   

  其中上面的三个参数分别表示意思:

  ·stream:表示生成报告的路径

  ·title:表示报告的标题

  ·description:表示用例执行情况说明

import unittest
import HTMLTestRunner
class Test(unittest.TestCase):
    def test_01(self):
        print('---用例01---')
        
    def test_02(self):
        print('---用例02---')
        
    def test_03(self):
        print('---用例03---')
        
if __name__ == '__main__':
    # 创建测试套件
    suite = unittest.TestSuite()
    # 测试用例加入到测试套件中
    suite.addTests([Test('test_01'), Test('test_02'),Test('test_03')])
    report_path = 'report.html'
    # 打开报告
    fp = open(report_path, 'wb')
    runner = HTMLTestRunner.HTMLTestRunner(stream=fp,
                                           title=u'自动化测试报告,测试结果如下:',
                                           description=u'用例执行情况:')
    # 执行用例
    runner.run(suite)
    # 关闭报告
    fp.close()

   

  通过执行会发现在当前目录已经生成了测试报告。点击查看会出现下图的报告内容。

1-13.png

  这里会看到报告还是不完美,没有详细的用例详情,我们只要在每条用例下加入函数注释即可。

1-14.png

  再次执行后,就会发现,我们每条用例中已经有详细的用例详情。

1-15.png

  总结

  通过这么长的阅读,肯定对unittest有所认识和了解。安静简单的介绍了unittest的一些功能,希望可以帮助读者运用到实际的工作中。


作者:测试安静   

来源:51Testing软件测试网原创

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   苹果公司将于近期发布的 iOS 17.1 更新解决了一个"可能导致显示屏烧屏"的问题。自 iPhone 15 机型发布以来,一直有零星报道称新设备出现严重的屏幕烧毁现象。有人猜测可能是 OLED 显示屏的硬件问题,但根据 iOS 17.1 更新,苹果发现并解决了这个问题。  虽然大多数显示屏问题的报告都来自 iPhone15 用户,但也有一些使用 iPhone 13 Pro 和 iPhone 12 Pro 设备的用户出现了类似问题,这很可能就是为什么苹果的发布说明没有特别提及 iPhone 15 的原因。  那些发现 iPhone 出现"烧屏"问题的...
            0 0 1001
            分享
          • 心里有数,也要留一手,和盘托出,不是一场好戏。底牌哪能随便乱漏?我们做人做事啊,千万要记得留有余地,留有余粮,以备不时之需。留有情面,两人之间就有了润滑的空间。留有神秘,两人之间就有了空间想象。留有距离,两人之间就有了美。留有底牌,两人之间就有了互相学习的机会。看透了,就没意思了。戏曲,歌剧,一出好戏,总是分好几出,好几场,好几段。有生旦净末丑,有咏叹调,有慢板,有快板……没有了这样的曲折蜿蜒,起伏跌宕,哪有那么美妙的歌曲?印象深刻的歌剧?适度,是人生智慧之一,积少成多,是客观现实之一,人们对自清醒地认识,就是知道自己不是无所不能,知道自己不是啥都能干,就是知道自己的局限性和渺小,狂妄份子貌似...
            1 1 879
            分享
          •   什么是软件测试缺陷?测验行业的习惯叫法,即Bug管理。在软件或程序开发过程中,编程人员编码、系统设计结构不合理等都会导致错误报错,影响系统程序的正常运行。并且软件测试的目的之一,就是通过手工测试或者自动测试工具来执行操作,测试发现这些Bug,并对代码进行修复。  一、软件测试缺陷分类  1、网络环境;如果测试过程中,外部网络不稳定,也有可能造成软件测试缺陷。例如性能测试对网络环境的配置要求比较高,网络出现延迟、卡顿等都会影响测试结果。  2、硬件环境;由于磁盘空间内存不足、CPU运行速度等造成的系统瓶颈问题。对操作系统、服务器等硬件配置的测试也可能出现偏差。  3、数据问题;由于不同环境i...
            0 0 4179
            分享
          •   从事测试工作已3年有余了,今天想聊一下自己刚入门时和现在的今昔对比,虽然现在也没什么成就,只能说笑谈一下自己的测试生涯,各位看官就当是茶余饭后的吐槽吧,另外也想写一写自己的职场感想,希望对刚开始工作的小伙伴能够有些帮助或启发。  选择测试的原因  我大学学的是计算机专业,对于IT互联网行业,那也算是正统科班出身吧,大四那年就进了一家还挺大的软件公司实习,开发公司的自主产品,一个线上管理软件。  所在的团队各个都是猫头鹰界的扛把子,动不动就干到半夜,我一个实习生,早走显得不够努力,只能也跟着硬熬,好在当时带我的组长照顾,让我早点下班,但其实在实习的近半年里,我也没有准时下班过。  写到这里,...
            0 0 854
            分享
          • 软件自动化测试当中最简单也是最常用接口自动化测试,当我们投入到实际工作应用中就会发现,虽然接口测试很有效也很容易推广开来,但是很多时候真正需要测试验证的不仅仅是接口测试的返回,还包括前端页面的重现。所以近下来的学习内容就将进入到 WEB 自动化(即 WEB 端 UI 自动化)。什么是 WEB自动化WEB 自动化测试就是把在网页上的人工操作转化为使用机器、软件、程序来测试产品的过程。也就是把大量需要人工回归用例、人工操作的这些手段由计算机代替执行的一种测试方式。模拟人工执行的一系列操作,同时最终会抓取并判断结果是否符合我们的预期的这样一个过程。换而言之,就是把 “点点点” 通过编程手段实现的一种...
            0 0 798
            分享
      • 51testing软件测试圈微信