2

我有一个相当复杂的应用程序,它使用 celery、mongo、redis 和 pyramid。我用鼻子进行测试。我没有做 TDD(至少不是测试优先),但我正在努力获得相当大的覆盖率。我被困在与上述某些服务集成的部分中。比如我用redis做celery任务之间的共享内存,但是我希望能够切换到memcache而不用太麻烦,所以我抽象出了以下函数:

import settings
db = StrictRedis(host=settings.db_uri, db=settings.db_name)

def has_task(correlation_id):
    """Return True if a task exists in db."""
    return db.exists(str(correlation_id))

def pop_task(correlation_id):
    """Get a task from db by correlation_id."""
    correlation_id = str(correlation_id) # no unicode allowed
    task_pickle = db.get(correlation_id)
    task = loads(task_pickle)
    if task:
        db.delete(correlation_id)
    return task

def add_task(correlation_id, task_id, model):
    """Add a task to db"""
    return db.set(str(correlation_id), dumps((task_id, model)))

我也在做类似的事情来抽象 Mongo,我用它来进行持久存储。

我见过用于运行虚拟 http 服务器、创建虚拟请求甚至虚拟数据库的集成 Web 应用程序的测试套件。我对 celery 和 pyramid没问题,但是我找不到 mongo 和 redis 的假人,所以我只能在这些服务实际运行时运行上述测试。有没有办法为上述提供虚拟服务所以我没有

  1. 安装并运行外部服务,以及
  2. 手动创建和销毁整个数据库(可以指望内存中的假人自行清理)
4

1 回答 1

2

我建议您将模拟库用于此类任务。这允许您用一些伪对象替换您的生产对象(例如数据库连接),这些伪对象可以提供一些测试所需的功能。

例子:

>>> from mock import Mock
>>> db = Mock()
>>> db.exists.return_value = True
>>> db.exists()
True

您可以断言您的代码如何与模拟交互,例如:

>>> db.delete(1)
<Mock name='mock.delete()' id='37588880'>
>>> db.delete.assert_called_with(1)
>>> db.delete.assert_called_with(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\mock.py", line 863, in assert_called_with
    raise AssertionError(msg)
AssertionError: Expected call: delete(2)
Actual call: delete(1)
于 2012-06-05T07:38:11.947 回答