#python
#python
Вопрос:
Для справки, я новичок.
Я пытаюсь создать функцию, которая «тестирует» другие функции, ничего сложного или чего-то еще. Это легче показать, чем объяснить:
def test(function, actual, expected):
print("Testing ", function)
print("Expected result:", expected, "Actual result:", actual)
В нынешнем виде имя функции и аргумент вводятся отдельно в виде строки:
test("function(5)", function(5), expected)
Я ищу способ получить фактический вызов функции (второй аргумент / параметр) в виде строки (в данном случае «function (5)»), потому что прямо сейчас он обрабатывается как возвращаемое значение, как только вызывается функция ‘test’.
Комментарии:
1. я думаю, вы ищете декоратора
2. @hjpotter92 Это решение сделало бы его намного чище, но оно также тесно связало бы тест с исходным кодом.
3.В Python все аргументы полностью оцениваются перед передачей.
function(5)
Сначала вы вызываете, а затем результат этого передаетсяtest
. Просто передайте функцию и выполните вызов внутриtest
4. @TedKleinBergman да, я согласен, это тоже было бы не намного чище. Функция достаточно чистая.
Ответ №1:
Вам нужно передать параметры функции в качестве аргументов. Вот как это делает платформа модульного тестирования python. Тогда ваша функция будет выглядеть примерно так:
def test(function_name, expected, function, *args, **kwargs):
print("Testing ", function_name)
print("Expected result:", expected, "Actual result:", function(*args, **kwargs))
test("function(5)", expected, function, 5)
Каждый аргумент или аргумент ключевого слова, переданный функции, будет распакован в функцию.
Причина, по которой я переместил expected
аргумент перед функцией, заключается в том, чтобы не было никакой двусмысленности в том, что должно быть аргументом test
функции и что должно быть передано function
.
Другое решение, которое позволяет вам опустить имя:
def test(expected, function, *args, **kwargs):
kwargs_repr = [f'{a}={b}' for a, b in kwargs.items()]
arguments = ', '.join(str(arg) for arg in (*args, *kwargs_repr))
print(f"Testing if {function.__name__}({arguments}) equals {expected}")
print("Expected result:", expected, "Actual result:", function(*args, **kwargs))
test(expected, function, 5)
Чтобы быть еще более полным, вы также должны перехватывать любые ошибки, которые могут быть вызваны функцией.
def test(expected, function, *args, **kwargs):
kwargs_repr = [f'{a}={b}' for a, b in kwargs.items()]
arguments = ', '.join(str(arg) for arg in (*args, *kwargs_repr))
print(f"Testing if {function.__name__}({arguments}) equals {expected}")
try:
print("Expected result:", expected, "Actual result:", function(*args, **kwargs))
except Exception as e:
print(f"Function raised exception: {e}")
test(None, print, 5, 3, end=' ', abc='hello')
Тестовая печать (1, 2, sep = 123, end= hello, abc = 123)
Вызванное функцией исключение: ‘abc’ является недопустимым аргументом ключевого слова для print()