接口自动化测试(2)— 使用 unittest 测试框架进行接口自动化测试

在接口自动化测试中,unittest 是 Python 自带的单元测试框架,它也非常适合用于编写和执行接口测试。通过集成 unittest 与 HTTP 请求库(如 requests),我们可以轻松实现对 RESTful API 或其他接口的自动化测试。

下面将结合实际案例,介绍如何使用 unittest 来进行接口自动化测试。


1. 基本概念

接口自动化测试的目标是验证接口的正确性、可靠性和稳定性。使用 unittest 进行接口测试时,我们需要执行以下操作:

  • 发送 HTTP 请求:使用 requests 等库向接口发送请求。
  • 获取响应:获取接口的响应数据。
  • 断言:通过断言对响应数据进行验证,例如验证响应码、响应时间、返回内容等。

2. 安装依赖

在进行接口自动化测试时,首先需要安装 requests 库,它是一个流行的 HTTP 请求库,用于与接口进行交互。

pip install requests

3. 编写测试代码

3.1 测试类和测试方法

通过继承 unittest.TestCase,编写测试类和测试方法,每个测试方法都使用 HTTP 请求与接口进行交互,并对接口返回结果进行断言。

import unittest
import requests

class TestAPI(unittest.TestCase):

    # 设置接口的 URL 和请求头
    base_url = "https://jsonplaceholder.typicode.com"
    headers = {"Content-Type": "application/json"}

    # 测试 GET 请求
    def test_get_user(self):
        response = requests.get(f"{self.base_url}/users/1", headers=self.headers)
        
        # 验证响应状态码
        self.assertEqual(response.status_code, 200)
        
        # 验证返回数据结构
        data = response.json()
        self.assertEqual(data['id'], 1)
        self.assertEqual(data['name'], 'Leanne Graham')

    # 测试 POST 请求
    def test_create_post(self):
        data = {"title": "foo", "body": "bar", "userId": 1}
        response = requests.post(f"{self.base_url}/posts", json=data, headers=self.headers)
        
        # 验证响应状态码
        self.assertEqual(response.status_code, 201)
        
        # 验证返回数据
        json_data = response.json()
        self.assertEqual(json_data['title'], "foo")
        self.assertEqual(json_data['body'], "bar")

    # 测试 PUT 请求
    def test_update_post(self):
        data = {"id": 1, "title": "foo updated", "body": "bar updated", "userId": 1}
        response = requests.put(f"{self.base_url}/posts/1", json=data, headers=self.headers)
        
        # 验证响应状态码
        self.assertEqual(response.status_code, 200)
        
        # 验证返回数据
        json_data = response.json()
        self.assertEqual(json_data['title'], "foo updated")
        self.assertEqual(json_data['body'], "bar updated")

    # 测试 DELETE 请求
    def test_delete_post(self):
        response = requests.delete(f"{self.base_url}/posts/1", headers=self.headers)
        
        # 验证响应状态码
        self.assertEqual(response.status_code, 200)

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

3.2 解释代码

  • setUp() 和 tearDown() 方法
    • setUp() 用于测试前的初始化,通常用于设置请求的 URL 或其他共享资源。
    • tearDown() 用于测试后的清理工作,比如断开数据库连接、清理缓存等。
  • requests 库
    • requests.get():发送 GET 请求。
    • requests.post():发送 POST 请求。
    • requests.put():发送 PUT 请求。
    • requests.delete():发送 DELETE 请求。
  • 断言
    • self.assertEqual():验证返回的 HTTP 状态码、响应数据是否符合预期。
    • response.json():将响应内容解析为 JSON 格式。
    • response.status_code:获取响应的 HTTP 状态码。

3.3 运行测试

  1. 将上面的代码保存到一个 Python 文件中(如 test_api.py)。
  2. 使用命令行执行该文件:
python test_api.py

运行后,unittest 会自动发现并执行测试类中的所有方法,并显示测试结果。


4. 进阶功能

4.1 使用 setUp() 和 tearDown() 方法

如果接口测试需要前置和后置操作,可以使用 setUp() 和 tearDown() 方法。

import unittest
import requests

class TestAPI(unittest.TestCase):

    def setUp(self):
        """ 在每个测试之前执行,进行测试环境的准备 """
        self.base_url = "https://jsonplaceholder.typicode.com"
        self.headers = {"Content-Type": "application/json"}

    def tearDown(self):
        """ 在每个测试之后执行,进行环境清理 """
        pass

    def test_get_user(self):
        response = requests.get(f"{self.base_url}/users/1", headers=self.headers)
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertEqual(data['id'], 1)

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

4.2 跳过某个测试

有时我们希望跳过某些测试,可以使用 @unittest.skip 装饰器。

@unittest.skip("Skipping this test")
def test_skip_example(self):
    # 该测试将会被跳过
    pass

4.3 批量执行多个测试(Test Suite)

我们可以将多个测试组织在一起,在一个测试套件中执行。

def suite():
    suite = unittest.TestSuite()
    suite.addTest(TestAPI("test_get_user"))
    suite.addTest(TestAPI("test_create_post"))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

5. 常用断言方法

  • assertEqual(a, b):验证 a == b
  • assertNotEqual(a, b):验证 a != b
  • assertTrue(x):验证 x 为 True
  • assertFalse(x):验证 x 为 False
  • assertIn(a, b):验证 a 是否在 b 中。
  • assertIsNone(x):验证 x 是否为 None
  • assertRaises(exception, func, *args, **kwargs):验证 func 执行时是否抛出 exception 异常。

6. 总结

通过 unittest 框架进行接口自动化测试非常方便。我们可以通过继承 unittest.TestCase 来组织测试,通过 requests 库发送 HTTP 请求与接口进行交互。unittest 提供了强大的断言功能,帮助我们验证接口返回的数据和状态。

常见的操作包括:

  • 使用 requests 发送不同类型的请求(GET、POST、PUT、DELETE)。
  • 使用断言方法验证响应的状态码、内容、格式等。
  • 使用 setUp() 和 tearDown() 方法进行环境的初始化与清理。
  • 通过装饰器跳过某些测试。
  • 使用测试套件批量执行多个测试用例。

通过合理组织测试代码,接口自动化测试可以帮助我们高效地验证接口的正确性,提升开发效率并减少回归错误。