如何在我的测试套件中单击以获取命令/子命令的列表?

时间:2019-05-15 13:48:22

标签: python command-line-interface pytest python-click

我有一个使用分组命令和子命令的CLI应用程序。一切正常。但是,我想确保将来仍然如此,所以我想确保所有命令和子命令都已正确加载。

我首先想到的是运行

commands = ["config", "othercommand"]
runner = CliRunner()
result = runner.invoke(cli.main)
for command in commands:
    assert command in result.output

从我的角度来看,这有一些陷阱。

  • 这要求我每次添加新commands时都要进行更新。我希望能够自动生成它。
  • 如果我有一个在帮助测试中会出现的相对通用的命令(即config),则可能会得到错误的结果。
  • 我不知道如何优雅地处理每个子命令。

我的应用程序的布局如下:

@click.group()
def main():
    """My entry point"""

@click.group()
def config():
    """config group"""

@config.command()
def add_config():
    """this is a subcommand to config"""

@click.group()
def othercommand():
    """othercommand group"""

@othercommand.command()
def do_thing():
    """this is a subcommand to othercommand"""

我的问题:有没有办法获取我可以使用的所有命令(和子命令)的列表,并从我的测试套件中执行此操作?最好不要进行所有周围的帮助测试,这样我就可以消除错误的结果。

1 个答案:

答案 0 :(得分:1)

可以对cli进行自省,使其结构如下:

代码:

def command_tree(obj):
    if isinstance(obj, click.Group):
        return {name: command_tree(value)
                for name, value in obj.commands.items()}

测试代码:

import click

@click.group()
def main():
    """My entry point"""

@main.group()
def config():
    """config group"""

@config.command()
def add_config():
    """this is a subcommand to config"""

@main.group()
def othercommand():
    """othercommand group"""


@othercommand.command()
def do_thing():
    """this is a subcommand to othercommand"""


print(command_tree(main))

结果:

{'config': {'add_config': None}, 'othercommand': {'do_thing': None}}