Чи можна для модульного тесту стверджувати, що метод викликає sys.exit ()


98

У мене є метод python 2.7, який іноді викликає

sys.exit(1) 

Чи можна зробити модульний тест, який підтверджує, що цей рядок коду викликається, коли виконуються належні умови?


Відповіді:


155

Так. sys.exitпідвищує SystemExit, тому ви можете перевірити це за допомогою assertRaises:

with self.assertRaises(SystemExit):
    your_method()

Екземпляри SystemExitмають атрибут, codeякому встановлено запропонований статус виходу, а менеджер контексту, що повертається, assertRaisesмає зловлений екземпляр винятку як exception, тому перевірка стану виходу проста:

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

sys.exit Документація :

Вихід з Python. Це реалізується шляхом підняття SystemExitвинятку ... можливо перехопити спробу виходу на зовнішньому рівні.


3
+1, за винятком того, що якщо він хоче перевірити, що він викликає sys.exit(1)(на відміну, скажімо, sys.exit(0)), вам потрібно фактично стверджувати, що codeце 1. Я думаю, ви могли б це зробити assertRaisesRegexp(SystemExit, '1')?
abarnert

Я був впевнений, що існує unittestметод, який дозволяє передавати виняток і викликаний предикат для запуску на винятку чи його аргументах, а не просто шаблон регулярного виразу, який запускається на рядковому поданні першого аргументу ... але, я думаю, ні. Чи є якийсь інший тестовий модуль, про який я думаю?
abarnert

1
+1, оскільки для перевірки коду помилки набагато простіше зробити просто: self.assertRaisesRegex( SystemExit, '^2$', testMethod ) Менше коду, достатньо читабельного.
Марек Левандовскі

1
@MarekLewandowski - друкарська помилка. Має бутиself.assertRaisesRegexp
Євген

12

Ось повний робочий приклад. Незважаючи на чудову відповідь Павла, мені потрібно було деякий час це зрозуміти, тому я включаю його сюди в надії, що це буде корисно.

import unittest
from glf.logtype.grinder.mapping_reader import MapReader

INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"

class TestMapReader(unittest.TestCase):

    def test_get_tx_names_incomplete_mapping_file(self):
        map_reader = MapReader()
        with self.assertRaises(SystemExit) as cm:
            tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
        self.assertEqual(cm.exception.code, 1)

3

Я знайшов відповідь на ваше запитання в пошуковій документації модульного тестування Python для "Тестування на винятки". На вашому прикладі модульний тест буде виглядати наступним чином:

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

Не забудьте включити всі аргументи, необхідні для перевірки вашої функції.


1

Як додаткове зауваження до чудової відповіді Павла, ви також можете перевірити наявність певних статусів, якщо вони передбачені функцією, яку ви тестуєте. Наприклад, якщо your_method()міститься наступне sys.exit("Error"), можна буде спеціально перевірити на "Помилку":

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.