Smalltalk по-русски
Advertisement

Я написал дополнение к 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'].

Очевидно, что второе утверждение не верно. Если мы запустим такой тест в режиме отладки, то вместо привычного окна с исключением увидим:

Sunit debug extensions 1

В текстовом поле вывелся текст того утверждения, которое привело к падению теста.

Изучение утверждения[]

В окне, которое мы только что видели работают привычные комбинации Ctrl+Q (Inspect It), Ctrl+P (Print It) и пр.

testInspectingAssertion
   | myVar1 myVar2 |
   myVar1 := 'something'.
   myVar2 := myInstVar size.

   self should: [myVar1 isString & myVar2 isString]

В окне отладки, которое откроется для этого теста можно выделить кусочек кода и, скажем, открыть инспектор на результате его выполнения:

Sunit debug extensions 2

Там же код можно отредактировать, например, заменив "&" на "|" и выполнить еще раз:

Sunit debug extensions 3

Подсказки[]

В окне отладки теста могут быть выведены подсказки - причина падения теста, состояние участвующих в утверждении объектов и пр. Например, для теста:

testIsZero
   | myVar |
   myVar := 1.2s.

   self should: [myVar isZero]

Окно будет выглядеть так:

Sunit debug extensions 4

Подсказка, что 1.2 это не ноль не выглядит очень полезной, но бывают случаи чуть сложнее:

testAllOdd
   | myVar |
   myVar := #(1 3 11 16 131 188 1001).

   self should: [myVar allSatisfy: [:each | each odd]]

Sunit debug extensions 5

Здесь красным подсвечены те элементы коллекции, из-за которых тест не прошел.

А вот достаточно показательный пример со сравнением строк:

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]

Sunit debug extensions 6

Диффератор бывает особенно полезен, когда строки значительно длинее, чем в нашем примере.

Так же поддерживаются проверки исключений:

testException
   self shouldnt: [1 / 0] raise: ZeroDivide

Sunit debug extensions 7

Отладка[]

Если в окне, которое открывается при отладке падающего теста нажать кнопку "Debug", то вы попадете в привычный отладчик. Но в отличии от обычного поведения, когда отладчик открывается на исключении TestFailure (т.е. все уже закончилось, и отлаживать, по сути, уже нечего), он откроется ДО выполнения блока #should:/#shouldnt:, который привел к падению теста. Вы сможете сразу же повторно пройти код этом в блоке и разобраться в причине падения.

Заключение[]

Для более детального описания работы с расширением загрузите из публичного репозитория пакадж SUnitDebugExtensionsExamples. Если у вас есть вопросы или пожелания, обязательно пишите мне на andreym@transas.com или оставьте сообщение в моем блоге moujikov.livejournal.com

Андрей Мужиков

Advertisement