我试图将参数从pytest测试用例传递到要测试的模块。例如,使用Python boilerplate中的main.py,我可以在命令行中以如下方式运行它:
[√] Flutter (Channel beta, v1.0.0, on Microsoft Windows [Version 10.0.17134.472], locale ko-KR)
• Flutter version 1.0.0 at C:\flutter
• Framework revision 5391447fae (5 weeks ago), 2018-11-29 19:41:26 -0800
• Engine revision 7375a0f414
• Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
[√] Android toolchain - develop for Android devices (Android SDK 28.0.3)
• Android SDK at C:\AndroidSDK
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• ANDROID_HOME = C:\AndroidSDK
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
• All Android licenses accepted.
[√] Android Studio (version 3.2)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 31.3.1
• Dart plugin version 181.5656
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
[!] IntelliJ IDEA Community Edition (version 2018.2)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.2
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.io/intellij-setup/#installing-the-plugins
[!] VS Code, 64-bit edition (version 1.30.1)
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
现在,我尝试使用以下test_sample.py
对pytest进行相同操作(注意::main.py需要命令行参数。但是这些参数需要在特定测试中进行硬编码,它们不应该是pytest的命令行参数。pytest测试用例只需要将这些值作为命令行参数发送到main.main()。)
$ python3 main.py
usage: main.py [-h] [-f] [-n NAME] [-v] [--version] arg
main.py: error: the following arguments are required: arg
$ python3 main.py xx
hello world
Namespace(arg='xx', flag=False, name=None, verbose=0)
并以以下方式运行测试:
import main
def test_case01():
main.main()
# I dont know how to pass 'xx' to main.py,
# so for now I just have one test with no arguments
这失败,并显示错误消息。我尝试查看其他答案以寻求解决方案,但无法使用它们。例如,42778124建议创建一个单独的文件run.py,这不是一件好事。并且48359957和40880259似乎更多地处理pytest的命令行参数,而不是将命令行参数传递给主代码。
我不需要pytest接受命令行参数,这些参数可以在特定测试中进行硬编码。但是这些参数需要作为参数传递给主代码。你能给我一个test_sample.py,它带有一些参数调用main.main()吗?
答案 0 :(得分:2)
如果您无法修改main
方法的签名,则可以使用monkeypatching技术将参数临时替换为测试数据。示例:想象为以下程序编写测试:
import argparse
def main():
parser = argparse.ArgumentParser(description='Greeter')
parser.add_argument('name')
args = parser.parse_args()
return f'hello {args.name}'
if __name__ == '__main__':
print(main())
从命令行运行时:
$ python greeter.py world
hello world
要使用某些自定义数据测试main
函数,请猴子补丁sys.argv
:
import sys
import greeter
def test_greeter(monkeypatch):
with monkeypatch.context() as m:
m.setattr(sys, 'argv', ['greeter', 'spam'])
assert greeter.main() == 'hello spam'
与parametrizing技术结合使用时,可以轻松测试不同的参数而无需修改测试函数:
import sys
import pytest
import greeter
@pytest.mark.parametrize('name', ['spam', 'eggs', 'bacon'])
def test_greeter(monkeypatch, name):
with monkeypatch.context() as m:
m.setattr(sys, 'argv', ['greeter', name])
assert greeter.main() == 'hello ' + name
现在您将获得三个测试,每个参数一个:
$ pytest -v test_greeter.py
...
test_greeter.py::test_greeter[spam] PASSED
test_greeter.py::test_greeter[eggs] PASSED
test_greeter.py::test_greeter[bacon] PASSED
答案 1 :(得分:0)
一个好的实践可能是拥有这种代码,而不是从main方法中读取参数。
# main.py
def main(arg1):
return arg1
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='My awesome script')
parser.add_argument('word', help='a word')
args = parser.parse_args()
main(args.word)
这样,您的主要方法可以轻松地在pytest中进行测试
import main
def test_case01():
main.main(your_hardcoded_arg)
除了使用os
模块外,我不确定是否可以调用python脚本进行测试,