Дифференциальное тестирование GNU Coreutils 'fmt' Utility
Я изучаю различные стратегии тестирования (дифференциальное, регрессионное, модульное и т. Д.), И мне было поручено тестировать GNU Coreutils
fmt
полезность. Я пытаюсь применить рандомизированное дифференциальное тестирование и создать оракула, чтобы утверждать, что описанные постусловия утилиты выполнены.
Я хотел бы создать утилиту Python, которая генерирует рандомизированную строку, применяет обтекание текстом к строке (до заданной ширины строки) для генерации ожидаемого вывода, а затем вызывает утилиту fmt для сгенерированной строки и утверждает, что результат соответствует ожидаемому результату. Для этого я пытаюсь использовать textwrap
Модуль Python. Тем не менее, я не нашел способа обеспечить сохранение отступа. Рассмотрим файл (file.txt) с содержимым
\s\s\s\sLorem ipsum dolor sit amet, consectetuer-adipiscing elit. Curabitur dignissim venenatis pede. Quisque dui dui, ultricies ut, facilisis non, pulvinar non.
как ввод в утилиту fmt. Вызов команды fmt -w 50 file.txt
приводит к выводу:
\s\s\s\sLorem ipsum dolor sit amet,
\s\s\s\sconsectetuer-adipiscing elit. Curabitur
\s\s\s\sdignissim venenatis pede. Quisque dui dui,
\s\s\s\sultricies ut, facilisis non, pulvinar non.
Согласно документации по утилитам fmt,
По умолчанию пустые строки, пробелы между словами и отступы сохраняются в выходных данных; последовательные строки ввода с разными отступами не объединяются; вкладки расширяются при вводе и вводятся при выводе.
fmt предпочитает разрывать строки в конце предложения и старается избегать разрывов строк после первого слова предложения или перед последним словом предложения. Разрыв предложения определяется либо как конец абзаца, либо как слово, оканчивающееся на любое из ".?!", За которым следуют два пробела или конец строки, игнорируя любые промежуточные скобки или кавычки.
В моей попытке воспроизвести то же поведение вывода, что и в утилите fmt, я решил использовать модули text wrap. fill
функционировать следующим образом:
textwrap.fill(in_str, width=50, expand_tabs=True, drop_whitespace=False, fix_sentence_endings=True, break_on_hyphens=False)
Что, согласно документации Python, должно делать следующее:
- Максимальная длина обернутых строк будет равна параметру ширины (50).
- Все символы табуляции на входе будут расширены до пробелов.
- Пробелы в начале и конце каждой строки (после переноса, но перед отступом) не удаляются.
- Предположим, что окончание предложения состоит из строчной буквы, за которой следует одна из ".", "!" Или "?", Возможно, за которой следует одна из "" или "", за которой следует пробел.
- Только пробелы будут считаться потенциально хорошими местами для разрывов строк.
Однако выходные данные функции text wrap.fill для того же ввода возвращают:
\s\s\s\sLorem ipsum dolor sit amet,
consectetuer-adipiscing elit. Curabitur dignissim
venenatis pede. Quisque dui dui, ultricies ut,
facilisis non, pulvinar non. Duis quis arcu a
purus volutpat iaculis. Morbi id dui in diam
ornare dictum. Praesent consectetuer vehicula
ipsum. Praesent tortor massa, congue et, ornare
in, posuere eget, pede.
Как видите, уровень отступа не поддерживается.
Какой инструмент и / или стратегию дифференциального тестирования лучше всего использовать для наиболее эффективного тестирования утилиты fmt? Любые предложения очень ценятся!
1 ответ
Попробуйте запустить этот фрагмент с py.test
:
#!/usr/bin/env python2.7
from textwrap import TextWrapper
input_tx = """\s\s\s\sLorem ipsum dolor sit amet, consectetuer-adipiscing elit. Curabitur dignissim venenatis pede. Quisque dui dui, ultricies ut, facilisis non, pulvinar non."""
output_tx1 = """\s\s\s\sLorem ipsum dolor sit amet, consectetuer-
\s\s\s\sadipiscing elit. Curabitur dignissim
\s\s\s\svenenatis pede. Quisque dui dui, ultricies
\s\s\s\sut, facilisis non, pulvinar non."""
output_tx2 = """\s\s\s\sLorem ipsum dolor sit amet,
\s\s\s\sconsectetuer-adipiscing elit. Curabitur
\s\s\s\sdignissim venenatis pede. Quisque dui dui,
\s\s\s\sultricies ut, facilisis non, pulvinar non."""
class Test_TextWrapper:
def test_stackru_q32753000_1(self):
sut = TextWrapper(width=50, subsequent_indent="\s\s\s\s")
assert sut.fill(input_tx) == output_tx1
def test_stackru_q32753000_2(self):
sut = TextWrapper(width=50, subsequent_indent="\s\s\s\s",
fix_sentence_endings=False,
break_on_hyphens=False)
assert sut.fill(input_tx) == output_tx2
Это должно показать вам что-то вроде этого:
> py.test -v -k Test_TextWrapper
============================================== test session starts ===============================================
platform linux2 -- Python 2.7.11, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- /usr/bin/python
cachedir: .cache
...
plugins: cov-2.2.1
collected 6 items
test_fmt.py::Test_TextWrapper::test_stackru_q32753000_1 PASSED
test_fmt.py::Test_TextWrapper::test_stackru_q32753000_2 PASSED
=================================== 4 tests deselected by '-kTest_TextWrapper' ===================================
===================================== 2 passed, 4 deselected in 0.03 seconds =====================================
Как вы можете видеть, мой второй контрольный пример выдает тот же результат, что и в примере вашего вопроса.
В настоящее время я пишу небольшой класс-оболочку Python для стандартной библиотеки Python textwrap.TextWrapper
учебный класс. Этот производный класс предоставит новый prefix
Ключевой аргумент, объединяющий эффекты initial_indent
и subsequent_indent
параметры с удалением префикса из входного текста. (Похоже на то, что -p
вариант fmt
полезная программа делает) В поисках предшествующего уровня техники и вдохновения я нашел ваш вопрос здесь.