Тестирование приложения python click, invoke () с env не работает - PullRequest
0 голосов
/ 15 апреля 2020

Я хочу протестировать приложение CLI python, работающее с щелчком мыши, с использованием pytest.

Это приложение, состоящее из нескольких команд, работает с постоянной конфигурацией, хранящейся в ~/.config/myapp. Затем myapp читает и анализирует файл конфигурации при каждом запуске и передает объект конфигурации в подкоманды (с pass_context () и pass_obj () )

Для тестирования I Я хочу выполнить команду в изолированной файловой системе, поэтому я добавил условие при объявлении CONFIG_DIR в config.py, но TMP_DIR env var, который я использую для выбора каталога базовой конфигурации, похоже, не передано команде.

Не могу найти, откуда она может прийти ...

Вот файлы:

src / main.py

...
class CommandContext():
    """Global options object"""
    def __init__(self, verbose=False):
        self.config = read_config()
        self.verbose = verbose


@click.group(cls=CLI)
@click.pass_context
@click.option('--verbose', is_flag=True)
def cli(context, verbose):
    """Pass context object to subcommands"""
    context.obj = CommandContext(verbose)
...

src / config.py

# Handle isolated filesystems for testing
if 'TEST' in environ and 'TMP_DIR' in environ:
    CONFIG_DIRECTORY = Path(environ['TMP_DIR'])
else:
    CONFIG_DIRECTORY = Path.home().joinpath(".config/myapp")

CONFIG_FILE = CONFIG_DIRECTORY.joinpath("config.json")
...
def read_config():
    """Read configuration from file"""
    if CONFIG_FILE.exists():
        with CONFIG_FILE.open("r") as file:
            return load(file)
    else:
        return None

def write_config(config):
    """Write config to file"""
    if not CONFIG_DIRECTORY.exists():
        makedirs(CONFIG_DIRECTORY)
    with CONFIG_FILE.open("w") as file:
        dump(config, file, indent=4, sort_keys=True)

test / init_test.py

def test_init(runner):
    with runner.isolated_filesystem() as fs:
        # Adding config location to env
        env = environ.copy()
        env['TMP_DIR'] = fs
        # Running init cmd with env
        res = runner.invoke(cli, ['--verbose', 'init', '.'], env=env)
        assert res.exit_code == 0
        assert fs in res.output

Официальная документация по invoke:

invoke (cli, args = None, input = None, env = None, catch_exceptions = True, color = False, ** extra)

Вызывает команду в изолированной среде. Аргументы передаются непосредственно в сценарий командной строки, дополнительные ключевые слова передаются в функцию main () команды

Параметры:

env - переопределение среды.

...

Если у кого-то есть решение, я буду очень счастлив. Заранее спасибо

...