Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Python, как уделенно исполняемому коду unittest.TestCase передать exit status в зависимости от перехваченного assertionError?

paramiko
unittest
python
Теги: #<Tag:0x00007f7b6d53a558> #<Tag:0x00007f7b6d53a418> #<Tag:0x00007f7b6d53a2d8>

(Евгений Бухгаммер) #1

Здравствуйте!

У меня есть управляющий скрипт, где очень общо делается такая вещь:

class PackageTest(unittest.TestCase):

    def setUp(self):
        remote_send()  # paramiko вызов, закидывающий на машину папку с моими скриптами из CWD
    def test_a_package_setup(self):
        # paramiko враппер вызов, который удаленно выполнит command line 
        remote_exec("python -m unittest tester_standalone_package_setup.FullPackagePlusStandAlones.test_a_package_setup")
    def tearDown(self):
        remote_exec("python -m unittest tester_standalone_package_setup.UninstallSoftware.test_a_uninstall_package")
        remote_exec("python -m unittest tester_standalone_package_setup.UninstallSoftware.test_a_uninstall_standalone")

def remote_exec(cmd):
    exit_st, out, err = exec_cmd(cmd)  # имплементация subprocess.Popen, только через SSH, вернет код завершения, stdout и stderr
    if exit_st != 0:
        vm.shutdown()
        logger.error(err)

Вопрос, заключается в следующем:

Представим, что в tearDown первый же удаленный запрос свалится на каком-то тесте.
мой враппер метод над Paramiko проверяет код ошибки отработавшего удаленно скрипта и и глушит виртуальную машину в случае, если там скрипт завершился “аварийно”.

Но в tearDown два вызова, и оба они должны попытаться отработать как этап очистки контекста.
Для этого мне во враппер методе можно получать специфичные коды ошибки, или со stderr парсить сообщения от self.assertTrue(%bool_statement%, “Uninstallation failed at step %s” % step).

Мне стало интересно, можно ли повешать глобальный хук на AssertionError в этом случае, чтобы он завершал скрипт (закинутый на удаленный компьютер и запущенный через парамикро удаленно) с нужным мне экзит статусом. Стоит ли в этом случае завести свои кастомные AssertionError унаследованные эксепшены.

Может быть, это вообще неправильный путь и не канонично?
Заметки и мысли:
Отчасти я понимаю, что если что-то валится в методе tearDown() - то наверняка метод выполняет не то,что ему предназначено делать. Он должен работать железно и не содержать в себе тестовой логики.

В общем, я ожидаю от программы, что tearDown() будет пытаться все подчистить удаленно, и если удаленный вызов завершится экзит кодом, который я ожидаю, то следующий удаленный вызов должен попытаться выполниться в любом случае.


(Евгений Бухгаммер) #2

upd:

На данный момент моя логика достигается тем, что я нахожу в stdout сообщение своего AssertionError.
Парсинг такого сообщения мне кажется грязным хаком, т.к. код ошибки представляется мне более фундаментально очевидным решением, плюс коды завершения скрипта могут возбуждаться разного рода семействами кастомных AssertionError