модульные тесты для командной строки args python - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть сценарий оболочки, который в настоящее время занимает 3 аргумента.Я запускаю это через сценарий оболочки с именем файла сценария оболочки, каталогом для запуска сценария python, вместе с именем каталога тестовых данных.Я хочу иметь возможность писать модульные тесты, которые выполняют приведенную ниже команду, но только если я должен был изменить дату, в зависимости от доступных данных она либо пройдет, либо потерпит неудачу.

main_config.sh
yamldir=$1

for yaml in $(ls ${yamldir}/*.yaml | grep -v "export_config.yaml"); do

    if [ "$yaml" != "export_config.yaml" ]; then

        echo "Running export for $yaml file...";
        python valid.py -p ${yamldir}/export_config.yaml -e $yaml -d ${endDate}
        wait

    fi

done

Это то, что выполняется в командной строке

./main_config.sh /Users/name/Desktop/yaml/ 2018-12-23

Это произойдет сбой и выдаст на терминал, так как нет каталога с именем 2012-12-23:

./main_config.sh /yaml/ 2018-12-23
    Running export for apa.yaml file...
    apa.json does not exist

Есликаталог существовал, он проходил и выводил на терминал:

Running export for apa.yaml file...
File Name: apa.json Exists 
File Size: 234 Bytes 
Writing to file

Мой скрипт сценария на python выглядит следующим образом:

def main(get_config):
    cfg = get_config()[0]  # export_config.yaml
    data = get_config()[1]  # export_apa.yaml
    date = get_config()[2]  # data folder - YYYY-MM-DD

# Conditional Logic


def get_config():
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", "--parameter-file", action="store", required=True)
    parser.add_argument("-e", "--export-data-file", action="store", required=True)
    parser.add_argument("-d", "--export-date", action="store", required=False)
    args = parser.parse_args()

    return [funcs.read_config(args.parameter_file), funcs.read_config(args.export_data_file), args.export_date]


if __name__ == "__main__":
    logging.getLogger().setLevel(logging.INFO)
    main(get_config)

1 Ответ

0 голосов
/ 03 декабря 2018

Мне кажется, что это не типичный модульный тест (который проверяет функцию или метод), а интеграционный тест (который проверяет подсистему извне).Но, конечно, вы все равно можете решить эту проблему с помощью типичных инструментов тестирования Python, таких как unittest.

. Простым решением было бы запустить скрипт с использованием subprocess, захватить выходные данные, а затем проанализировать эти выходные данные как часть.вашего теста:

import unittest

import os
import sys
if os.name == 'posix' and sys.version_info[0] < 3:
    import subprocess32 as subprocess
else:
    import subprocess

class TestScriptInvocation(unittest.TestCase):

    def setUp(self):
        """call the script and record its output"""
        result = subprocess.run(["./main_config.sh", "/Users/yasserkhan/Desktop/yaml/", "2018-12-23"], stdout=subprocess.PIPE)
        self.returncode = result.returncode
        self.output_lines = result.stdout.decode('utf-8').split('\n')

    def test_returncode(self):
        self.assertEqual(self.returncode, 0)

    def test_last_line_indicates_success(self):
        self.assertEqual(self.output_lines[-1], 'Writing to file')

if __name__ == '__main__':
    unittest.main()

Обратите внимание, что этот код использует бэкпорт модуля Python 3 subprocess.Кроме того, он пытается декодировать содержимое result.stdout, потому что в Python 3 это будет bytes объект, а не str, как в Python 2. Я не тестировал его, но эти две вещи должны составлять кодПереносим между 2 и 3.

Также обратите внимание, что использование абсолютных путей, таких как "/Users/yasserkhan/Desktop/yaml", может легко сломаться, поэтому вам нужно либо найти относительный путь, либо передать базовый путь к тестам, используя, например, переменные среды.

Вы можете добавить дополнительные тесты, которые будут анализировать другие строки и проверять наличие приемлемых выходных данных, таких как размер файла в ожидаемом диапазоне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...