DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
Basics of assertions in automated testing
1.
2. ASSERTIONS? WTF??
Wikipedia говорит нам:
«Утверждение (англ. Assertion) в программировании —
предикат, размещѐнный в программе и указывающий на
то, что разработчик имеет в виду этот предикат в этом
месте программы всегда истинным.»
3. PREDICATE, MY ASS!
Какой-то бред сумасшедшего, правда?
Как же все-таки работать с этими непонятными
ассертами и при этом еще и не прослыть лошарой?
В этой презентации мы рассмотрим такие продвинутые
техники как курощение, низведение, дуракаваляние и
многие другие. Все они широко применяются в
автоматизированном тестировании.
4. КУРОЩЕНИЕ
Различают несколько видов курощения ассертами.
Какие же преимущества они дают?
• Посторонние не понимают, что проверяется и почему
• Посторонние не понимают, где ожидаемое значение, а где
реальное
• Посторонние не понимают, почему тот или иной тест
падает, хотя на вид все вроде бы в порядке
• Посторонние видят, что вы – грамотный специалист с
опытом использования разных фреймворков
• Количество зависимостей проекта возрастает, а значит,
возрастает и шанс, что посторонние отчаются и не
станут билдить ваш проект, а это вам только на руку
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();
}
Легко видеть, что приведенный код не содержит никаких
ассертов, нет их и в вызываемых методах. В чем же смысл
данного теста? Если ничего нигде не упало, значит, все
ништяк!