Вопрос или проблема
Я хочу проверить, совпадает ли вывод функции с текстом, который я представляю, что она должна записать в стандартный вывод. Но приведенный ниже код никогда не выводит test PASS
, и я не могу понять, почему. Я также пытался вставлять различные \n
символы или удалять их в переменной GROUND_TRUTH
, но это не помогло.
error_out()
{
printf "%s\n" "${ERROR}"
printf "Return to exit\n"
read -r THROW_AWAY
exit
}
ERROR="Test output."
OUTPUT_TO_TEST=$(error_out)
GROUND_TRUTH="Test output.\nReturn to exit\n"
{ [ "${OUTPUT_TO_TEST}" = "${GROUND_TRUTH}" ] \
&& printf "error_out test PASS\n"; } \
|| { \
printf "error_out test FAIL\n"; \
}
У вас две проблемы:
-
Результат подстановки команды
$(...)
никогда не будет оканчиваться на LF (так как они обрезаются оболочкой). Поэтому ваша переменнаяGROUND_TRUTH
не должна заканчиваться на LF. -
Оболочка не понимает
\n
как управляющую последовательность для символа LF. Поскольку вы нацелены на оболочку POSIX, вам нужно использовать настоящий LF в вашем строковом литерале.
Таким образом, минимальное исправление, которое заставит ваш код работать так, как задумано, будет заменой:
GROUND_TRUTH="Test output.\nReturn to exit\n"
на:
GROUND_TRUTH="Test output.
Return to exit"
Ответ или решение
Чтобы успешно пройти тестирование функции POSIX shell и сопоставить её вывод с ожидаемым текстом, необходимо учесть несколько важных моментов. Давайте подробно разберем вашу задачу и найдем оптимальное решение.
Проблема
В вашем коде функция error_out()
выводит текст на стандартный вывод, однако реализация, которую вы используете для проверки, не позволяет добиться ожидаемого результата. Основные моменты вашей проблемы заключаются в следующем:
-
Конец строки: Результат подстановки команды
$(...)
никогда не заканчивается символом новой строки (LF), так как завершающие символы в выводе команд удаляются оболочкой. Это значит, что переменнаяGROUND_TRUTH
не должна заканчиваться символом новой строки. -
Эскейп-последовательность: В POSIX shell символ
\n
не интерпретируется как перенос строки. Чтобы указать перенос строки в строковой литерале, необходимо фактически использовать символ переноса строки.
Решение
Для исправления кода вам нужно внести две правки в переменную GROUND_TRUTH
. Вместо вашей исходной версии:
GROUND_TRUTH="Test output.\nReturn to exit\n"
должно быть:
GROUND_TRUTH="Test output.
Return to exit"
Исправленный Код
Вот как должен выглядеть ваш обновленный код:
error_out() {
printf "%s\n" "${ERROR}"
printf "Return to exit\n"
read -r THROW_AWAY
exit
}
ERROR="Test output."
OUTPUT_TO_TEST=$(error_out)
GROUND_TRUTH="Test output.
Return to exit"
{ [ "${OUTPUT_TO_TEST}" = "${GROUND_TRUTH}" ] && printf "error_out test PASS\n"; } \
|| { \
printf "error_out test FAIL\n"; \
}
Объяснение
-
Подстановка результата: Теперь
OUTPUT_TO_TEST
будет содержать вывод без завершающего символа новой строки, что в свою очередь позволяет корректно сравнивать его сGROUND_TRUTH
. -
Использование переноса строки: Перенос строки указан в
GROUND_TRUTH
без использования эскейп-последовательности, поэтому теперь вывод будет правильно сопоставлен с ожидаемым значением.
Заключение
При тестировании функций в POSIX shell важно учитывать нюансы обработки строк и вывода. Убедитесь, что ваши строки настроены правильно, и вы сможете без труда проверить соответствие вывода ваших функций ожидаемым результатам. Корректное форматирование и внимание к деталям позволят вам избежать распространенных ошибок и сделать код более надежным.