ASSERTIONS? WTF??
Wikipedia говорит нам:
«Утверждение (англ. Assertion) в программировании —
предикат, размещѐнный в программе и указывающий на
то, что разработчик имеет в виду этот предикат в этом
месте программы всегда истинным.»
PREDICATE, MY ASS!
Какой-то бред сумасшедшего, правда?
Как же все-таки работать с этими непонятными
ассертами и при этом еще и не прослыть лошарой?
В этой презентации мы рассмотрим такие продвинутые
техники как курощение, низведение, дуракаваляние и
многие другие. Все они широко применяются в
автоматизированном тестировании.
КУРОЩЕНИЕ
Различают несколько видов курощения ассертами.
Какие же преимущества они дают?
• Посторонние не понимают, что проверяется и почему
• Посторонние не понимают, где ожидаемое значение, а где
реальное
• Посторонние не понимают, почему тот или иной тест
падает, хотя на вид все вроде бы в порядке
• Посторонние видят, что вы – грамотный специалист с
опытом использования разных фреймворков
• Количество зависимостей проекта возрастает, а значит,
возрастает и шанс, что посторонние отчаются и не
станут билдить ваш проект, а это вам только на руку
А ЭТО ЗНАЧИТ…
ВАС НЕ УВОЛЯТ!
КУРОЩЕНИЕ КЛАССАМИ
Крайне полезно для проекта употребление всех возможных видов
ассертов сразу. Здесь работает принцип «побольше
ассертов, хороших и разных». Наилучших результатов удается
достичь, когда ассерты из различных фреймворков встречаются в
рамках одного и того же класса.
Примеры:
• junit.framework.Assert.assertEquals(expected, actual)
;
• org.junit.Assert.assertEquals(expected, actual);
• org.testng.Assert.assertEquals(actual, expected);
и т.п.
Нельзя забывать и о встроенных ассертах языка
программирования:
• assert expression : message
КУРОЩЕНИЕ СООБЩЕНИЯМИ
Общеизвестно, что код должен документировать себя сам.
Это в особенности касается столь вредного явления как
сообщения в ассертах.
Сравним:
Assert.assertTrue(«Button „Click Me‟ was not found
on the page.», a);
и
Assert.assertTrue(a);
Почти втрое меньше символов! Налицо значительная
экономия, код стал более читабельным. Кого волнует, что
такое «a» и почему оно должно было равняться true?
КУРОЩЕНИЕ ТИПАМИ
Весьма хитроумным способом запутывания пользователей
считается курощение типами сравниваемых значений.
Возьмем следующий пример:
Assert.assertEquals(priceTextField.getAttribute(“v
alue”), 10 );
При хорошем раскладе есть шанс увидеть в отчете
сообщение вида «expected [10] but found [10]», что
обязательно поставит в тупик посторонних и лишний раз
подтвердит вашу незаменимость на проекте. К
сожалению, не для всех классов ассертов это работает.
НИЗВЕДЕНИЕ
Еще одной полезной техникой является так называемое
низведение ассертов, т.е. развертывание их при помощи
условных операторов. Это позволяет повысить
читабельность кода и увеличить общее число строк, что
может служить отличной метрикой его качества.
Пример кода:
if (element.isPresent()) {
Assert.assertTrue(true);
} else {
Assert.assertTrue(false);
}
НИЗВЕДЕНИЕ
Другой реальный пример низведения:
public void verifySomething(Boolean expected) {
if (isSomething()) {
Assert.assertTrue(expected.equals(false));
}
}
ДУРАКАВАЛЯНИЕ
Иногда бывает полезно пересыпать код так называемыми
контрольными ассертами. Подобный подход, называемый еще
дуракавалянием, может использоваться для тех же целей, что и
курощение, а также для временно-постоянной маркировки
участков кода, которые не должны выполняться никогда (но чтобы
компилятор не ругался).
Примеры использования:
• Assert.assertTrue(true);
• Assert.assertTrue(false);
• Assert.assertEquals(2, 23);
и др.
Отметим следующее: не стоит в таких случаях прибегать к вызову
Assert.fail(). Этот метод написан для дилетантов, которые не
умеют пользоваться ассертами.
ДУРАКАВАЛЯНИЕ
Дополнительно в целях унификации кода и затруднения
понимания его посторонними можно использовать такую
дуракавалятельную методику как подмена методов:
Assert.assertTrue(a == b);
вместо
Assert.assertEquals(a, b);
В сущности абсолютно все виды ассертов можно заменить на
assertTrue() без ущерба для функциональности теста. В случае
ошибки со сгенерированным сообщением в репорте о том, что true
не равно false, будет сложно не согласиться даже самым
отъявленным скептикам.
ПЕРЕХВАТ АССЕРТОВ
Код всегда должен понимать, кто в доме хозяин. Он не
должен думать, что может безнаказанно выбрасывать
ошибки, как будто ему здесь никто не указ.
Ошибки, генерируемые ассертами, легко можно
перехватить, так же как и любые другие:
try {
Assert.assertTrue(false);
} catch (AssertionError e) {
logger.info(“Обломись, глупый ассерт”);
}
ЭМУЛЯЦИЯ АССЕРТОВ
Если не принять особых мер, будущие пользователи
автотестов могут решить, будто код писали какие-нибудь
малообразованные неучи, незнакомые с архитектурой
фреймворков тестирования, которые только и могут, что
дергать библиотечные методы. Вот пример из реальной
жизни, демонстрирующий, как это можно предотвратить:
if (actual == null && expected != null) {
throw new AssertionError("Expected list "+key+" but was null
(expected "+expected+")");
}
Теперь ни у кого не возникнет и мысли, будто вы не в
состоянии сгенерировать AssertionError
самостоятельно!
НУЛЕВОЙ АССЕРТ
Вершиной дзена автоматизированного тестирования
является так называемый нулевой ассерт, то есть
ассерт, которого в явном виде не существует.
@Test
public void testThatEverythingsAwright() {
doThis();
doThat();
andNowForSomethingEntirelyDifferent();
}
Легко видеть, что приведенный код не содержит никаких
ассертов, нет их и в вызываемых методах. В чем же смысл
данного теста? Если ничего нигде не упало, значит, все
ништяк!
ВОПРОСЫ?
=)

