[БЕЗ_ЗВУКА] В предыдущем видео
мы с вами смогли с помощью юнит-тестов найти ошибку в решении задачи «Синонимы».
При этом по ходу разработки юнит-тестов мы смогли написать такой
небольшой юнит-тест фреймворк, в который, на самом деле,
можно добавлять было бы и другие тесты, если бы мы не нашли ошибку.
Давайте посмотрим, что же за фреймворк у нас получился,
вот так вот за одну лекцию написанный в прямом эфире, можно сказать.
Значит, во-первых, мы этот фреймворк основали на стандартной функции Assert,
которая у нас использовалась,
чтобы проверять какие-то ожидания от нашего кода.
Давайте посмотрим, какие у Assert есть преимущества и недостатки.
Важным преимуществом Assert является то,
что он показывает, какая именно проверка сработала в юнит-тесте.
Вот у меня на экране приведен пример сработавшего Assert, и мы видим,
что если в консоли выведено coursera.cpp Line 32,
мы понимаем, что мы понимаем, какой именно Assert сработал,
можем пойти в код и понять, что это вот эта вот проверка, и мы понимаем,
какой именно юнит-тест у нас выстрелил, нашел ошибку и
конкретно с ним можем разбираться и изучать, где же, собственно, проблема.
Правда, на самом деле, на этом преимущества стандартной
функции Assert заканчиваются, а начинаются недостатки.
Важным недостатком является то, что в консоль,
при проверке равенства в консоль не выводятся значения
тех переменных, которые в Assert сравниваются.
Вот опять же давайте рассмотрим пример.
Вот у нас в консоли выведено, у нас сработал Assert,
и в консоль выведено empty == expected.
Мы понимаем, что это вот этот вот кусок кода,
но мы из кода понимаем, чему равна константа expected — мы можем прямо здесь,
на месте прочитать и понять, какой именно словарь синонимов мы ожидаем.
А вот чему оказалась равна переменная empty, мы нигде не видим.
И чтобы узнать, какой она стала, нам приходится делать какие-то
дополнительные действия: запускать отладчик, снова выполнять этот юнит-тест,
смотреть в отладчики, чему оказалась равна переменная, в данном случае empty.
Это, конечно же, неудобно.
Дальше.
Какие еще были недостатки у нашего фреймворка,
которым мы пользовались?
Если срабатывал хотя бы один Assert в наших юнит-тестах,
то программа завершалась аварийно, и другие тесты не срабатывали.
Давайте даже мы с вами это продемонстрируем.
Вот мы переключимся в Eclipse, и мы с вами
нашли ошибку с помощью теста TestAddSynomyms,
вот давайте мы его — он у нас третьим выполнялся, давайте выполним его вторым.
При этом мы убедимся, что та ошибка, которую мы нашли,
она у нас сейчас присутствует.
Вот давайте мы скомпилируем наш код, запустим его и увидим,
что у нас, значит, программа отработала,
один из тестов выстрелил — мы это видим по красному выводу в консоли.
И что мы здесь видим?
Что тест на функцию AreSynonyms отработал.
Дальше мы видим, что упал наш тест, вот Line 35.
Мы можем перейти в эту строчку и увидеть, что это наш тест AddSynonyms.
А вот у нас есть еще третий тест, TestCount — он не был выполнен,
потому что выполнение программы прекратилось.
А на самом деле, очень хорошо, когда у вас независимо от того,
сколько тестов выстрелило, сколько тестов упало, выполняются все тесты,
потому что в этом случае вы видите более полную картину, вы понимаете.
Допустим, если у вас только один юнит-тест вывел ошибку,
вы понимаете, что у вас, скорее всего, там одна ошибка в одной тестируемой сущности,
а в остальных местах все в порядке,
и вы можете спокойно сконцентрироваться только на одном блоке вашей программы.
Поэтому то, что при падении одного из тестов другие
не выполняются, те, которые вызываются после него — это заметный недостаток.
Кроме того, вот, смотрите, опять же вернемся в Eclipse
и посмотрим вот на этот вывод теста, который завершился успешно.
Он — давайте мы его даже откроем, вот он, — он в конце
своего выполнения выводит в стандартный вывод сообщение OK, чтобы мы знали,
что конкретно этот тест выполнился, отработал и не нашел никаких ошибок.
Но мы это выводим в стандартный вывод, в cout.
Я напомню, что мы, вообще говоря, решаем задачу,
задание по программированию из нашего курса про синонимы,
и решение этой задачи — вот оно сейчас тут у нас закомментировано, но оно,
как видите, вот здесь вот тоже должно выводить в стандартный вывод, в cout.
Что получается?
Что вывод тестов,
он смешивается с выводом основной нашей программы, решением нашей задачи.
И это плохо, потому что вы, отправляя решение в тестирующую систему,
вы можете забыть закомментировать вызов тестов,
и они тоже будут выводить что-то в стандартный вывод,
тестирующая система будет рассматривать это как вывод вашего решения,
не будет принимать ваши решения, вы будете думать, что у вас ошибка, а ошибки,
на самом деле нет — вы просто забыли закомментировать вызов тестов.
Так что тот факт, что тесты что-то выводят в
стандартный вывод — это тоже неудобно, это тоже недостаток.
Конечно же, в мире C++ существует большое количество
уже готовых фреймворков для создания юнит-тестов, в которых нету ни одного из
перечисленных недостатков — это большие широкоприменяемые системы,
которые хорошо оттестированы и весьма удобны в использовании.
Вот на экране приведены некоторые из них.
И я уверен, что кто-то из тех,
кто смотрит это видео, мог возмутиться: а зачем мы вот там в предыдущем
видео написали свой фреймворк для тестирования, какой-то такой простенький,
а сразу не стали учить вас использовать что-то из готового?
Но на самом деле мы сделали это осознанно.
Мы специально хотим в следующих видео исправить все указанные
недостатки в нашем простеньком фреймворке и создать свой,
еще один фреймворк для написания юнит-тестов,
чтобы вы могли им пользоваться и применять его для тестирования своих программ,
своих решений заданий нашего курса.
И мы это сделали осознанно, специально, во-первых, чтобы показать вам,
что текущих знаний вот эти полутора курсов по C++ уже хватает,
для того чтобы на C++ написать что-то практически применимое,
что-то полезное, что можно применять для тестирования своих программ.
Кроме того, так как мы вместе с вами напишем этот фреймворк
самостоятельно, вы будете понимать, как он устроен внутри.
Вы будете видеть, как те или иные конструкции языка
C++ применяются для придания фреймворку желаемых свойств.
Вы будете видеть, как C++ применяется на реальной задаче,
для того чтобы получился удобный фреймворк.
И, наконец, так как вы будете понимать, как он устроен, у вас будет возможность
самостоятельно вносить в него изменения, вносить изменения в этот фреймворк,
улучшать его и делать удобнее для вас.
Поэтому, начиная со следующего видео,
мы будем избавляться от перечисленных недостатков юнит-тест фреймворка,
последовательно продвигаясь к удобному и функциональному юнит-тест фреймворку.