Имам скрипт, който използва subprocess.check_output
на команда. Има случаи, при които тази команда може да не успее и да повдигне subprocess.CalledProcessError
.
Аз се опитвам да напиша единичен тест (използвайки pytest за провеждане на теста) за тази функция и да тествам условието за изключение.
3.1.3
Python 3.5.3
Написах този малък код, за да изследвам безрезултатно.
# mytest.py
import subprocess
def test_sub():
try:
command_output = subprocess.check_output("unzip x".split())
# unzip x is used to raise the exception when running with python
# but would be replaced by proper command that may fail
output = command_output
except subprocess.CalledProcessError as cpe:
#except Exception as cpe:
print("nType of error:", type(cpe))
print(cpe.args)
output = "unzip"
return output
if __name__ == "__main__":
print(test_sub())
Когато се движите с python mytest.py
изходът е unzip
както се очакваше след unzip
командата ще се провали и ще повдигне грешката.
Това е кодът за тестване на функцията
# test.py
import unittest
import unittest.mock as mock
from mytest import test_sub
import subprocess
class SubErrorTest(unittest.TestCase):
@mock.patch("mytest.subprocess", autospec=True)
def test_subprocess_error_thrown(self, mock_subprocess):
mock_subprocess.check_output.side_effect = subprocess.CalledProcessError(returncode=2,cmd=["bad"])
output = test_sub()
self.assertEqual("unzip", output)
Когато тичам pytest test.py
тестът е неуспешен с грешката
output = test_sub() #error thrown from here in test
test.py:
def test_sub(): try: command_output = subprocess.check_output("unzip x".split()) output = command_output except subprocess.CalledProcessError as cpe: #error is indicated here
E TypeError: уловът на класове, които не наследяват от BaseException не е разрешен
Ако коментирам except subprocess.CalledProcessError as cpe:
и се оттегли #except Exception as cpe:
тестът преминава с изхода:
test.py
Тип на грешката: <class> subprocess.CalledProcessError ">
()
Това изглежда, че ми подсказва, че грешката е хвърлена, както е посочено в макета и уловена и блокът за изключение е изпълнен. Въпросът тогава е защо не работи, когато улавя subprocess.CalledProcessError
.
Това се връща True
isinstance(subprocess.CalledProcessError(returncode=2,cmd=["bad"]), BaseException)
В този момент подозирам, че има нещо, което ми липсва в целия процес.
Какво ми липсва?
Отговори:
1 за отговор № 1Мисля, че се забивате по грешния път.
@mock.patch("mytest.subprocess", autospec=True)
Пътят трябва да бъде пътят към тествания модул, а не самият тест. Това, което мисля, че се случва е вашето подигравателно подпроцес в пространството namespace test.py, така че когато зададете side_effect да subprocess.CalledProcessError
вие го поставяте на присмех. Можете да потвърдите това, като регистрирате side_effect, след като го зададете.