软件测试笔记|接口测试|如何测试依赖第三方的接口?

在测试依赖第三方的接口时,可以采用以下方法:

一、模拟第三方接口(Mocking)

1. 使用模拟框架

• 可以使用专门的模拟测试框架,如unittest.mock(Python)、Mockito(Java)等。这些框架允许你创建模拟对象,模拟第三方接口的行为。

• 例如,在 Python 中,可以使用unittest.mock模块来模拟一个依赖的第三方接口。假设要测试的函数function_under_test依赖于一个第三方接口third_party_api:


import unittest
from unittest.mock import patch

def function_under_test():
    # 假设这里调用了第三方接口
    response = third_party_api()
    return response

def third_party_api():
    # 实际的第三方接口实现
    return "Real response from third party"

class TestFunctionUnderTest(unittest.TestCase):

    @patch('__main__.third_party_api')
    def test_function_under_test(self, mock_api):
        # 设置模拟接口的返回值
        mock_api.return_value = "Mocked response"
        result = function_under_test()
        self.assertEqual(result, "Mocked response")

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


2. 手动模拟

• 如果没有模拟框架,也可以手动创建一个模拟对象来代替第三方接口。例如,可以创建一个类,该类具有与第三方接口相同的方法签名,并在测试中使用这个模拟对象。

• 以下是一个手动模拟的示例:


class MockThirdPartyAPI:
    def __init__(self):
        self.counter = 0

    def api_method(self):
        self.counter += 1
        return f"Mocked response {self.counter}"

def function_under_test(third_party):
    response = third_party.api_method()
    return response

class TestFunctionUnderTest(unittest.TestCase):

    def test_function_under_test(self):
        mock_api = MockThirdPartyAPI()
        result = function_under_test(mock_api)
        self.assertIn("Mocked response", result)

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


二、使用桩(Stub)

1. 创建桩函数

• 桩是一个替代实际依赖的简单实现。可以编写一个桩函数,该函数具有与第三方接口相同的签名,但返回固定的值或可配置的值。

• 例如,假设要测试的函数function_under_test依赖于一个第三方接口third_party_api,可以创建一个桩函数:


def function_under_test():
    response = third_party_api()
    return response

def stub_third_party_api():
    return "Stubbed response"

class TestFunctionUnderTest(unittest.TestCase):

    def test_function_under_test(self):
        # 将实际的第三方接口替换为桩函数
        global third_party_api
        third_party_api = stub_third_party_api
        result = function_under_test()
        self.assertEqual(result, "Stubbed response")

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


2. 配置桩的行为

• 根据需要,可以配置桩函数的行为,使其在不同的测试场景中返回不同的值。例如,可以使用参数来控制桩函数的返回值。

• 以下是一个可配置的桩函数示例:


def function_under_test():
    response = third_party_api()
    return response

def stub_third_party_api(config=None):
    if config is None:
        return "Default stubbed response"
    else:
        return config["response"]

class TestFunctionUnderTest(unittest.TestCase):

    def test_function_under_test(self):
        # 配置桩函数的行为
        config = {"response": "Configured stubbed response"}
        global third_party_api
        third_party_api = lambda: stub_third_party_api(config)
        result = function_under_test()
        self.assertEqual(result, "Configured stubbed response")

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


三、使用代理

1. 创建代理对象

• 创建一个代理对象,该对象拦截对第三方接口的调用,并返回预设的响应或执行其他自定义的逻辑。

• 例如,在 Python 中,可以使用自定义类来实现代理:


class ThirdPartyProxy:
    def __init__(self):
        self.response = "Proxy response"

    def api_method(self):
        return self.response

def function_under_test(third_party):
    response = third_party.api_method()
    return response

class TestFunctionUnderTest(unittest.TestCase):

    def test_function_under_test(self):
        proxy = ThirdPartyProxy()
        result = function_under_test(proxy)
        self.assertEqual(result, "Proxy response")

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


2. 动态代理

• 一些编程语言提供了动态代理的功能,可以在运行时动态地创建代理对象。例如,在 Java 中,可以使用java.lang.reflect.Proxy类来创建动态代理。

• 以下是一个 Java 动态代理的示例:


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface ThirdPartyInterface {
    String apiMethod();
}

class RealThirdParty implements ThirdPartyInterface {
    @Override
    public String apiMethod() {
        return "Real response from third party";
    }
}

class ThirdPartyProxyHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return "Proxy response";
    }
}

public class Test {
    public static void main(String[] args) {
        ThirdPartyInterface realThirdParty = new RealThirdParty();
        ThirdPartyInterface proxy = (ThirdPartyInterface) Proxy.newProxyInstance(
                realThirdParty.getClass().getClassLoader(),
                realThirdParty.getClass().getInterfaces(),
                new ThirdPartyProxyHandler());
        String result = proxy.apiMethod();
        System.out.println(result);
    }
}


四、记录和回放

1. 记录实际的响应

• 在实际环境中调用第三方接口,并记录下响应。然后,在测试中回放这些记录的响应,而不是实际调用第三方接口。

• 可以使用工具来记录和回放接口请求和响应,例如VCR.py(Python)、WireMock(Java)等。

• 以下是一个使用VCR.py的示例:


import requests
import vcr

@vcr.use_cassette('tests/fixtures/cassette.yml')
def function_under_test():
    response = requests.get('https://third-party-api.com/data')
    return response.json()

class TestFunctionUnderTest(unittest.TestCase):

    def test_function_under_test(self):
        result = function_under_test()
        self.assertIsInstance(result, dict)

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


• 第一次运行这个测试时,VCR.py会记录对第三方接口的请求和响应到cassette.yml文件中。后续的运行将回放这个记录的响应,而不是实际调用第三方接口。

2. 更新记录

• 当第三方接口的行为发生变化时,需要更新记录。可以手动删除记录文件,然后重新运行测试来创建新的记录。或者使用工具提供的更新功能来自动更新记录。

通过以上方法,可以在测试中有效地处理依赖第三方接口的情况,提高测试的稳定性和可重复性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳哥整理软件测试笔记

博文不易,打赏让创作更有动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值