Basics of assertions in automated testing

  • 2.
    ASSERTIONS? WTF?? Wikipedia говоритнам: «Утверждение (англ. Assertion) в программировании — предикат, размещѐнный в программе и указывающий на то, что разработчик имеет в виду этот предикат в этом месте программы всегда истинным.»
  • 3.
    PREDICATE, MY ASS! Какой-тобред сумасшедшего, правда? Как же все-таки работать с этими непонятными ассертами и при этом еще и не прослыть лошарой? В этой презентации мы рассмотрим такие продвинутые техники как курощение, низведение, дуракаваляние и многие другие. Все они широко применяются в автоматизированном тестировании.
  • 4.
    КУРОЩЕНИЕ Различают несколько видовкурощения ассертами. Какие же преимущества они дают? • Посторонние не понимают, что проверяется и почему • Посторонние не понимают, где ожидаемое значение, а где реальное • Посторонние не понимают, почему тот или иной тест падает, хотя на вид все вроде бы в порядке • Посторонние видят, что вы – грамотный специалист с опытом использования разных фреймворков • Количество зависимостей проекта возрастает, а значит, возрастает и шанс, что посторонние отчаются и не станут билдить ваш проект, а это вам только на руку
  • 5.
  • 6.
    КУРОЩЕНИЕ КЛАССАМИ Крайне полезнодля проекта употребление всех возможных видов ассертов сразу. Здесь работает принцип «побольше ассертов, хороших и разных». Наилучших результатов удается достичь, когда ассерты из различных фреймворков встречаются в рамках одного и того же класса. Примеры: • junit.framework.Assert.assertEquals(expected, actual) ; • org.junit.Assert.assertEquals(expected, actual); • org.testng.Assert.assertEquals(actual, expected); и т.п. Нельзя забывать и о встроенных ассертах языка программирования: • assert expression : message
  • 7.
    КУРОЩЕНИЕ СООБЩЕНИЯМИ Общеизвестно, чтокод должен документировать себя сам. Это в особенности касается столь вредного явления как сообщения в ассертах. Сравним: Assert.assertTrue(«Button „Click Me‟ was not found on the page.», a); и Assert.assertTrue(a); Почти втрое меньше символов! Налицо значительная экономия, код стал более читабельным. Кого волнует, что такое «a» и почему оно должно было равняться true?
  • 8.
    КУРОЩЕНИЕ ТИПАМИ Весьма хитроумнымспособом запутывания пользователей считается курощение типами сравниваемых значений. Возьмем следующий пример: Assert.assertEquals(priceTextField.getAttribute(“v alue”), 10 ); При хорошем раскладе есть шанс увидеть в отчете сообщение вида «expected [10] but found [10]», что обязательно поставит в тупик посторонних и лишний раз подтвердит вашу незаменимость на проекте. К сожалению, не для всех классов ассертов это работает.
  • 9.
    НИЗВЕДЕНИЕ Еще одной полезнойтехникой является так называемое низведение ассертов, т.е. развертывание их при помощи условных операторов. Это позволяет повысить читабельность кода и увеличить общее число строк, что может служить отличной метрикой его качества. Пример кода: if (element.isPresent()) { Assert.assertTrue(true); } else { Assert.assertTrue(false); }
  • 10.
    НИЗВЕДЕНИЕ Другой реальный примернизведения: public void verifySomething(Boolean expected) { if (isSomething()) { Assert.assertTrue(expected.equals(false)); } }
  • 11.
    ДУРАКАВАЛЯНИЕ Иногда бывает полезнопересыпать код так называемыми контрольными ассертами. Подобный подход, называемый еще дуракавалянием, может использоваться для тех же целей, что и курощение, а также для временно-постоянной маркировки участков кода, которые не должны выполняться никогда (но чтобы компилятор не ругался). Примеры использования: • Assert.assertTrue(true); • Assert.assertTrue(false); • Assert.assertEquals(2, 23); и др. Отметим следующее: не стоит в таких случаях прибегать к вызову Assert.fail(). Этот метод написан для дилетантов, которые не умеют пользоваться ассертами.
  • 12.
    ДУРАКАВАЛЯНИЕ Дополнительно в целяхунификации кода и затруднения понимания его посторонними можно использовать такую дуракавалятельную методику как подмена методов: Assert.assertTrue(a == b); вместо Assert.assertEquals(a, b); В сущности абсолютно все виды ассертов можно заменить на assertTrue() без ущерба для функциональности теста. В случае ошибки со сгенерированным сообщением в репорте о том, что true не равно false, будет сложно не согласиться даже самым отъявленным скептикам.
  • 13.
    ПЕРЕХВАТ АССЕРТОВ Код всегдадолжен понимать, кто в доме хозяин. Он не должен думать, что может безнаказанно выбрасывать ошибки, как будто ему здесь никто не указ. Ошибки, генерируемые ассертами, легко можно перехватить, так же как и любые другие: try { Assert.assertTrue(false); } catch (AssertionError e) { logger.info(“Обломись, глупый ассерт”); }
  • 14.
    ЭМУЛЯЦИЯ АССЕРТОВ Если непринять особых мер, будущие пользователи автотестов могут решить, будто код писали какие-нибудь малообразованные неучи, незнакомые с архитектурой фреймворков тестирования, которые только и могут, что дергать библиотечные методы. Вот пример из реальной жизни, демонстрирующий, как это можно предотвратить: if (actual == null && expected != null) { throw new AssertionError("Expected list "+key+" but was null (expected "+expected+")"); } Теперь ни у кого не возникнет и мысли, будто вы не в состоянии сгенерировать AssertionError самостоятельно!
  • 15.
    НУЛЕВОЙ АССЕРТ Вершиной дзенаавтоматизированного тестирования является так называемый нулевой ассерт, то есть ассерт, которого в явном виде не существует. @Test public void testThatEverythingsAwright() { doThis(); doThat(); andNowForSomethingEntirelyDifferent(); } Легко видеть, что приведенный код не содержит никаких ассертов, нет их и в вызываемых методах. В чем же смысл данного теста? Если ничего нигде не упало, значит, все ништяк!
  • 16.