Python接口测试之moco

  在现在的软件开发过程中,特别是app的部分,需要的很多数据以及内容,都是来自server端的API,但是不能保证在客户端开发的时候,

api在server端已经开发完成,专门等着前端来调用,理想的情况是前端在开发的时候,已经有人写好了接口,直接调用就可以了,但是这仅仅

是理想的情况,很多时候,现实总是比理想多一层思考和磨难,如果在前端开发的时候,提供api的同学没有提供,那么怎么办?等待还是自己

先开发,等待肯定是愚蠢的做法,那么自己开发怎么来解决api提供数据的这个问题,那么使用mock就可以很好的解决。

什么是mock?

  mock简单的理解就是开发在开发的过程中,需要依赖一部分的接口,但是对方没有提供或者环境等等情况,总之是没有,那么开发使用mock server

自己来mock数据,方便自己正常的进行开发和对编写的功能进行自测。

     在https://github.com/dreamhead/moco地址中可以下载到moco-runner-0.11.0-standalone.jar,下载下来就是一个jar

简单的编写一个登录的,见编写的login.json字符串:

[
  {
    "request":
    {
      "method":"post",
      "uri":"/login",
      "json":
      {
        "username":"admin",
        "password":"admin",
        "roleID":22
      }
    },
    "response":
    {
      "json":
      {
        "username":"wuya",
        "userID":22,
        "token":"asdgfhh32456asfgrsfss"
      }
    }
  }
]

在运行命令前,最好让mock server与编写的login.json文件是在同一个目录下,见执行的命令: 

java -jar  moco-runner-0.10.0-standalone.jar http -p 12306 -c login.json

如上的命令中,

  java -jar  moco-runner-0.10.0-standalone.jar是启动jar,

  moco-runner-0.10.0-standalone.jar 指jar包所在目录(因为jar就在当前目录下所以这里使用的是相对路径) http表示进行的是http协议,

    -p后面跟的是端口号,这里端口号指的是12306,

  -c后面跟编写的json文件,这里是login.json,见执行如上的命令后出现的信息

 (切记无任何的错误信息表示OK,如果有错误,慢慢的进行检查错误),见截图:

OK,下来我们使用postman来验证下,我们mock的登录接口是不是OK的,见postman中填写的信息,见截图:

header为:

  • Content-Length →63
  • Content-Type →application/json

OK,学习到这里,我们使用python编写一个接口测试用例,来验证换这个登录的接口和获取它的token,见实现的代码:

# -*- coding:utf-8 -*-

import  unittest
import  requests

class MockLoginTest(unittest.TestCase):
    def setUp(self):
        self.url='http://localhost:12306'

    def tearDown(self):
        pass

    def getUrl(self,path):
        return self.url+path

    def getToken(self):
        '''获取token'''
        data={
            "username":"admin",
            "password":"admin",
            "roleID":22
        }
        r=requests.post(self.getUrl('/login'),json=data)
        return r.json()['token']

    def test_login(self):
        '''验证登录的接口'''
        data={
            "username":"admin",
            "password":"admin",
            "roleID":22
        }
        r=requests.post(self.getUrl('/login'),json=data)
        self.assertEqual(r.status_code,200)
        self.assertEqual(r.json()['username'],'wuya')

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

OK,在上面的python代码中,实现了对登录接口的验证和获取了它的token

 

我们先看之前的mock-server部分,之前编写了一个登录的mock,具体json文件见如下的内容:

[
  {
    "request":
    {
      "method":"post",
      "uri":"/login",
      "json":
      {
        "username":"admin",
        "password":"admin",
        "roleID":22
      }
    },
    "response":
    {
      "json":
      {
        "username":"wuya",
        "userID":22,
        "token":"asdgfhh32456asfgrsfss"
      }
    }
  }
]

 数据分离:

查看上面的内容,我们可以看出,这样的方式并不是那么的友好,在UI或者接口的自动化测试中,我们知道在TDD的模式中,对数据进行分离,这样也是

为了维护的方便,这样的目的是为了后期自动化测试用例的扩展性,和它的易维护性。

那么下来我们来对上面的json文件进行修改下,对response部分的数据进行分离下,把它放在一个文件中,这样就可以分离了出来

我们把response的内容从login.json分离到login_response.json,切记login.json与login_response.json务必保持在同一个目录下,

见login.json的内容:

[
  {
    "request":
    {
      "method":"post",
      "uri":"/login",
      "json":
      {
        "username":"admin",
        "password":"admin",
        "roleID":22
      }
    },
    "response":
    {
      "file":"login_response.json"
    }
  }
]

见login_response.json文件的内容:

{
  "username":"wuya",
  "userID":22,
  "token":"asdgfhh32456asfgrsfss"
}

