Python中unittest 用不同的参数组合,测试同样的行为;使test case根据参数多次运行

本文介绍了一种使用Python unittest框架进行参数化测试的方法。通过自动生成针对不同参数组合的测试案例,提高了测试效率与可读性。文章提供了一个具体示例,展示了如何实现这一功能。

原文:http://www.2cto.com/kf/201501/367270.html

在某种情况下,需要用不同的参数组合,测试同样的行为我们希望从test case的执行结果上知道在测试什么,而不是单单得到一个大的 test case;

此时如果仅仅写一个test case并用内嵌循环来进行,那么其中一个出了错误,很难从测试结果里边看出来问题

所以现在问题的关键在于是否有办法根据输入参数的不同组合产生出对应的test case?

譬如你有10组数据,那么得到10个test case,这种情况当然不适用纯手工的方式写那么多个test_成员函数。

 一种可能的思路是不利用unittest.TestCase这个类框中的test_成员函数的方法,而是自己写runTest这个成员函数,那样会有一些额外的工作,而且看起来不是那么“智能”。

那该如何让框架自动调用testcase呢? 

我们的思路是: 利用setattr来自动为已有的TestCase类添加成员函数 为了使这个方法凑效,需要用类的static method来生成decorate类的成员函数,并使该函数返回一个test函数对象出去 在某个地方注册这个添加test成员函数的调用(只需要在实际执行前就可以,可以放在模块中自动执行亦可以手动调用)


dome:

# !/usr/bin/env python
# -*- coding: utf-8 -*-
import unittest


class TestCases(unittest.TestCase):

    def setUp(self):
        pass

    def action(self, arg1, arg2):
        print arg1, arg2

    @staticmethod
    def getTestFunc(arg1, arg2):
        def func(self):
            self.action(arg1, arg2)
        return func

def __generateTestCases():
    arglists = [('arg11', 'arg12'), ('arg21', 'arg22'), ('arg31', 'arg32')]
    for args in arglists:
        setattr(TestCases, 'test_func_%s_%s' % (args[0], args[1]),
                TestCases.getTestFunc(*args))
__generateTestCases()

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


<think>好的,用户问的是如何在Pythonunittest框架中进行接口自动化测试时的参数拼装。我需要先回忆一下unittest的基本结构,然后结合参数化的方法。 首先,unittest.TestCase类中的测试方法通常是以test_开头的方法。用户可能已经知道这点,但需要具体如何传递不同参数参数化的常见方法有使用@parameterized.expand装饰器,或者用subTest上下文管理器。 然后,引用中的内容可能有帮助。比如引用[2]提到了setUpModule和测试类的结构,但没有直接涉及参数化。引用[1]提到读取Excel中的用例,可能参数来源是Excel,但用户的问题更关注如何拼装参数,而不是数据来源。 参数拼装的方法可能有几种:动态生成测试用例、使用参数化库、或者循环遍历参数组合。比如,使用parameterized库可以方便地为测试方法提供多组参数,每个参数生成一个独立的测试用例。或者,在测试方法内部使用循环和subTest来逐一测试不同参数组合,这样可以在一个测试方法中处理多组数据,同时保持测试报告的清晰。 另外,需要考虑接口测试参数的构造方式,比如GET请求的查询参数和POST请求的请求体参数。可能需要根据不同的HTTP方法拼接参数,比如将字典转换为查询字符串或JSON格式。 还要提到如何处理动态参数,比如时间戳或token,这可能需要在setUp方法中预先生成,并拼接到参数中。比如在setUp里获取token,然后在测试方法中将token加入请求头或参数中。 需要确保回答的结构清晰,分步骤说明不同的方法,并给出代码示例。例如,先介绍参数化库的使用,再讲解subTest的用法,最后说明如何动态生成参数。同时,要引用相关的资料,比如引用[1]中的Excel用例读取可以和参数拼装结合使用。 最后,验证是否有遗漏点,比如数据驱动测试参数化的关系,如何处理不同接口的不同参数需求,以及如何管理测试数据等。可能还需要提到维护性和可读性的建议,比如将参数数据与测试代码分离,使用外部文件存储参数组合。</think>在Python的`unittest`框架中进行接口自动化测试时,参数拼装是数据驱动测试的核心环节。以下是几种常见的参数拼接方法及实现步骤: --- ### 1. **使用`@parameterized`库实现参数化** 通过第三方库`parameterized`为测试方法动态注入参数组合,适用于固定参数场景。 ```python import unittest from parameterized import parameterized class TestAPI(unittest.TestCase): @parameterized.expand([ ("case1", {"user": "admin", "pwd": "123"}, 200), ("case2", {"user": "guest", "pwd": ""}, 401), ]) def test_login(self, case_name, params, expected_code): response = requests.post("https://api.example.com/login", json=params) self.assertEqual(response.status_code, expected_code) ``` - **说明**:每个元组对应一组测试数据,参数会按顺序传递给测试方法[^2]。 --- ### 2. **通过`subTest`实现上下文参数化** 使用`subTest`上下文管理器在单个测试方法中遍历多组参数,适合动态生成的参数组合。 ```python class TestAPI(unittest.TestCase): def test_search(self): test_cases = [ {"keyword": "手机", "page": 1, "expected": 200}, {"keyword": "", "page": 0, "expected": 400}, ] for case in test_cases: with self.subTest(case=case): response = requests.get( "https://api.example.com/search", params={"q": case["keyword"], "page": case["page"]} ) self.assertEqual(response.status_code, case["expected"]) ``` - **优势**:测试报告中会明确区分每组参数的执行结果。 --- ### 3. **从外部文件读取参数(如Excel)** 结合`openpyxl`或`pandas`读取Excel中的测试数据,实现参数与代码分离。 ```python import pandas as pd def read_test_cases(file_path): df = pd.read_excel(file_path) return df.to_dict('records') class TestAPI(unittest.TestCase): def setUp(self): self.cases = read_test_cases("test_cases.xlsx") def test_create_order(self): for case in self.cases: with self.subTest(case=case): response = requests.post( "https://api.example.com/order", json=case["request_body"] ) self.assertIn(case["expected_result"], response.text) ``` - **引用场景**:如引用[1]中提到的Excel用例读取方法[^1]。 --- ### 4. **动态生成复杂参数** 针对需要动态生成的参数(如时间戳、Token),可在`setUp`或测试方法中实时构造。 ```python class TestAPI(unittest.TestCase): def setUp(self): self.token = self.get_auth_token() def get_auth_token(self): # 获取鉴权Token的逻辑 return "Bearer abc123" def test_user_info(self): headers = {"Authorization": self.token} response = requests.get("https://api.example.com/user", headers=headers) self.assertEqual(response.status_code, 200) ``` --- ### 5. **参数类型处理** 根据接口需求选择参数格式: - **GET请求**:使用`params`拼接查询参数 ```python params = {"page": 1, "size": 10} requests.get(url, params=params) ``` - **POST请求**:使用`json`或`data`传递请求体 ```python json_data = {"username": "test", "age": 25} requests.post(url, json=json_data) ``` ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值