接口自动化测试框架之unittest

什么是unittest

unittest是python自带的单元测试框架。
什么是单元测试?说白了就是测试代码。
测试代码中的哪些内容?测试类和方法。
所以unittest说白了就是测试代码中类和方法的测试框架。

为什么要用unittest

unittest是单元测试框架,与接口自动化测试有什么关系呢?
其实并没有直接的关系。只是unittest的强大功能很适合用来进行接口自动化测试。
详见下面的四大组件。

四大组件介绍

TestCase

即测试用例。什么是测试用例呢?一个完整的单元测试测试流程,包括环境的搭建(或前置条件)、测试代码、环境的还原(或后置条件)。单元测试的本质也就在这里,一个测试用例是一个完整的测试单元流程,通过运行这个测试单元,可以对某一个问题进行验证。
下面拿测试一个用户登录的接口进行举例说明,一条测试用户正常登录测试用例的完整流程包括:
1.环境的搭建。也即前置条件,每执行一条测试用例前应该做的事,如登录数据库;
2.测试用例代码。包括准备测试用例的数据(能登录成功的测试数据),准备预期结果,调用接口得到实际结果,预期结果与实际结果进行断言,判断这次的用例是否执行成功。
3.环境的还原。也即后置条件,每执行一条测试用例后应该做的事,如关闭数据库。
这一条只是其中一条测试用例。就测试用户登录接口而言还有其他的测试用例,如:用户名为空、密码为空、用户名错误、密码错误等。

TestSuite

即测试套件。把所有的测试用例集合起来,相当于一个篮子。也可以将多个测试套件集合起来。通过TestLoader来加载测试用例到测试套件中。

TestRunner

即测试用例的执行。前面TestSuite将所有测试用例集合起来,这里的TestRunner将执行测试套件下的所有测试用例。除了执行测试用例之外,还可以通过图形化的网页展示测试结果。

TestFixture

即测试夹具。包括测试环境的搭建和销毁,有前置条件和后置条件。

代码实操

TestCase与TestFixture均写在一个具体的测试用例模块中,如test_login.py、test_register.py等

TestCase

test_login.py

import unittest

#模拟登录接口
def login(username=None, password=None):
    """登录"""
    if (not username) or (not password):
        # 用户名或者密码为空
        return {"msg": "empty"}

    if username == 'tom' and password == '123456':
        # 正确的用户名和密码
        return {"msg": "success"}

    return {"msg": "error"}

#定义测试类,继承TestCase类。最好以Test开头。
class TestLogin(unittest.TestCase):
    """
    下面每个方法中的代码表示的是一条测试用例。一条测试用例包括四个部分:准备传参、调用接口获取实际结果、
    准备预期结果、预期结果与实际结果进行断言
    """
    #登录成功
    def test_login_success(self):
         #准备接口测试需的数据,即要传入接口的传参
         username = 'tom'
         password = '123456'
         #用准备好的数据调用接口,拿到实际结果
         actual_result = login(username,password)
         #准备预期结果
         expected_result = {"msg":"success"}
         #预期结果及实际结果进行断言,判断这一条测试用例能否通过
         self.assertTrue(actual_result == expected_result)

    #登录失败--用户名+密码为空
    def test_login_failed_empty(self):
         #准备接口测试需的数据,即要传入接口的传参
         username = ''
         password = ''
         #用准备好的数据调用接口,拿到实际结果
         actual_result = login(username,password)
         #准备预期结果
         expected_result = {"msg": "empty"}
         #预期结果及实际结果进行断言,判断这一条测试用例能否通过
         self.assertTrue(actual_result == expected_result)

    #登录失败--用户名错误
    def test_login_failed_wrong_username(self):
         #准备接口测试需的数据,即要传入接口的传参
         username = 'aaa'
         password = '123456'
         #用准备好的数据调用接口,拿到实际结果
         actual_result = login(username,password)
         #准备预期结果
         expected_result = {"msg": "error"}
         #预期结果及实际结果进行断言,判断这一条测试用例能否通过
         self.assertTrue(actual_result == expected_result)

    # 登录失败--用户名正确,密码错误
    def test_login_failed_wrong_password(self):
        # 准备接口测试需的数据,即要传入接口的传参
        username = 'tom'
        password = '000000'
        # 用准备好的数据调用接口,拿到实际结果
        actual_result = login(username, password)
        # 准备预期结果
        expected_result = {"msg": "error"}
        # 预期结果及实际结果进行断言,判断这一条测试用例能否通过
        self.assertTrue(actual_result == expected_result)