执行login.json文件后,访问该接口,看是否OK,见执行login.json文件的命令:

使用postman查看该接口,看是否OK,见如下的截图:

    下面我们再进行一个业务,就是输入一个车牌号,查询该车牌号的显示时长,和它的停车费用,直接在login.json文件中完善,见完善后的内容:

[
  {
    "request":
    {
      "method":"post",
      "uri":"/login",
      "json":
      {
        "username":"admin",
        "password":"admin",
        "roleID":22
      }
    },
    "response":
    {
      "file":"login_response.json"
    }
  },

  {
    "request":
    {
      "method":"post",
      "uri":"/parkinside",
      "json":
      {
        "token":"asdgfhh32456asfgrsfss",
        "vpl":"AJ3585"
      }
    },
    "response":
    {
      "file":"parkinside.json"
    }
  }
]
 

 

见parkinside.json文件的内容:

{
  "vplInfo":
  {
    "userID":22,
    "username":"wuya",
    "vpl":"京AJ3585"
  },
  "Parking time long":"20小时18分钟",
  "Parking fee":"20$"
}

 

见查询停车时长的接口请求的结果,见如下的postman截图:

 

下面我们通过python语言,来对如上的二个接口进行实战的操作,切记parkinside的接口是在登录之后才可以操作的业务,未登录操作该业务,

返回502无效的token,见实现的代码:

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

import  unittest
import  requests

class MockTest(unittest.TestCase):
    def setUp(self):
        self.url='http://localhost:12306'
        
    def tearDown(self):
        pass
    
    def test_login(self,url='/login'):
        '''验证登录的接口'''
        data={
            "username":"admin",
            "password":"admin",
            "roleID":22
        }
        r=requests.post(self.url+url,json=data)
        self.assertEqual(r.status_code,200)
        self.assertEqual(r.json()['username'],'wuya')
        
    def getToken(self,url='/login'):
        '''登录成功后获取token'''
        data={
            "username":"admin",
            "password":"admin",
            "roleID":22
        }
        r=requests.post(self.url+url,json=data)
        return r.json()['token']
    
    def test_parkingside(self,url='/parkinside'):
        '''验证查询停车时长接口'''
        data={
            "token":self.getToken(),
            "vpl":"AJ3585"
        }
        r=requests.post(self.url+url,json=data)
        self.assertEqual(r.status_code,200)
        self.assertEqual(r.json()['Parking time long'],u'20小时18分钟')
        self.assertEqual(r.json()['Parking fee'], u'20$')
        
if __name__=='__main__':
    unittest.main(verbosity=2) 

 

  上面介绍了moco的详细的使用,它主要是基于moco-runner-0.11.0-standalone.jar,通过编写json的文件来实现,那么我们现在来看python之中的

mock,那么怎么理解mock了,mock翻译过来就是模拟的意思,也就是说,它是将测试对象所依存的对象替换为虚构对象的库,该虚构对象的调用允许事后查看。

在python的2.x版本中,它是属于第三方的库,需要单独的按钮,在python3.3的版本以后,不需要单独的安装,直接导入就可以了,那么我们先看它的安装命令,

安装命令为: pip  install mock 

见安装的截图:

安装好后,在cmd的命令行中进入到python的环境中,可以直接的导入,见操作的截图:

在python3.3以上的版本中,因为是标准库,就不需要单独的按钮,直接导入就可以了,见操作的截图:

     Ok,安装成功后,下来我们来看mock库的经常使用的方法以及它的详细的帮助信息,见获取的代码:

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

import  mock

print u'查看modk库常用的方法:',dir(mock)
print u'查看mock库详细的帮助信息:',type(help(mock))

 

见然上的代码执行后的详细的信息:

C:\Python27\python.exe D:/git/Python/FullStack/PyUnit/xUnit/mockHelp.py
查看modk库常用的方法: ['ANY', 'CallableMixin', 'DEFAULT', 'FILTER_DIR', 'MagicMock', 'Mock', 'NonCallableMagicMock', 'NonCallableMock', 'PropertyMock', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__', '_mock', 'absolute_import', 'call', 'create_autospec', 'mock', 'mock_open', 'patch', 'sentinel', 'version_info']
查看mock库详细的帮助信息:Help on package mock:

NAME
    mock

FILE
    c:\python27\lib\site-packages\mock\__init__.py

PACKAGE CONTENTS
    mock
    tests (package)

SUBMODULES
    _mock

CLASSES
    mock.mock.Base(__builtin__.object)
        mock.mock.CallableMixin
            mock.mock.Mock(mock.mock.CallableMixin, mock.mock.NonCallableMock)
                mock.mock.MagicMock(mock.mock.MagicMixin, mock.mock.Mock)
                mock.mock.PropertyMock
        mock.mock.NonCallableMock
            mock.mock.NonCallableMagicMock(mock.mock.MagicMixin, mock.mock.NonCallableMock)
    mock.mock.MagicMixin(__builtin__.object)
        mock.mock.MagicMock(mock.mock.MagicMixin, mock.mock.Mock)
        mock.mock.NonCallableMagicMock(mock.mock.MagicMixin, mock.mock.NonCallableMock)
    
    class CallableMixin(Base)
     |  Method resolution order:
     |      CallableMixin
     |      Base
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  __call__(_mock_self, *args, **kwargs)
     |  
     |  __init__(self, spec=None, side_effect=None, return_value=sentinel.DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Base:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
    
    class MagicMock(MagicMixin, Mock)
     |  MagicMock is a subclass of Mock with default implementations
     |  of most of the magic methods. You can use MagicMock without having to
     |  configure the magic methods yourself.
     |  
     |  If you use the `spec` or `spec_set` arguments then *only* magic
     |  methods that exist in the spec will be created.
     |  
     |  Attributes and the return value of a `MagicMock` will also be `MagicMocks`.
     |  
     |  Method resolution order:
     |      MagicMock
     |      MagicMixin
     |      Mock
     |      CallableMixin
     |      NonCallableMock
     |      Base
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  mock_add_spec(self, spec, spec_set=False)
     |      Add a spec to a mock. `spec` can either be an object or a
     |      list of strings. Only attributes on the `spec` can be fetched as
     |      attributes from the mock.
     |      
     |      If `spec_set` is True then only attributes on the spec can be set.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from MagicMixin:
     |  
     |  __init__(self, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MagicMixin:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from CallableMixin:
     |  
     |  __call__(_mock_self, *args, **kwargs)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from NonCallableMock:
     |  
     |  __delattr__(self, name)
     |  
     |  __dir__(self)
     |      Filter the output of `dir(mock)` to only useful members.
     |  
     |  __getattr__(self, name)
     |  
     |  __repr__(self)
     |  
     |  __setattr__(self, name, value)
     |  
     |  assert_any_call(self, *args, **kwargs)
     |      assert the mock has been called with the specified arguments.
     |      
     |      The assert passes if the mock has *ever* been called, unlike
     |      `assert_called_with` and `assert_called_once_with` that only pass if
     |      the call is the most recent one.
     |  
     |  assert_called(_mock_self)
     |      assert that the mock was called at least once
     |  
     |  assert_called_once(_mock_self)
     |      assert that the mock was called only once.
     |  
     |  assert_called_once_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called exactly once and with the specified
     |      arguments.
     |  
     |  assert_called_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called with the specified arguments.
     |      
     |      Raises an AssertionError if the args and keyword args passed in are
     |      different to the last call to the mock.
     |  
     |  assert_has_calls(self, calls, any_order=False)
     |      assert the mock has been called with the specified calls.
     |      The `mock_calls` list is checked for the calls.
     |      
     |      If `any_order` is False (the default) then the calls must be
     |      sequential. There can be extra calls before or after the
     |      specified calls.
     |      
     |      If `any_order` is True then the calls can be in any order, but
     |      they must all appear in `mock_calls`.
     |  
     |  assert_not_called(_mock_self)
     |      assert that the mock was never called.
     |  
     |  attach_mock(self, mock, attribute)
     |      Attach a mock as an attribute of this one, replacing its name and
     |      parent. Calls to the attached mock will be recorded in the
     |      `method_calls` and `mock_calls` attributes of this one.
     |  
     |  configure_mock(self, **kwargs)
     |      Set attributes on the mock through keyword arguments.
     |      
     |      Attributes plus return values and side effects can be set on child
     |      mocks using standard dot notation and unpacking a dictionary in the
     |      method call:
     |      
     |      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
     |      >>> mock.configure_mock(**attrs)
     |  
     |  reset_mock(self, visited=None)
     |      Restore the mock object to its initial state.
     |  
     |  ----------------------------------------------------------------------
     |  Static methods inherited from NonCallableMock:
     |  
     |  __new__(cls, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NonCallableMock:
     |  
     |  __class__
     |  
     |  call_args
     |  
     |  call_args_list
     |  
     |  call_count
     |  
     |  called
     |  
     |  mock_calls
     |  
     |  return_value
     |  
     |  side_effect
    
    class Mock(CallableMixin, NonCallableMock)
     |  Create a new `Mock` object. `Mock` takes several optional arguments
     |  that specify the behaviour of the Mock object:
     |  
     |  * `spec`: This can be either a list of strings or an existing object (a
     |    class or instance) that acts as the specification for the mock object. If
     |    you pass in an object then a list of strings is formed by calling dir on
     |    the object (excluding unsupported magic attributes and methods). Accessing
     |    any attribute not in this list will raise an `AttributeError`.
     |  
     |    If `spec` is an object (rather than a list of strings) then
     |    `mock.__class__` returns the class of the spec object. This allows mocks
     |    to pass `isinstance` tests.
     |  
     |  * `spec_set`: A stricter variant of `spec`. If used, attempting to *set*
     |    or get an attribute on the mock that isn't on the object passed as
     |    `spec_set` will raise an `AttributeError`.
     |  
     |  * `side_effect`: A function to be called whenever the Mock is called. See
     |    the `side_effect` attribute. Useful for raising exceptions or
     |    dynamically changing return values. The function is called with the same
     |    arguments as the mock, and unless it returns `DEFAULT`, the return
     |    value of this function is used as the return value.
     |  
     |    Alternatively `side_effect` can be an exception class or instance. In
     |    this case the exception will be raised when the mock is called.
     |  
     |    If `side_effect` is an iterable then each call to the mock will return
     |    the next value from the iterable. If any of the members of the iterable
     |    are exceptions they will be raised instead of returned.
     |  
     |  * `return_value`: The value returned when the mock is called. By default
     |    this is a new Mock (created on first access). See the
     |    `return_value` attribute.
     |  
     |  * `wraps`: Item for the mock object to wrap. If `wraps` is not None then
     |    calling the Mock will pass the call through to the wrapped object
     |    (returning the real result). Attribute access on the mock will return a
     |    Mock object that wraps the corresponding attribute of the wrapped object
     |    (so attempting to access an attribute that doesn't exist will raise an
     |    `AttributeError`).
     |  
     |    If the mock has an explicit `return_value` set then calls are not passed
     |    to the wrapped object and the `return_value` is returned instead.
     |  
     |  * `name`: If the mock has a name then it will be used in the repr of the
     |    mock. This can be useful for debugging. The name is propagated to child
     |    mocks.
     |  
     |  Mocks can also be called with arbitrary keyword arguments. These will be
     |  used to set attributes on the mock after it is created.
     |  
     |  Method resolution order:
     |      Mock
     |      CallableMixin
     |      NonCallableMock
     |      Base
     |      __builtin__.object
     |  
     |  Methods inherited from CallableMixin:
     |  
     |  __call__(_mock_self, *args, **kwargs)
     |  
     |  __init__(self, spec=None, side_effect=None, return_value=sentinel.DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from NonCallableMock:
     |  
     |  __delattr__(self, name)
     |  
     |  __dir__(self)
     |      Filter the output of `dir(mock)` to only useful members.
     |  
     |  __getattr__(self, name)
     |  
     |  __repr__(self)
     |  
     |  __setattr__(self, name, value)
     |  
     |  assert_any_call(self, *args, **kwargs)
     |      assert the mock has been called with the specified arguments.
     |      
     |      The assert passes if the mock has *ever* been called, unlike
     |      `assert_called_with` and `assert_called_once_with` that only pass if
     |      the call is the most recent one.
     |  
     |  assert_called(_mock_self)
     |      assert that the mock was called at least once
     |  
     |  assert_called_once(_mock_self)
     |      assert that the mock was called only once.
     |  
     |  assert_called_once_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called exactly once and with the specified
     |      arguments.
     |  
     |  assert_called_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called with the specified arguments.
     |      
     |      Raises an AssertionError if the args and keyword args passed in are
     |      different to the last call to the mock.
     |  
     |  assert_has_calls(self, calls, any_order=False)
     |      assert the mock has been called with the specified calls.
     |      The `mock_calls` list is checked for the calls.
     |      
     |      If `any_order` is False (the default) then the calls must be
     |      sequential. There can be extra calls before or after the
     |      specified calls.
     |      
     |      If `any_order` is True then the calls can be in any order, but
     |      they must all appear in `mock_calls`.
     |  
     |  assert_not_called(_mock_self)
     |      assert that the mock was never called.
     |  
     |  attach_mock(self, mock, attribute)
     |      Attach a mock as an attribute of this one, replacing its name and
     |      parent. Calls to the attached mock will be recorded in the
     |      `method_calls` and `mock_calls` attributes of this one.
     |  
     |  configure_mock(self, **kwargs)
     |      Set attributes on the mock through keyword arguments.
     |      
     |      Attributes plus return values and side effects can be set on child
     |      mocks using standard dot notation and unpacking a dictionary in the
     |      method call:
     |      
     |      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
     |      >>> mock.configure_mock(**attrs)
     |  
     |  mock_add_spec(self, spec, spec_set=False)
     |      Add a spec to a mock. `spec` can either be an object or a
     |      list of strings. Only attributes on the `spec` can be fetched as
     |      attributes from the mock.
     |      
     |      If `spec_set` is True then only attributes on the spec can be set.
     |  
     |  reset_mock(self, visited=None)
     |      Restore the mock object to its initial state.
     |  
     |  ----------------------------------------------------------------------
     |  Static methods inherited from NonCallableMock:
     |  
     |  __new__(cls, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NonCallableMock:
     |  
     |  __class__
     |  
     |  call_args
     |  
     |  call_args_list
     |  
     |  call_count
     |  
     |  called
     |  
     |  mock_calls
     |  
     |  return_value
     |  
     |  side_effect
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Base:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
    
    class NonCallableMagicMock(MagicMixin, NonCallableMock)
     |  A version of `MagicMock` that isn't callable.
     |  
     |  Method resolution order:
     |      NonCallableMagicMock
     |      MagicMixin
     |      NonCallableMock
     |      Base
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  mock_add_spec(self, spec, spec_set=False)
     |      Add a spec to a mock. `spec` can either be an object or a
     |      list of strings. Only attributes on the `spec` can be fetched as
     |      attributes from the mock.
     |      
     |      If `spec_set` is True then only attributes on the spec can be set.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from MagicMixin:
     |  
     |  __init__(self, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MagicMixin:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from NonCallableMock:
     |  
     |  __delattr__(self, name)
     |  
     |  __dir__(self)
     |      Filter the output of `dir(mock)` to only useful members.
     |  
     |  __getattr__(self, name)
     |  
     |  __repr__(self)
     |  
     |  __setattr__(self, name, value)
     |  
     |  assert_any_call(self, *args, **kwargs)
     |      assert the mock has been called with the specified arguments.
     |      
     |      The assert passes if the mock has *ever* been called, unlike
     |      `assert_called_with` and `assert_called_once_with` that only pass if
     |      the call is the most recent one.
     |  
     |  assert_called(_mock_self)
     |      assert that the mock was called at least once
     |  
     |  assert_called_once(_mock_self)
     |      assert that the mock was called only once.
     |  
     |  assert_called_once_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called exactly once and with the specified
     |      arguments.
     |  
     |  assert_called_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called with the specified arguments.
     |      
     |      Raises an AssertionError if the args and keyword args passed in are
     |      different to the last call to the mock.
     |  
     |  assert_has_calls(self, calls, any_order=False)
     |      assert the mock has been called with the specified calls.
     |      The `mock_calls` list is checked for the calls.
     |      
     |      If `any_order` is False (the default) then the calls must be
     |      sequential. There can be extra calls before or after the
     |      specified calls.
     |      
     |      If `any_order` is True then the calls can be in any order, but
     |      they must all appear in `mock_calls`.
     |  
     |  assert_not_called(_mock_self)
     |      assert that the mock was never called.
     |  
     |  attach_mock(self, mock, attribute)
     |      Attach a mock as an attribute of this one, replacing its name and
     |      parent. Calls to the attached mock will be recorded in the
     |      `method_calls` and `mock_calls` attributes of this one.
     |  
     |  configure_mock(self, **kwargs)
     |      Set attributes on the mock through keyword arguments.
     |      
     |      Attributes plus return values and side effects can be set on child
     |      mocks using standard dot notation and unpacking a dictionary in the
     |      method call:
     |      
     |      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
     |      >>> mock.configure_mock(**attrs)
     |  
     |  reset_mock(self, visited=None)
     |      Restore the mock object to its initial state.
     |  
     |  ----------------------------------------------------------------------
     |  Static methods inherited from NonCallableMock:
     |  
     |  __new__(cls, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NonCallableMock:
     |  
     |  __class__
     |  
     |  call_args
     |  
     |  call_args_list
     |  
     |  call_count
     |  
     |  called
     |  
     |  mock_calls
     |  
     |  return_value
     |  
     |  side_effect
    
    class NonCallableMock(Base)
     |  A non-callable version of `Mock`
     |  
     |  Method resolution order:
     |      NonCallableMock
     |      Base
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  __delattr__(self, name)
     |  
     |  __dir__(self)
     |      Filter the output of `dir(mock)` to only useful members.
     |  
     |  __getattr__(self, name)
     |  
     |  __init__(self, spec=None, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs)
     |  
     |  __repr__(self)
     |  
     |  __setattr__(self, name, value)
     |  
     |  assert_any_call(self, *args, **kwargs)
     |      assert the mock has been called with the specified arguments.
     |      
     |      The assert passes if the mock has *ever* been called, unlike
     |      `assert_called_with` and `assert_called_once_with` that only pass if
     |      the call is the most recent one.
     |  
     |  assert_called(_mock_self)
     |      assert that the mock was called at least once
     |  
     |  assert_called_once(_mock_self)
     |      assert that the mock was called only once.
     |  
     |  assert_called_once_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called exactly once and with the specified
     |      arguments.
     |  
     |  assert_called_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called with the specified arguments.
     |      
     |      Raises an AssertionError if the args and keyword args passed in are
     |      different to the last call to the mock.
     |  
     |  assert_has_calls(self, calls, any_order=False)
     |      assert the mock has been called with the specified calls.
     |      The `mock_calls` list is checked for the calls.
     |      
     |      If `any_order` is False (the default) then the calls must be
     |      sequential. There can be extra calls before or after the
     |      specified calls.
     |      
     |      If `any_order` is True then the calls can be in any order, but
     |      they must all appear in `mock_calls`.
     |  
     |  assert_not_called(_mock_self)
     |      assert that the mock was never called.
     |  
     |  attach_mock(self, mock, attribute)
     |      Attach a mock as an attribute of this one, replacing its name and
     |      parent. Calls to the attached mock will be recorded in the
     |      `method_calls` and `mock_calls` attributes of this one.
     |  
     |  configure_mock(self, **kwargs)
     |      Set attributes on the mock through keyword arguments.
     |      
     |      Attributes plus return values and side effects can be set on child
     |      mocks using standard dot notation and unpacking a dictionary in the
     |      method call:
     |      
     |      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
     |      >>> mock.configure_mock(**attrs)
     |  
     |  mock_add_spec(self, spec, spec_set=False)
     |      Add a spec to a mock. `spec` can either be an object or a
     |      list of strings. Only attributes on the `spec` can be fetched as
     |      attributes from the mock.
     |      
     |      If `spec_set` is True then only attributes on the spec can be set.
     |  
     |  reset_mock(self, visited=None)
     |      Restore the mock object to its initial state.
     |  
     |  ----------------------------------------------------------------------
     |  Static methods defined here:
     |  
     |  __new__(cls, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |  
     |  __class__
     |  
     |  call_args
     |  
     |  call_args_list
     |  
     |  call_count
     |  
     |  called
     |  
     |  mock_calls
     |  
     |  return_value
     |  
     |  side_effect
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Base:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
    
    class PropertyMock(Mock)
     |  A mock intended to be used as a property, or other descriptor, on a class.
     |  `PropertyMock` provides `__get__` and `__set__` methods so you can specify
     |  a return value when it is fetched.
     |  
     |  Fetching a `PropertyMock` instance from an object calls the mock, with
     |  no args. Setting it calls the mock with the value being set.
     |  
     |  Method resolution order:
     |      PropertyMock
     |      Mock
     |      CallableMixin
     |      NonCallableMock
     |      Base
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  __get__(self, obj, obj_type)
     |  
     |  __set__(self, obj, val)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from CallableMixin:
     |  
     |  __call__(_mock_self, *args, **kwargs)
     |  
     |  __init__(self, spec=None, side_effect=None, return_value=sentinel.DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from NonCallableMock:
     |  
     |  __delattr__(self, name)
     |  
     |  __dir__(self)
     |      Filter the output of `dir(mock)` to only useful members.
     |  
     |  __getattr__(self, name)
     |  
     |  __repr__(self)
     |  
     |  __setattr__(self, name, value)
     |  
     |  assert_any_call(self, *args, **kwargs)
     |      assert the mock has been called with the specified arguments.
     |      
     |      The assert passes if the mock has *ever* been called, unlike
     |      `assert_called_with` and `assert_called_once_with` that only pass if
     |      the call is the most recent one.
     |  
     |  assert_called(_mock_self)
     |      assert that the mock was called at least once
     |  
     |  assert_called_once(_mock_self)
     |      assert that the mock was called only once.
     |  
     |  assert_called_once_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called exactly once and with the specified
     |      arguments.
     |  
     |  assert_called_with(_mock_self, *args, **kwargs)
     |      assert that the mock was called with the specified arguments.
     |      
     |      Raises an AssertionError if the args and keyword args passed in are
     |      different to the last call to the mock.
     |  
     |  assert_has_calls(self, calls, any_order=False)
     |      assert the mock has been called with the specified calls.
     |      The `mock_calls` list is checked for the calls.
     |      
     |      If `any_order` is False (the default) then the calls must be
     |      sequential. There can be extra calls before or after the
     |      specified calls.
     |      
     |      If `any_order` is True then the calls can be in any order, but
     |      they must all appear in `mock_calls`.
     |  
     |  assert_not_called(_mock_self)
     |      assert that the mock was never called.
     |  
     |  attach_mock(self, mock, attribute)
     |      Attach a mock as an attribute of this one, replacing its name and
     |      parent. Calls to the attached mock will be recorded in the
     |      `method_calls` and `mock_calls` attributes of this one.
     |  
     |  configure_mock(self, **kwargs)
     |      Set attributes on the mock through keyword arguments.
     |      
     |      Attributes plus return values and side effects can be set on child
     |      mocks using standard dot notation and unpacking a dictionary in the
     |      method call:
     |      
     |      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
     |      >>> mock.configure_mock(**attrs)
     |  
     |  mock_add_spec(self, spec, spec_set=False)
     |      Add a spec to a mock. `spec` can either be an object or a
     |      list of strings. Only attributes on the `spec` can be fetched as
     |      attributes from the mock.
     |      
     |      If `spec_set` is True then only attributes on the spec can be set.
     |  
     |  reset_mock(self, visited=None)
     |      Restore the mock object to its initial state.
     |  
     |  ----------------------------------------------------------------------
     |  Static methods inherited from NonCallableMock:
     |  
     |  __new__(cls, *args, **kw)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from NonCallableMock:
     |  
     |  __class__
     |  
     |  call_args
     |  
     |  call_args_list
     |  
     |  call_count
     |  
     |  called
     |  
     |  mock_calls
     |  
     |  return_value
     |  
     |  side_effect
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from Base:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)

FUNCTIONS
    create_autospec(spec, spec_set=False, instance=False, _parent=None, _name=None, **kwargs)
        Create a mock object using another object as a spec. Attributes on the
        mock will use the corresponding attribute on the `spec` object as their
        spec.
        
        Functions or methods being mocked will have their arguments checked
        to check that they are called with the correct signature.
        
        If `spec_set` is True then attempting to set attributes that don't exist
        on the spec object will raise an `AttributeError`.
        
        If a class is used as a spec then the return value of the mock (the
        instance of the class) will have the same spec. You can use a class as the
        spec for an instance object by passing `instance=True`. The returned mock
        will only be callable if instances of the mock are callable.
        
        `create_autospec` also takes arbitrary keyword arguments that are passed to
        the constructor of the created mock.
    
    mock_open(mock=None, read_data='')
        A helper function to create a mock to replace the use of `open`. It works
        for `open` called directly or used as a context manager.
        
        The `mock` argument is the mock object to configure. If `None` (the
        default) then a `MagicMock` will be created for you, with the API limited
        to methods or attributes available on standard file handles.
        
        `read_data` is a string for the `read` methoddline`, and `readlines` of the
        file handle to return.  This is an empty string by default.
    
    patch(target, new=sentinel.DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
        `patch` acts as a function decorator, class decorator or a context
        manager. Inside the body of the function or with statement, the `target`
        is patched with a `new` object. When the function/with statement exits
        the patch is undone.
        
        If `new` is omitted, then the target is replaced with a
        `MagicMock`. If `patch` is used as a decorator and `new` is
        omitted, the created mock is passed in as an extra argument to the
        decorated function. If `patch` is used as a context manager the created
        mock is returned by the context manager.
        
        `target` should be a string in the form `'package.module.ClassName'`. The
        `target` is imported and the specified object replaced with the `new`
        object, so the `target` must be importable from the environment you are
        calling `patch` from. The target is imported when the decorated function
        is executed, not at decoration time.
        
        The `spec` and `spec_set` keyword arguments are passed to the `MagicMock`
        if patch is creating one for you.
        
        In addition you can pass `spec=True` or `spec_set=True`, which causes
        patch to pass in the object being mocked as the spec/spec_set object.
        
        `new_callable` allows you to specify a different class, or callable object,
        that will be called to create the `new` object. By default `MagicMock` is
        used.
        
        A more powerful form of `spec` is `autospec`. If you set `autospec=True`
        then the mock will be created with a spec from the object being replaced.
        All attributes of the mock will also have the spec of the corresponding
        attribute of the object being replaced. Methods and functions being
        mocked will have their arguments checked and will raise a `TypeError` if
        they are called with the wrong signature. For mocks replacing a class,
        their return value (the 'instance') will have the same spec as the class.
        
        Instead of `autospec=True` you can pass `autospec=some_object` to use an
        arbitrary object as the spec instead of the one being replaced.
        
        By default `patch` will fail to replace attributes that don't exist. If
        you pass in `create=True`, and the attribute doesn't exist, patch will
        create the attribute for you when the patched function is called, and
        delete it again afterwards. This is useful for writing tests against
        attributes that your production code creates at runtime. It is off by
        default because it can be dangerous. With it switched on you can write
        passing tests against APIs that don't actually exist!
        
        Patch can be used as a `TestCase` class decorator. It works by
        decorating each test method in the class. This reduces the boilerplate
        code when your test methods share a common patchings set. `patch` finds
        tests by looking for method names that start with `patch.TEST_PREFIX`.
        By default this is `test`, which matches the way `unittest` finds tests.
        You can specify an alternative prefix by setting `patch.TEST_PREFIX`.
        
        Patch can be used as a context manager, with the with statement. Here the
        patching applies to the indented block after the with statement. If you
        use "as" then the patched object will be bound to the name after the
        "as"; very useful if `patch` is creating a mock object for you.
        
        `patch` takes arbitrary keyword arguments. These will be passed to
        the `Mock` (or `new_callable`) on construction.
        
        `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are
        available for alternate use-cases.

DATA
    ANY = <ANY>
    DEFAULT = sentinel.DEFAULT
    FILTER_DIR = True
    __all__ = ('__version__', 'version_info', 'Mock', 'MagicMock', 'patch'...
    __version__ = '2.0.0'
    call = call
    sentinel = <mock.mock._Sentinel object>
    version_info = (2, 0, 0, 'final', 0)

VERSION
    2.0.0


<type 'NoneType'>

Process finished with exit code 0
View Code

mock详细的学习文档可以参考官方的文档,官方地址:http://www.voidspace.org.uk/python/mock/mock.html

       下面我们首先来看一个例子,来引入mock,来查看它解决什么问题,以及我们为什么需要mock,知道了这些以后,我们再详细的探讨mock它详细的使用。

我们编写如下的一个方法,它要实现的是删除一个C盘下的文件夹,而该文件夹就是Windows文件夹,见该代码:

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


import  mock
import  os

class Remove(object):

    def rmdir(self,path='c:/Windows'):
        os.rmdir(path)

 

如果我们要测试rmdir()的方法,那么执行的就是我们每测试一次,就得删除一次文件夹,这样我们的测试结果是通过的,另外有这么几个点需要考虑,第一就是该文件

夹是否可删除,如果删除,引起系统出问题如何处理?第二是删除该文件夹的时候,是否已经创建了,难道我们每次删除一次,就得判断是否存在,是否创建,再做删

除的操作?很显然这样的一个测试过程,最难的不是第二个问题,而是第一个文件,C盘下的Windows文件夹可以正常的删除吗?可以做删除的操作吗?答案是不可以

的,因为我们的系统盘就是C盘下,而Windows文件夹里面储存了很多的系统文件,绝对不允许删除,那么我们如何测试了,这个时候,就需要mock,也就是模拟,

我们再写一个方法,模拟rmdir()方法的执行,见更新后的代码:

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

import  mock
import  os

class Remove(object):

    def rmdir(self,path='c:/Windows'):
        r=os.rmdir(path)
        if r==None :
            return u'删除成功'
        else:
            return u'Sorry,删除失败'

    def exists_get_rmdir(self):
        return self.rmdir()

 

见测试的代码:

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


import  mock
import  os
import  unittest


class Remove(object):

    def rmdir(self,path='c:/log'):
        r=os.rmdir(path)
        if r==None :
            return 'success'
        else:
            return 'fail'

    def exists_get_rmdir(self):
        return self.rmdir()


class MockTest(unittest.TestCase):
    def setUp(self):
        self.r=Remove()


    def tearDown(self):
        pass

    def test_success_rmdir(self):
        '''
        删除目录成功
        :return:
        '''
        success_path=mock.Mock(return_value='success')
        self.r.rmdir=success_path
        self.assertEqual(self.r.exists_get_rmdir(),'success')

    def test_fail_rmdir(self):
        '''
        删除目录失败
        :return:
        '''
        fail_path=mock.Mock(return_value='fail')
        self.r.rmdir=fail_path
        self.assertEqual(self.r.exists_get_rmdir(),'fail')

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

 

执行如上的代码的时候,我们就不需要考虑是否存在该文件夹,以及该文件夹是否可正常的删除,我们完全使用mock来解决了这个问题,那么我们来看它的执行顺序:

1、找到替换的对象,我们需要测试的是exists_get_imdir()方法,那么我们就需要替换掉rmdir()方法

2、对Mock类进行实例化对象得到mock,并且设置这个mock的行为return_value值,也就是mock虚构对象,在测试通过中,我们虚构return_value为'success',在测试不通过我们虚构return_value为'fail'

3、使用mock对象我们想替换的方法rmdir(),这样我们就替换到了self.r.rmdir

4、编写测试代码,进行断言,我们调用self.r.exists_get_imdir()方法,并且期望它的返回值与我们预期的结果一致(不管是成功的还是失败的),使用mock虚构对象,比如我们案例使用的Mock(return_value='success'),它是一个什么样的形式了,如果我们使用函数怎么样编写,下来我们详细的来实现这个过程:

见如下模拟类当中的方法,见实现的案例代码:

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

import  mock

mock=mock.Mock()
mock.info.return_value='Hello Mock'
print mock.info()

class F:
    def info(self):
        return 'Hello Mock'

f=F()
print f.info()

 

 
posted @ 2019-06-11 16:06  拼搏_90  阅读(977)  评论(0编辑  收藏  举报