The best in the whole network, interface automation test mock framework module actual combat, entry to advanced...


foreword

Introduction to mock

py3 has integrated mock into the unittest library;
for better unit testing;
easy to understand, simulate the return parameters of the interface;
easy to understand, directly modify the value of the interface return parameters;

The role of mock

1. Solve the dependency problem and achieve decoupling.
When we test a target interface (module), the interface depends on other interfaces. When the dependent interface is not developed, we can use mock to simulate the dependent interface to complete the target interface. test;

2. Simulate complex business interfaces
When we test a target interface (module) that depends on a very complex interface, we can use mock to simulate this complex business interface; it also solves the same principle of interface dependence

3. Unit testing
If an interface (module) has not been developed yet and a test case needs to be written, the interface (module) can be simulated by mock for testing

4. Front-end and front-end joint debugging
The pages developed by the front-end need to display different pages according to the different status codes returned by the back-end. When the back-end interface has not been developed, you can also use mock to simulate the back-end interface to return the data you want

Interpretation of mock class

class Mock(spec=None,side_effect=None,return_value=DEFFAULT,name=None) 

secp: defines the attribute value of the mock object, which can be a list, a string, or even an object or instance
side_effect: can be used to throw an exception or dynamically change the return value, it must be an iterator (list), it will override return_value
return_value: Define the return value of the mock method, which can be a value or an object (if there is a side_effect parameter, this is useless, that is, it cannot be used at the same time) name:
As an identifier of the mock object, it can be seen when printing

mock actually used

How to test an undeveloped function?

def add(self, a, b):
    """两个数相加"""
    pass


class TestSub(unittest.TestCase):
    """测试两个数相加用例"""

    def test_sub(self):
        # 创建一个mock对象 return_value代表mock一个数据
        mock_add = mock.Mock(return_value=15)
        # 将mock对象赋予给被测函数
        add = mock_add
        # 调用被测函数
        result = add(5, 5)
        # 断言实际结果和预期结果
        self.assertEqual(result, 15)

How to test a developed function?

class SubClass(object):
    def add(self, a, b):
        """两个数相加"""
        return a + b


class TestSub(unittest.TestCase):
    """测试两个数相加用例"""


    def test_add2(self):
        # 初始化被测函数类实例
        sub = SubClass()
        # 创建一个mock对象 return_value代表mock一个数据
        # 传递side_effect关键字参数, 会覆盖return_value参数值, 使用真实的add方法测试
        sub.add = Mock(return_value=15, side_effect=sub.add)
        # 调用被测函数
        result = sub.add(5, 5)
        # 断言实际结果和预期结果
        self.assertEqual(result, 10)

side_effect: The parameter value given here is the address of sub.add which is equivalent to the add method. When we call the add method, the real add method will be called

Simple understanding: when the side_effect parameter is passed and the value is the address of the function under test, the mock will not work; the two cannot coexist

In addition, side_effect accepts an iterable sequence. When multiple values ​​are passed, different values ​​will be returned each time the mock is called;

mock_obj = mock.Mock(side_effect= [1,2,3])
print(mock_obj())
print(mock_obj())
print(mock_obj())
print(mock_obj())

# 输出
Traceback (most recent call last):
File "D:/MyThreading/mymock.py", line 37, in <module>
print(mock_obj())
File "C:\Python36\lib\unittest\mock.py", line 939, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "C:\Python36\lib\unittest\mock.py", line 998, in _mock_call
result = next(effect)
StopIteration

How to test the functions with dependencies?

# 支付类
class Payment:

    def requestOutofSystem(self, card_num, amount):
        '''
        请求第三方外部支付接口,并返回响应码
        :param card_num: 卡号
        :param amount: 支付金额
        :return: 返回状态码,200 代表支付成功,500 代表支付异常失败
        '''
        # 第三方支付接口请求地址(故意写错)
        url = "http://third.payment.pay/"
        # 请求参数
        data = {
    
    "card_num": card_num, "amount": amount}
        response = requests.post(url, data=data)
        # 返回状态码
        return response.status_code

    def doPay(self, user_id, card_num, amount):
        '''
        支付
        :param userId: 用户ID
        :param card_num: 卡号
        :param amount: 支付金额
        :return:
        '''
        try:
            # 调用第三方支付接口请求进行真实扣款
            resp = self.requestOutofSystem(card_num, amount)
            print('调用第三方支付接口返回结果:', resp)
        except TimeoutError:
            # 如果超时就重新调用一次
            print('重试一次')
            resp = self.requestOutofSystem(card_num, amount)

        if resp == 200:
            # 返回第三方支付成功,则进行系统里面的扣款并记录支付记录等操作
            print("{0}支付{1}成功!!!进行扣款并记录支付记录".format(user_id, amount))
            return 'success'

        elif resp == 500:
            # 返回第三方支付失败,则不进行扣款
            print("{0}支付{1}失败!!不进行扣款!!!".format(user_id, amount))
            return 'fail'

