Расширение SUnit
Материал из Smalltalk по-русски
Я написал дополнение к SUnit в VisualWorks. Это расширение помогает в определении причин падения теста и в его отладке. Вы можете скачать из публичного репозитория бандл SUnitDebugExtensions (или SUnitDebugExtensionsWithTests, если хотите посмотреть еще и тесты), а так же пакадж с примерами - SUnitDebugExtensionsExamples.
Ниже я опишу несколько примеров использования расширения. Это не все возможности, но они достаточно показательны. Итак.
Содержание |
[править] Общие правила
Большинство возможностей расширения станут доступны только в том случае, если вы будете использовать #should: и #shouldnt: вместо #assert: и #deny:. Первые отличаются от вторых тем, что принимают параметром не true/false, а блок, который должен при выполнении true или false вернуть. Это важно, т.к. имея только результат утверждения, сложно проанализировать, что привело к его получению. Другое дело смолтолковский блок, который можно декомпилировать, разобрать и выудить массу полезного.
Переход на #should:/#shouldnt:, на мой взгляд, не проблема, т.к. их использование ничем, по сути, не отличается от #assert:/#deny: - всего лишь плюс одни скобки. Перевести существующий код можно с помошью Rewrite tool, затратив пару минут.
С #should:raise: и #shouldnt:raise ничего делать не нужно - они для наших целей и так подходят.
[править] Вывод неверного утверждения
Итак, первая возможность - вывод утверждения, которое привело к падению теста. Это бывает полезно, когда в тесте таких утверждений несколько. Например, в таком:
testSeveralAssertions | myVar | myVar := 42. self should: [myVar notNil]. self should: [myVar isString]. self should: [myVar = 'qwerty'].
Очевидно, что второе утверждение не верно. Если мы запустим такой тест в режиме отладки, то вместо привычного окна с исключением увидим:
В текстовом поле вывелся текст того утверждения, которое привело к падению теста.
[править] Изучение утверждения
В окне, которое мы только что видели работают привычные комбинации Ctrl+Q (Inspect It), Ctrl+P (Print It) и пр.
testInspectingAssertion | myVar1 myVar2 | myVar1 := 'something'. myVar2 := myInstVar size. self should: [myVar1 isString & myVar2 isString]
В окне отладки, которое откроется для этого теста можно выделить кусочек кода и, скажем, открыть инспектор на результате его выполнения:
Там же код можно отредактировать, например, заменив "&" на "|" и выполнить еще раз:
[править] Подсказки
В окне отладки теста могут быть выведены подсказки - причина падения теста, состояние участвующих в утверждении объектов и пр. Например, для теста:
testIsZero | myVar | myVar := 1.2s. self should: [myVar isZero]
Окно будет выглядеть так:
Подсказка, что 1.2 это не ноль не выглядит очень полезной, но бывают случаи чуть сложнее:
testAllOdd | myVar | myVar := #(1 3 11 16 131 188 1001). self should: [myVar allSatisfy: [:each | each odd]]
Здесь красным подсвечены те элементы коллекции, из-за которых тест не прошел.
А вот достаточно показательный пример со сравнением строк:
testStrings | myVar1 myVar2 | myVar1 := 'The class of class Metaclass is class Metaclass class'. myVar2 := 'The class of class Metaclass class is class Metaclass'. self should: [myVar1 = myVar2]
Диффератор бывает особенно полезен, когда строки значительно длинее, чем в нашем примере.
Так же поддерживаются проверки исключений:
testException self shouldnt: [1 / 0] raise: ZeroDivide
[править] Отладка
Если в окне, которое открывается при отладке падающего теста нажать кнопку "Debug", то вы попадете в привычный отладчик. Но в отличии от обычного поведения, когда отладчик открывается на исключении TestFailure (т.е. все уже закончилось, и отлаживать, по сути, уже нечего), он откроется ДО выполнения блока #should:/#shouldnt:, который привел к падению теста. Вы сможете сразу же повторно пройти код этом в блоке и разобраться в причине падения.
[править] Заключение
Для более детального описания работы с расширением загрузите из публичного репозитория пакадж SUnitDebugExtensionsExamples. Если у вас есть вопросы или пожелания, обязательно пишите мне на andreym@transas.com или оставьте сообщение в моем блоге moujikov.livejournal.com







