Python 单元测试 - unittest详解

文章目录

    • 一.什么是unittest
    • 二.unittest case的运行流程:
    • 三 Testcase:
    • 四.Test suite:
    • 五.TestLoader:
    • 六. Test fixture:
    • 七. 测试用例报告生成
      • HTMLTestRunner
      • 生肖配对
      • 星座运势接口
      • 通过runcase来调用这两个接口运用了unittest的descover方法

一.什么是unittest

unittest是python内置的用于测试代码的模块,无需安装, 使用简单方便。

unittest中有4个重要的概念:test fixture, test case, test suite, test runner
Python 单元测试 - unittest详解_第1张图片

二.unittest case的运行流程:

unittest case的运行流程:

  • 写好一个完整的TestCase
  • 多个TestCase 由TestLoder被加载到TestSuite里面, TestSuite也可以嵌套TestSuite
  • 由TextTestRunner来执行TestSuite,测试的结果保存在TextTestResult中
  • TestFixture指的是环境准备和恢复

三 Testcase:

    一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码 (run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

  • 参数verbosity可以控制错误报告的详细程度:默认为1。0,表示不输出每一个用例的执行结果;2表示详细的执行报告结果。
  • Verbosity=1情况下成功是 .,失败是 F,出错是 E,跳过是 S
  • 测试的执行跟方法的顺序没有关系, 默认按字母顺序
  • 每个测试方法均以 test 开头
  • Verbosity=2情况下会打印测试的注释

四.Test suite:

多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。

一般通过addTest()或者addTests()向suite中添加。case的执行顺序与添加到Suite中的顺序是一致的

  • @unittest.skip()装饰器跳过某个case
    (1)skip():无条件跳过
  • @unittest.skip("i don’t want to run this case. ")
    (2)skipIf(condition,reason):如果condition为true,则 skip
  • @unittest.skipIf(condition,reason)
    (3)skipUnless(condition,reason):如果condition为False,则skip
  • @unittest.skipUnless(condition,reason)

五.TestLoader:

是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例
TestLoadder用来加载TestCase到TestSuite中。

loadTestsFrom*()方法从各个地方寻找testcase,创建实例,然后addTestSuite,再返回一个TestSuite实例
defaultTestLoader() 与 TestLoader()功能差不多,复用原有实例
unittest.TestLoader().loadTestsFromTestCase(testCaseClass)
unittest.TestLoader().loadTestsFromModule(module)
unittest.TestLoader().loadTestsFromName(name,module=None)
unittest.TestLoader().loadTestsFromNames(names,module=None)
unittest.TestLoader().discover()

六. Test fixture:

对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖 TestCase的setUp()和tearDown()方法来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp() 中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的 TestCase留下一个干净的环境。关于fixture,还有一个专门的库函数叫做fixtures,功能更加强大。

用于测试环境的准备和恢复还原, 一般用到下面几个函数。

  • setUp():准备环境,执行每个测试用例的前置条件
  • tearDown():环境还原,执行每个测试用例的后置条件
  • setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只运行一次
  • tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次

七. 测试用例报告生成

HTMLTestRunner

现在把测试用例生成报告主要应用到了HTMLTestRunner 这个包,HTMLTestRunner是一个第三方的unittest HTML报告库,但是这个包不能直接 pip install ,所以我们需要去下载py文件 http://tungwaiyip.info/software/HTMLTestRunner.html

首先根据这个链接下载文件到Python下的Lib目录下的site-packages;

还有一部分同学不知道自己python安装到哪里了。

  • 首先打开cmd
  • 在小黑窗口中输入python
  • 出现交互页面 输入
 import sys
  • 继续输入 sys.path 就会显示python的安装路径了。如图:
  • Python 单元测试 - unittest详解_第2张图片

shell 模式下输入 import HTMLTestRunner 不报错就证明安装好了
Python 单元测试 - unittest详解_第3张图片

运行出的报告样板如下:
Python 单元测试 - unittest详解_第4张图片

附上部分代码供大家参考:
这是引用聚合网上的接口例子:生肖配对、星座运势接口
这两个接口来通过一个runcase文件批量执行。

生肖配对

# -*- coding: utf-8 -*-
# @Time    : 2021/8/13 16:43
# @Author  : DuYiB
# @FileName: test_sxpd.py
# @Software: PyCharm

import requests
import unittest
#继承unittest.TestCase
class TestSxpd(unittest.TestCase):
    #url地址
    url = 'http://apis.juhe.cn/sxpd/query'
    def test_top(self):
        #传入参数
        data = "key=6a8be1a21763f1b6db02f2edaf626559&men=蛇&women=虎"
        #请求响应传入参数,返回数据
        res = requests.get(url=self.url,params=data)
        #变成json格式
        njson = res.json()
        #通过断言来判断实际结果是否与预期结果一致
        self.assertEqual(res.status_code,200,msg="状态码是200")
        self.assertEqual(njson['error_code'],0,msg='错误为0')

    def test_key_void(self):
        data ="men=蛇&women=虎"
        res = requests.get(url=self.url,params=data)
        njson = res.json()
        #通过断言来判断实际结果与预期结果是否一致
        self.assertEqual(res.status_code,200,msg="状态码是200")
        self.assertEqual(njson['error_code'],10001,msg='错误为0')


    def test_women_void(self):
        data = "key=6a8be1a21763f1b6db02f2edaf626559&men=蛇"
        res = requests.get(url=self.url,params=data)
        njson = res.json()
        #通过断言来判断实际结果与预期结果是否一致
        self.assertEqual(res.status_code,200,msg="状态码是200")
        self.assertEqual(njson['error_code'],253901,msg='错误为0')

    def test_men_void(self):
        data = "key=6a8be1a21763f1b6db02f2edaf626559&women=虎"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        # 通过断言来判断实际结果与预期结果是否一致
        self.assertEqual(res.status_code, 200, msg="状态码是200")
        self.assertEqual(njson['error_code'], 253901, msg='错误为0')


    def test_men_error(self):
        data = "key=6a8be1a21763f1b6db02f2edaf626559&women=虎&men=asd"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        # 通过断言来判断实际结果与预期结果是否一致
        self.assertEqual(res.status_code, 200, msg="状态码是200")
        self.assertEqual(njson['error_code'], 253901, msg='错误为0')




# if __name__ == '__main__':
#     unittest.main()

星座运势接口

# -*- coding: utf-8 -*-
# @Time    : 2021/8/14 7:02
# @Author  : DuYiB
# @FileName: test_xzys.py
# @Software: PyCharm

import requests
import  time
import unittest

class TestXzys(unittest.TestCase):
    url = "http://web.juhe.cn:8080/constellation/getAll"
    def test_top(self):
        data = "key=ce06d65173eaaf9a96559db02f9fec18&consName=金牛座&type=today"
        res = requests.get(url=self.url,params=data)
        njson = res.json()
        self.assertEqual(res.status_code,200,msg='状态码为200')
        self.assertEqual(njson['error_code'],0,msg="错误码为0")


    def test_top_key_void(self):
        data ="consName=金牛座&type=today"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        self.assertEqual(res.status_code, 200, msg='状态码为200')
        self.assertEqual(njson['error_code'], 10001, msg="错误码为0")



    def test_top_cosName_void(self):
        data ="key=ce06d65173eaaf9a96559db02f9fec18&type=today"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        self.assertEqual(res.status_code, 200, msg='状态码为200')
        self.assertEqual(njson['error_code'], 205801, msg="错误码为0")



    def test_top_type_void(self):
        data ="key=ce06d65173eaaf9a96559db02f9fec18&consName=金牛座&type=duyibo"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        self.assertEqual(res.status_code, 200, msg='状态码为200')
        self.assertEqual(njson['error_code'], 205801, msg="错误码为0")


    def test_top_key_error(self):
        data ="key=ce06d65173eaaf9a96559db02f9fadwaec18&consName=金牛座&type=today"
        res = requests.get(url=self.url, params=data)
        njson = res.json()
        self.assertEqual(res.status_code, 200, msg='状态码为200')
        self.assertEqual(njson['error_code'], 10001, msg="错误码为0")

if __name__ == '__main__':
    unittest.main()

通过runcase来调用这两个接口运用了unittest的descover方法

# -*- coding: utf-8 -*-
# @Time    : 2021/8/13 19:26
# @Author  : DuYiB
# @FileName: runcase.py
# @Software: PyCharm

import requests
import os
import time
import HTMLTestRunner
import unittest
#实例化对象通过调用方法找到在当前路径下的test开头的py文件
descover = unittest.defaultTestLoader.discover('./','test*.py')
#格式化时间参数
now = time.strftime('%Y%m%d %H%M%S')
#确定生成报告的路径以及格式
filepath =  "路径\"+ now + '_result.html'
fp = open(filepath,'wb')
#调用方法获取路径、标头、描述等
runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='测试用例报告详细表',description='报告如下')
runner.run(descover)
fp.close()

以上适合初级者学习,若有想法,欢迎交流

你可能感兴趣的:(测试工程师,python,单元测试,开发语言)