简体   繁体   English

如何对运行芹菜任务的代码进行单元测试?

[英]How to unit test code that runs celery tasks?

The app I am working on is heavily asynchronous.我正在开发的应用程序是高度异步的。 The web application runs a lot of tasks through celery depending on user actions. Web 应用程序根据用户操作通过 celery 运行许多任务。 The celery tasks themselves are capable of launching further tasks. celery 任务本身能够启动进一步的任务。

Code such as the one shown below occurs in our code base quite frequently.如下所示的代码在我们的代码库中经常出现。

def do_sth():
    logic();
    if condition:
         function1.apply_async(*args)
    else:
         function2.apply_asynch(*args)

Now we want to start unit testing any new code that we write and we are not sure how to do this.现在我们想开始对我们编写的任何新代码进行单元测试,但我们不确定如何执行此操作。 What we would like to assert in our pytest unit tests is that we want to see if function1 actually got called.我们想在我们的pytest单元测试中断言我们想看看 function1 是否真的被调用了。 We do not want to necessarily run function1 itself as we will have a unit test for the function1 .我们不希望一定运行function1本身,我们将会对单元测试function1

I do not want to be running celery as a process, neither do I want to run any AMQP broker during the unit test session.我不想将 celery 作为一个进程运行,我也不想在单元测试会话期间运行任何 AMQP 代理。

Is this achievable?这是可以实现的吗?

Edit编辑

It was pointed out that this is a duplicate of How do you unit test a Celery task?有人指出,这是如何对 Celery 任务进行单元测试?

It is not.它不是。 Think about it.想想看。 What I am asking is how to test if function has called function1 through apply_async.我要问的是如何测试函数是否通过 apply_async 调用了function1 That question is about how do I test function1 itself.这个问题是关于我如何测试function1本身。 There is a major difference.有很大的不同。 I did hit that question before framing this one.在制定这个问题之前,我确实遇到了这个问题。

Have a look at the unittest.mock module which allows replacing functions you don't want to be invoked with "mocks" which look sufficiently similar to the original functions to convince the calling code that it's invoking the "real thing".看看unittest.mock模块,它允许用“模拟”替换您不想调用的函数,这些“模拟”看起来与原始函数非常相似,以说服调用代码它正在调用“真实的东西”。 You can then check that the mock was actually invoked and with what parameters.然后,您可以检查是否实际调用了模拟以及使用了哪些参数。 Example:例子:

from unittest.mock import patch

def test_do_sth():
    with patch('function1.apply_async') as function1_mock:
        do_sth()
        assert function1_mock.called

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM