集成测试多个芹菜工人和数据库支持的Django API

时间:2014-05-02 15:09:40

标签: python django integration celery

我正在使用面向软件的架构,该架构有多个芹菜工人(我们称之为worker1worker2worker3)。所有三个工作者都是独立的实体(即,单独的代码库,单独的存储库,单独的芹菜实例,单独的机器),并且它们都没有连接到Django应用程序。

与这三个工作者中的每一个进行通信是基于Django的MySQL支持的RESTful API。

在开发过程中,这些服务都在一个流浪盒上,每个服务器都作为一个独立的机器运行。我们有一个RabbitMQ代理可以完成所有Celery任务。

通过这些服务的典型路径可能如下所示:worker1从设备获取消息,进行一些处理,在worker2上排队任务,进行进一步处理并进行POST到API,它写入MySQL数据库并触发worker3上的任务,该任务执行一些其他处理并对API进行另一次POST,从而导致MySQL写入。

服务正在很好地沟通,但每次我们对任何服务进行更改时测试此流程都非常烦人。我真的希望得到一些完整的集成测试(即,从发送到worker1并通过整个链的消息开始),但我不知道从哪里开始。我面临的主要问题是:

如果我在worker1上排队,我怎么能分辨出整个流程何时结束?当我不知道结果是否已经到达时,我怎样才能对结果做出合理的断言?

如何处理数据库设置/拆除?我希望在每次测试结束时删除测试期间所有条目,但如果我从Django应用程序外部开始测试,我不确定如何有效地清除它。手动删除它并在每次测试后重新创建它似乎可能是太多的开销。

2 个答案:

答案 0 :(得分:3)

Celery允许同步运行任务,因此第一步是:将整个流程划分为单独的任务,伪造请求和断言结果:

原始流程:

device --- worker1 --- worker2 --- django --- worker3 --- django

第一级集成测试:

1.      |- worker1 -|
2.                  |- worker2 -|
3.                              |- django -|
4.                                         |- worker3 -|
5.                                                     |- django -|

对于每个测试,创建虚假请求或同步调用并断言结果。将这些测试放在相应的存储库中例如,在worker1的测试中,您可以模拟worker2并测试它是否已使用适当的参数调用。然后,在另一个测试中,您将调用worker2和模拟请求来检查它是否正确调用API。等等。

测试整个流程将很困难,因为所有任务都是独立的实体。我现在唯一想到的方法就是对worker1进行一次虚假调用,设置合理的超时并等待数据库中的最终结果。此类测试仅告诉您它是否有效。它不会告诉你,问题出在哪里。

答案 1 :(得分:0)

要使用完整设置,您可以设置Celery结果后端。 有关基础知识,请参阅Celery 'next steps'文档。

然后,

worker1可以报告传递给worker2的任务句柄。 worker2返回的结果将是传递给worker3的任务ID。 worker3返回的结果意味着整个序列已完成,您可以检查结果。 结果还可以立即报告这些结果的有趣部分,以便更容易进行检查。

这可能在Celery中看起来像一样

worker1_result = mytask.delay(someargs)  # executed by worker1
worker2_result = worker1_result.get()  # waits for worker1 to finish
worker3_result = worker2_result.get()  # waits for worker2 to finish
outcome = worker3_result.get()  # waits for worker3 to finish

(细节可能需要不同;我自己还没有使用过。我不确定任务结果是否可序列化,因此它们本身适合作为任务函数返回值。)