# 单元测试类
class payTest(unittest.TestCase):

    def test_pay_success(self):
        pay = Payment()
        # 模拟第三方支付接口返回200
        pay.requestOutofSystem = mock.Mock(return_value=200)
        resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
        self.assertEqual('success', resp)

    def test_pay_fail(self):
        pay = Payment()
        # 模拟第三方支付接口返回500
        pay.requestOutofSystem = mock.Mock(return_value=500)
        resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
        self.assertEqual('fail', resp)

    def test_pay_time_success(self):
        pay = Payment()
        # 模拟第三方支付接口首次支付超时,重试第二次成功
        pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 200])
        resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
        self.assertEqual('success', resp)

    def test_pay_time_fail(self):
        pay = Payment()
        # 模拟第三方支付接口首次支付超时,重试第二次失败
        pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 500])
        resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
        self.assertEqual('fail', resp)

Some people may ask: even if the third-party payment cannot be used, is our test result valid?

Usually when testing a module, it can be considered that the functions of other modules are normal, and there is no problem in testing only the target module, so the test result is also correct

mock decorator

There are two formats

 @patch('module名字.方法名') 
 @patch.object(类名, '方法名') 
# 装饰类演示
from mock import Mock, patch


# 单独的相乘函数
def multiple(a, b):
    return a * b


# 单独的捕获Exception函数
def is_error():
    try:
        os.mkdir("11")
        return False
    except Exception as e:
        return True


# 计算类,包含add方法
class calculator(object):
    def add(self, a, b):
        return a + b


# 装饰类演示 - 单元测试类
class TestProducer(unittest.TestCase):

    # case执行前
    def setUp(self):
        self.calculator = calculator()

    # mock一个函数,注意也要指定module
    @patch('mock_learn.multiple')
    def test_multiple(self, mock_multiple):
        mock_multiple.return_value = 3
        self.assertEqual(multiple(8, 14), 3)

    # mock一个类对象的方法
    @patch.object(calculator, 'add')
    def test_add(self, mock_add):
        mock_add.return_value = 3
        self.assertEqual(self.calculator.add(8, 14), 3)

    # mock调用方法返回多个不同的值
    @patch.object(calculator, 'add')
    def test_effect(self, mock_add):
        mock_add.side_effect = [1, 2, 3]
        self.assertEqual(self.calculator.add(8, 14), 1)
        self.assertEqual(self.calculator.add(8, 14), 2)
        self.assertEqual(self.calculator.add(8, 14), 3)

    # mock的函数抛出Exception
    @patch('os.mkdir')
    def test_exception(self, mkdir):
        mkdir.side_effect = Exception
        self.assertEqual(is_error(), True)

    # mock多个函数,注意函数调用顺序
    @patch.object(calculator, 'add')
    @patch('mock_learn.multiple')
    def test_more(self, mock_multiple, mock_add):
        mock_add.return_value = 1
        mock_multiple.return_value = 4
        self.assertEqual(self.calculator.add(3, 3), 1)
        self.assertEqual(multiple(3, 3), 4)
The following is the most complete software test engineer learning knowledge architecture system diagram in 2023 that I compiled

1. From entry to mastery of Python programming

Please add a picture description

2. Interface automation project actual combat

Please add a picture description

3. Actual Combat of Web Automation Project

Please add a picture description

4. Actual Combat of App Automation Project

Please add a picture description

5. Resume of first-tier manufacturers

Please add a picture description

6. Test and develop DevOps system

Please add a picture description

7. Commonly used automated testing tools

Please add a picture description

Eight, JMeter performance test

Please add a picture description

9. Summary (little surprise at the end)

Only those who go forward bravely can create their own miracles; only those who are willing to give can reap real achievements; only those who persevere can realize their dreams. Don't stop, chase bravely, you will find infinite possibilities!

Only with unremitting efforts can we pursue our dreams; only with never giving up struggle can we create brilliance. Every day's efforts create hope for a better future. Believe in yourself, go forward bravely, you will gain unlimited possibilities!

Only by working hard can we reap a brilliant future; only by persevering can we climb the peak of life; only by firm belief can we overcome all difficulties; only by challenging ourselves can we surpass our limits. Fight, you are invincible!

Guess you like

Origin blog.csdn.net/m0_70102063/article/details/131457581