右键选择unittest执行,可在控制台中看到执行结果。如果有一条测试用例不通过,会在左侧展示哪条不通过,且在右侧弹出AssertionError的报错;
如果是代码本身有错,则弹出代码具体的报错。
在这里插入图片描述

TestFixture

test_login.py

class TestLogin(unittest.TestCase):

    #前置条件类方法(测试环境的准备),每执行所有方法前先执行该方法
    @classmethod
    def setUpClass(cls) -> None:
        print("登录数据库")

    #前置条件实例方法(测试环境的准备),每执行一条用例前先执行该方法
    def setUp(self) -> None:
        print("每执行一条用例前先执行的前置条件")

    #后置条件实例方法(测试环境的销毁),每执行完一条用例后再执行该方法
    def tearDown(self) -> None:
        print("每执行一条用例后再执行的后置条件")

    # 后置条件类方法(测试环境的准备),每执行所有方法前先执行该方法
    @classmethod
    def tearDownClass(cls) -> None:
        print("关闭数据库")


    #登录成功
    def test_login_success(self):
         #准备接口测试需的数据,即要传入接口的传参
         username = 'tom'
         password = '123456'
         #用准备好的数据调用接口,拿到实际结果
         actual_result = login(username,password)
         #准备预期结果
         expected_result = {"msg":"success"}
         #预期结果及实际结果进行断言,判断这一条测试用例能否通过
         self.assertTrue(actual_result == expected_result)
  
#...   
#其他测试用例

执行unittest结果如下:
在这里插入图片描述

TestSuite与TestRunner均写在测试用例的运行模块:run.py中

TestSuite

TestSuite加载用例方式有两种,一种是加载某个目录下的所有测试用例,另一种是加载指定的测试用例。

第一种:加载所有测试用例(建议使用)

run.py

#初始化一个加载器:TestLoader
loader = unittest.TestLoader()

# 获取测试用例目录的路径
dir_path = os.path.dirname(os.path.abspath(__file__))
case_path = os.path.join(dir_path, 'tests')

# 初始化一个test_suite,使用 loader 收集所有的测试用例
test_suite = loader.discover(case_path)

第二种:加载部分测试用例

run.py

# 只加载注册的和登录的用例
suite_login = loader.loadTestsFromModule(test_login)
suite_register = loader.loadTestsFromModule(test_register)

# 初始化一个 suite
suit_total = unittest.TestSuite()
suit_total.addTests([suite_login, suite_register])

TestRunner

testRunner除了执行测试用例之外,还有一项任务:生成测试报告。测试报告的生成有两种方法:一种是使用unittest自带的TextTestRunner方法;另一种是使用第三方模块:HTMLTestRunner生成测试报告。所以测试方法的执行也有两种方式。

第一种:使用unittest自带的TextTestRunner

run.py

# 生成测试报告
with open("test_reports.txt", 'w', encoding='utf-8') as f:
     runner = unittest.TextTestRunner(f)
     runner.run(test_suit)

执行unittest后,在指定目录下生成test_reports.txt的测试报告如下。由于不好维护,且很难看,所以建议用第二种方法。
在这里插入图片描述

第二种:使用第三方模块:HTMLTestRunner(建议使用)

run.py

# HTML 测试报告 不是内置。是需要自己准备的。
from HTMLTestRunnerNew import HTMLTestRunner
with open("test_reports.html", 'wb') as f:
    runner = HTMLTestRunner(
        f,
        title='测试报告',
        description="这是第一次测试报告",
        tester='wonderful'
    )
    runner.run(suit_total)

执行unittest后,生成测试报告如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值