У меня есть функция, которая обновляет файл спецификации rpm для дальнейшего использования. у него есть три параметра: имя приложения, версия, которую мы хотим изменить, и место, где файл спецификаций находится в файловой системе.
То, что я не могу сделать, это, скажем, иметь файл tests / files / package_name.spec и проверить, что он корректирует его версию, не изменяя фактический файл спецификации. Я не хочу изменять реальный файл спецификации, потому что это сделает тест бесполезным при втором запуске.
Я попытался заглянуть в библиотеку mock и mock_open, но, похоже, ничего не подходит для этого случая.
def test_update_spec_file():
update_spec_file("package_name", "5.0.0", "files/package_name")
with open("files/package_name.spec", "r") as f:
contents = f.read()
version_regex = re.compile("^.*define _software_version.*$")
assert (
re.search(version_regex, contents).group(0)
== "%define _software_version 5.0.0"
)
По сути, функция update_spec_file
находит строку %define _software_version 5.0.0
, используя regex, и снова использует regex для перехода в новую версию.
Итак, в заключение, можно ли было бы создать файл, открыть его с каким-то имитирующим файлом с его содержимым, запустить функцию и подтвердить, что он выполнил свою работу без фактического изменения файла в файловой системе?
Либо это, либо сбросьте файл после его изменения.
Это код, который обновляет файл спецификации:
def update_spec_file(application, release_version, path_to_spec_file):
"""Update the spec file with the release version.
Args:
application (str): Name of the application.
release_version (str): New version of application.
path_to_spec_file (str, optional):
path the the applications spec file we are modifying.
"""
print(f"Updating spec file _software_version to {release_version}")
try:
with open(path_to_spec_file, "r") as spec_file:
spec_contents = spec_file.readlines()
except EnvironmentError:
print(f"Unable to open spec file located at: {path_to_spec_file}")
# raise the original exception again.
raise
# Find and replace software version in contents of spec file.
version_regex = re.compile("%define _software_version.*?(?=(?:\\n)|$)")
define_version = f"%define _software_version {release_version}"
# Splice the new software version line into the existing file contents
spec_contents[:] = [
version_regex.sub(define_version, line) for line in spec_contents
]
try: # Open the file and write the new spliced contents
with open(path_to_spec_file, "w") as f_spec_file:
f_spec_file.writelines(spec_contents)
except EnvironmentError: # Catch spec file not found.
print(f"Unable to open spec file located at: {path_to_spec_file}")
# raise the original exception again.
raise
редактирование:
это модифицированный код:
def test_update_spec_file():
content = open("tests/files/package_name.spec").read()
with patch(__name__ + ".open", create=True) as mock_open:
mock_open.return_value.__enter__.return_value = StringIO(content)
with open("tests/files/package_name.spec") as f:
update_spec_file(
"package_name", "5.0.0", "tests/files/package_name.spec"
что я делаю, чтобы проверить это cat
файл спецификации перед выполнением теста и cat
после запуска теста
древовидная структура кода:
release/
├── release_all_in_one
│ ├── changelog_utils.py
│ ├── confluence_email.py
│ ├── confluence_utils.py
│ ├── create_confluence_page.py
│ ├── __init__.py
│ ├── jira_utils.py
│ ├── parse_confluence.py
│ ├── parse_rm_objects.py
│ ├── release_all_in_one_openshift.py
│ ├── release_all_in_one.py
│ ├── tag_branch.py
│ ├── templates
│ │ ├── admin_package_template
│ │ ├── base_template
│ │ ├── cdn_package_template
│ │ ├── fe_package_template
│ │ ├── oddjob_package_template
│ │ ├── openshift_template
│ │ └── procedure.json
│ └── utils.py
├── setup.cfg
├── setup.py
└── tests
├── files
│ └── package_name.spec
├── test_changelog.py
├── testing_utils.py
└── test_utils.py