Spec-Zone.ru › click

Тестирование приложений Click

Для базового тестирования Click предоставляет модуль click.testing , который предоставляет функциональность для тестирования, помогающую вызывать командные приложения и проверять их поведение.

Эти инструменты следует использовать только для тестирования, так как они изменяют состояние всего интерпретатора для простоты и никоим образом не являются потокобезопасными!

Базовое тестирование

Основной функциональностью для тестирования приложений Click является CliRunner, которая может вызывать команды как скрипты командной строки. Метод CliRunner.invoke() выполняет скрипт командной строки изолированно и сохраняет вывод как в байтах, так и в двоичных данных.

Возвращаемое значение — объект Result, содержащий сохранённые данные вывода, код завершения и необязательное исключение:

hello.py
import click

@click.command()
@click.argument('name')
def hello(name):
   click.echo(f'Hello {name}!')
test_hello.py
from click.testing import CliRunner
from hello import hello

def test_hello_world():
  runner = CliRunner()
  result = runner.invoke(hello, ['Peter'])
  assert result.exit_code == 0
  assert result.output == 'Hello Peter!\n'

Для тестирования подкоманд необходимо указать имя подкоманды в параметре args метода CliRunner.invoke():

sync.py
import click

@click.group()
@click.option('--debug/--no-debug', default=False)
def cli(debug):
   click.echo(f"Debug mode is {'on' if debug else 'off'}")

@cli.command()
def sync():
   click.echo('Syncing')
test_sync.py
from click.testing import CliRunner
from sync import cli

def test_sync():
  runner = CliRunner()
  result = runner.invoke(cli, ['--debug', 'sync'])
  assert result.exit_code == 0
  assert 'Debug mode is on' in result.output
  assert 'Syncing' in result.output

Дополнительные ключевые аргументы, переданные в .invoke(), будут использованы для создания начального объекта Context. Например, если вы хотите выполнить тесты с фиксированной шириной терминала, вы можете использовать следующее:

runner = CliRunner()
result = runner.invoke(cli, ['--debug', 'sync'], terminal_width=60)

Изоляция файловой системы

Для базовых инструментов командной строки с операциями с файловой системой метод CliRunner.isolated_filesystem() полезен для установки текущей рабочей директории в новую пустую папку.

cat.py
import click

@click.command()
@click.argument('f', type=click.File())
def cat(f):
   click.echo(f.read())
test_cat.py
from click.testing import CliRunner
from cat import cat

def test_cat():
   runner = CliRunner()
   with runner.isolated_filesystem():
      with open('hello.txt', 'w') as f:
          f.write('Hello World!')

      result = runner.invoke(cat, ['hello.txt'])
      assert result.exit_code == 0
      assert result.output == 'Hello World!\n'

Передайте temp_dir для управления тем, где создается временная директория. В этом случае Click не удалит директорию. Это полезно для интеграции с фреймворком, например, Pytest, который управляет временными файлами.

def test_keep_dir(tmp_path):
    runner = CliRunner()

    with runner.isolated_filesystem(temp_dir=tmp_path) as td:
        ...

Потоки ввода

Обёртка для тестов также может использоваться для предоставления данных ввода для потока ввода (stdin). Это очень полезно для тестирования подсказок, например:

prompt.py
import click

@click.command()
@click.option('--foo', prompt=True)
def prompt(foo):
   click.echo(f"foo={foo}")
test_prompt.py
from click.testing import CliRunner
from prompt import prompt

def test_prompts():
   runner = CliRunner()
   result = runner.invoke(prompt, input='wau wau\n')
   assert not result.exception
   assert result.output == 'Foo: wau wau\nfoo=wau wau\n'

Обратите внимание, что подсказки будут эмулированы таким образом, чтобы они также записывали данные ввода в поток вывода. Если ожидается скрытый ввод, этого, очевидно, не произойдёт.

© Copyright 2014 Pallets.
Licensed under the BSD 3-Clause License.
We are not supported nor endorsed by Pallets.
https://click.palletsprojects.com/en/8.1.x/testing/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API