简体   繁体   English

使用 pytest 测试模块执行

[英]Testing module execution with pytest

I have a python module that gets executed as python -m my_package.my_module --arg1 a1 --arg2 a2 .我有一个 python 模块,它被执行为python -m my_package.my_module --arg1 a1 --arg2 a2 Which creates an artifact on the local disk and uploads that artifact to a cloud bucket.这会在本地磁盘上创建一个工件并将该工件上传到云存储桶。

My module essentially looks like this我的模块基本上是这样的

import argparse

def func():
    # parse args
    # create artifact
    # upload to bucket

func()

I'd like to write a test for this module which I can run from a different script, say test_module.py .我想为这个模块编写一个测试,我可以从不同的脚本运行,比如test_module.py I would like to mock the cloud api so nothing gets uploaded, but also provide a set of test command line args to the module.我想模拟云 api 所以没有上传任何东西,但也为模块提供一组测试命令行参数。

So far I can do something like this到目前为止我可以做这样的事情

#test_module.py
from unittest import mock

def test_my_module():
    test_args = # [  test args ]
    with mock.patch.object(sys, 'argv', test_args):
        import my_package.my_module
        # test file is written to local dir

The problem here is that I can't mock the cloud api without first importing my_package.my_module which runs the code in the module and uploads the artifact.这里的问题是,如果不先导入运行模块中的代码并上传工件的my_package.my_module ,我就无法模拟云 api。 And if I do something like this如果我这样做

#test_module.py
from unittest import mock
import my_package.my_module

@mock.patch('my_package.my_module.cloud_client')
def test_my_module():
    # run test

Then the code will execute on the first import statement import my_package.my_module .然后代码将在第一个导入语句import my_package.my_module上执行。 Is there a solution where I can mock an object before importing the module it's located in?有没有解决方案,我可以在导入它所在的模块之前模拟 object?

Use the idiomatic solution to this exact problem:使用惯用的解决方案来解决这个确切的问题:

import argparse

def func():
    # parse args
    # create artifact
    # upload to bucket

# Ensure this function only runs when this module is being executed as main, not when imported.
if __name__ == '__main__':
    func()

You can find more details here: What does if __name__ == "__main__": do?您可以在此处找到更多详细信息: What does if __name__ == "__main__": do?

After your module is imported (but not run) in the test, you can setup your mock & perform the test.在测试中导入(但未运行)模块后,您可以设置模拟并执行测试。

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

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