Случайным образом выберите файл внутри папки, используя Hypothesis

Я хочу добавить тесты с помощью библиотеки Hypothesis (уже использую в ПО для тестирования). Для этих тестов я должен использовать набор текстовых файлов, содержащихся в папке. Мне нужно случайным образом выбирать один из этих файлов каждый раз, когда я запускаю свои тесты. Как это сделать с помощью гипотезы?

редактировать Вот в принципе, как бы это выглядело, чтобы соответствовать шаблонам уже существующих тестов.

@given(doc=)
def mytest(doc):

    # assert some stuff according to doc
    assert some_stuff

person David N    schedule 17.02.2020    source источник
comment
Отвечает ли это на ваш вопрос? Как случайным образом выбрать элемент из списка?   -  person mkrieger1    schedule 17.02.2020
comment
@mkrieger1 Нет, потому что я хочу, чтобы это было сделано с помощью Hypthesis.   -  person David N    schedule 17.02.2020
comment
Зачем вам нужна Гипотеза для вашего очень простого случая?   -  person Yaroslav Nikitenko    schedule 27.11.2020


Ответы (1)


Статический случай

Если предполагается, что список файлов "заморожен" (файлы не будут удалены/добавлены), то мы можем использовать os.listdir + hypohtesis.strategies.sampled_from нравится

import os

from hypothesis import strategies

directory_path = 'path/to/directory/with/txt/files'
txt_files_names = strategies.sampled_from(sorted(os.listdir(directory_path)))

или если нам нужны полные пути

from functools import partial
...
txt_files_paths = (strategies.sampled_from(sorted(os.listdir(directory_path)))
                   .map(partial(os.path.join, directory_path)))

или если в каталоге могут быть файлы с разными расширениями, а нам нужны только файлы .txt, мы можем использовать glob.glob

import glob
...
txt_files_paths = strategies.sampled_from(sorted(glob.glob(os.path.join(directory_path, '*.txt'))))

Динамический случай

Если содержимое каталога может измениться, и мы хотим выполнять сканирование каталога при каждой попытке генерации данных, это можно сделать следующим образом:

dynamic_txt_files_names = (strategies.builds(os.listdir,
                                             strategies.just(directory_path))
                           .map(sorted)
                           .flatmap(strategies.sampled_from))

или с полными путями

dynamic_txt_files_paths = (strategies.builds(os.listdir,
                                             strategies.just(directory_path))
                           .map(sorted)
                           .flatmap(strategies.sampled_from)
                           .map(partial(os.path.join, directory_path)))

или с glob.glob

dynamic_txt_files_paths = (strategies.builds(glob.glob,
                                             strategies.just(os.path.join(
                                                     directory_path,
                                                     '*.txt')))
                           .map(sorted)
                           .flatmap(strategies.sampled_from))

Редактировать

person Azat Ibrakov    schedule 17.02.2020
comment
Вы должны поставить .map(sorted) перед плоской картой, чтобы гарантировать воспроизводимость примеров — не все операционные системы или файловые системы гарантируют стабильный порядок итераций, и это нарушит воспроизведение. - person Zac Hatfield-Dodds; 18.02.2020
comment
sorted специально должен быть перед sampled_from - как написано, вы не стабилизируете порядок итерации, вы конвертируете строку в отсортированный список символов! - person Zac Hatfield-Dodds; 22.02.2020
comment
@ ZacHatfield-Dodds: вы правы, моя ошибка, тестировался только статический случай, теперь должна быть исправлена - person Azat Ibrakov; 22.02.2020