1.关于单元测试的思考
怎样对游戏进行单元测试是我在一直思考的问题,我们的游戏服务端是用Python写的,我们开发的测试方式确实很原始,服务端游戏逻辑写完后,都要借助于客户端链接上服务器,然后利用GM指令,或者其他蹩脚的方式才能测试服务端的逻辑是否正确,这个过程存在很多显而易见的弊端:
- 测试流程太过繁琐,并且测试点有可能不全面
- 没有规范的单元测试,自动化测试也很难实施
- 单元测试也是理解代码逻辑的一种方式,如果单元测试都没有,理解代码的渠道就少了一层
目前的困难:
- Python2.7 有自己的单元测试框架,可以好好的利用这个模块,怎样将此模块与游戏逻辑结合在一起也是要仔细考虑的问题
- 依赖于客户端的登录是因为一个模块的逻辑依赖于很多其他模块,使用客户端端登录,其他模块自然也就存在了,怎样摆脱客户端,完全在服务端进行单元测试也是一个难点
- 单元测试模块怎样构建,怎样可扩展
单元测试我也是最近开始研究,这篇博文不仅写给大家,也写给我自己。我也将会将自己对单元测试的理解写成一个系列,今天先来说说对Python Mock模块的理解。
2.Python Mock
Mock模块在Python3.3被加入到Python标准库中,如果Python2.x要使用Mock模块可以使用pip进行安装。
> sudo pip install mock
先罗列一下Mock模块的几个关键的内容:
- Mock类本身
- MagicMock
- patch修饰器
3.Mock
介绍Mock模块首先要说一下Mock类,Mock类的构造函数如下:
class Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
个人比较关注如下几个参数:
spec
spec的参数可以是一个Python类。
>>> class Foo(object):
... val_a = 1
... def func_a(self):
... print "call in func_a"
...
>>> m = Mock(spec = Foo)
>>> m.val_a
<Mock name='mock.val_a' id='4501041936'>
>>> m.func_a()
<Mock name='mock.func_a()' id='4501044176'>
>>> m.func_b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mock/mock.py", line 717, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'func_b'
Foo类有一个参数val_a和方法func_a,实例m调用val_a和func_a都没有问题,但是调用Foo没有的参数或者方法则会抛出AttributeError异常。
return_value
return_value定义mock被调用时的返回值。
>>> m = Mock(return_value = 1)
>>> m
<Mock id='4501997840'>
>>> m()
1
side_effect
side_effect和return_value正好相反,side_effect赋值后,mock的调用将会是side_effect的内容。side_effect可以是一个exception,也可以是一个可迭代的实例。
>>> li = [1,2,3]
>>> m = Mock(side_effect = li)
>>> m()
1
>>> m()
2
>>> m()
3
>>> m()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mock/mock.py", line 1063, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "mock/mock.py", line 1122, in _mock_call
result = next(effect)
File "mock/mock.py", line 127, in next
return _next(obj)
StopIteration
Reference
- 使用 Python Mock 类进行单元测试 - http://www.oschina.net/translate/unit-testing-with-the-python-mock-class
- Python Mock Doc - https://docs.python.org/3/library/unittest.mock.html