EQSP 15/20: Тестирование второго порядка

Лекция в Высшей Школе Экономики для бакалавров четвертого курса.

Расшифровка видео
Введение
0:00
Итак у нас сегодня лекция номер 15 я хочу поговорить о таком топике который я
0:07
для себя сформулировал буквально недавно тестирование второго порядка такое название я ему дал и думаю что оно имеет
0:14
под собой достаточно оснований мы вообще говорим в этом курсе о том как тестировать софт и делать это
0:21
автоматически Как сделать так чтобы тот софт который мы пишем он находился под постоянным контролем поэтому так курс
0:27
называется insuran colity то есть мы должны не просто один раз настроить что-то
0:34
качественно не просто один раз написать софт качественно А мы хотим чтобы у нас
0:39
это было под постоянным наблюдением под постоянным контролем автоматических
0:44
инструментов автоматизированных инструментов чтобы мы как программисты не волновались о том что у нас этот
0:51
контроль потеряется чтобы не мы люди были ответственны за за
0:57
качество кода а какие-то автоматические автоматизированные средства тогда качество будет держаться на каком-то
1:03
уровне мы постоянно возвращаемся я вас постоянно возвращаю к мысли о том что нужно делать так чтобы программисты были
1:10
программисты были под контролем нужно чтобы эти инструменты которые мы создаем они нас прямо говоря не жалели чтобы они
1:18
нас удерживали постоянно под наблюдением потому что мы люди существа не
1:24
организованы хаотичные интуитивные импульсивные эмоциональные и так далее
1:30
мы пишем код некачественный мы не умеем делать это постоянно качественно Даже
1:36
если мы стараемся Даже если мы считаем себя хорошими программистами Все равно Все равно мы пишем
1:41
с ошибками и эти ошибки они бывают тяжелые бывают очень тяжелые бывает
1:47
конечно незначительные В общем если постоянно нас контролировать то мы будем в итоге будет продукт получаться
1:54
высокого качества и вам будет приятно с этим продуктом работать в этом По крайней мере я для себя много лет назад
Как не презирать себя за свой код
2:01
нашел такое как сказать Ну некий ответ на вопрос как мне не
2:11
презирать себя Зато за тот код который я пишу а это происходило происходило со
2:17
мной постоянно первые годы моей практики программе программирования начинаешь
2:23
писать программу очень хочется сделать все хорошо стараешься делаешь красиво проходит неделя месяц два месяца работы
2:32
с этим продуктом и тебе становится неприятно к нему подходить Ты себя уже
2:37
не любишь в той форме в которой ты видишь себя пишущего этот код количество
2:45
проблем растет количество технического объема технического долго увеличивается становится все тяжелее и тяжелее
2:51
разбираться в том что ты написал месяц назад В итоге это все накапливается и
2:56
раздражение которое возникает такое зрение к самому себе за то что ты что ты
3:03
делаешь Чем ты занимаешься Что ты не бросаешь этот продукт и переходишь к новому опять с нуля начинаешь опять тебе
3:08
кажется что все будет хорошо это этот цикл бесконечно этих перерождений он у
3:16
всех программистов один и тот же про него написано уже много книг Я здесь ничего не изобретаю Когда вам об этом
3:21
рассказываю все с этим сталкиваются постоянный Круг по которому мы ходим хочется делать хорошо мы делаем В итоге
3:28
Все разваливается потому что время нас убивает единственное И решение которое я
3:33
для себя нашел это поставить над собой над собой именно над самим собой
3:41
поставить контролёр автоматизированного контролёра который вы постоянно меня бил По рукам Я бы
3:48
постоянно этого контролёра усиливал бы его все мощнее и мощнее
3:54
и тогда мой продукт не будет скатываться в вот такой вот не будет разлагаться не
4:01
будет деградировать а он деградирует под влиянием времени под давлением изменений которые туда вношу вот и мы Для этого
4:08
делаем как мы уже говорили статический анализаторы У нас есть Style чекеры У нас есть автоматизированные тесты У нас
4:14
есть интеграционные тесты мы все это уже обсуждали на предыдущих лекциях есть еще один шаг который вы можете сделать еще
4:21
пойти дальше Вы должны постоянно будучи архитектором проекта Вы должны постоянно
4:26
думать о том как пройти дальше как усилить своего контролёра никак его
4:32
сделать мягче никак не могу сделать где-то срезать угол и сделать так чтобы какие-то поблажки вам давал Вы должны
4:38
его усиливать делать его все жестче и жестче и я вам уже говорил когда вы будете работать в команде
4:45
то Вас за это будут не любить вы будете под постоянным давлением находиться потому что команда будет сопротивляться
4:51
команда будет говорить Это слишком жестко мы не хотим такой контроль Мы хотим помягче и основной довод который
4:57
они вам будут приводить это они будут говорить что существуют разные мнения относительно того что вы нам предлагаете
5:02
допустим вы настраиваете свой этот контролер качества так чтобы например он
5:09
запрещал использование терминальных операторов а к вам обязательно придет кто-то из команды и скажет что
5:14
существует мнение что терминарный оператор наоборот это хорошо Это не зло это Бест и будут такие два полярные
5:22
мнения вы будете считать что это зло например а члены вашей команды будет считать что это добро и команда
5:27
разделится на две части на две половинки так будет происходить всегда при почти всегда почти всех
5:35
изменениях которые вы будете вносить в эти контролирующие инструменты команда будет пытаться вас
5:43
и она будет приводить такие доводы она будет говорить что у нас существует разные мнения Поэтому да вот как в чате
5:50
пишут демократия будут предлагать голосование будут предлагать демократические пути решения этих
5:55
вопросов Вы должны категорически это все отрицать и настаивать на том что есть только один путь это путь ужесточения
6:02
требований не смягчение а ужесточение никакой демократии при этом быть не должно вы должны идти по пути
6:08
исключительно по пути закручивания гаек все время делать все тяжелее и тяжелее команда должна все больше и больше
6:14
страдать как бы это ни звучало но программисты должны страдать от того что
6:19
над ними все жестче жестче контроль контроль качества тогда в итоге они
6:25
будут довольны на длительном интервале времени в итоге проект будет в хорошем
6:31
качестве и программисты в итоге будут счастливы на коротком интервале они будут страдать Потому что если вы
6:38
постоянно будете повышать жесткость этих ограничений то каждые несколько недель
6:43
они будут сталкиваться с чем-то новым их это будет раздражать напрягать еще вчера это можно было делать а уже сегодня это
6:50
делать нельзя и вот это изменение от более мягкого режима к более жестком
6:55
происходящее регулярно Конечно будет их очень нервировать И это будет команда
7:00
Может дестабилизировать вы можете терять людей при этом все это будет происходить но в итоге вы будете бороться за хороший
7:07
результат по окончании то есть максимально Думайте о том как закрутить гайки и Вот еще один метод закручивания
7:13
гаек сегодня обсудим тесты которые вы написали тесты которые вы создали они тоже
7:20
являются артефактом сами по себе помимо того что у вас есть собственно тот
7:26
артефакт который вы отдаете пользователю У вас есть тесты которые тестируют этот артефакт но сами тесты Вы можете тоже
7:33
тестировать То есть вы можете написать Еще сверху тесты второго порядка которые
7:39
будут смотреть на тесты которые пишут ваша команда контролировать их качество
7:44
если они некачественные по каким-то характеристикам то она будет эти тесты
7:49
блокировать В общем запрещать команде комедить например изменения если тесты
7:55
не соответствуют тем ожиданиям которые вас будет два уровня
8:01
тестирования Первое это сами тесты которые тестируют продукт и второй уровень тесты второго порядка которые
8:07
тестируют сами тесты например несколько сегодня примеров приведу первый пример конечно это
8:13
коврыч Control о котором мы уже говорили вот кавычкантрол контроль покрытия
Coverage Control (Тесты второго порядка)
8:18
тестами это собственно есть тесты второго порядка вы написали сам продукт потом вы написали тесты которые
8:24
тестируют этот продукт а потом вы хотите проверить Хорошо ли они его тестируют может они ничего не тестирует Можно не
8:31
только называются тестами на самом деле они Никакой пользы не приносят И вы тогда пишите Ну не напишите она
8:37
настраиваете а может быть и пишите настраиваете систему контроля покрытия которая как мы уже обсуждали но обсудим
8:44
еще в двух словах которые до того как тесты стартуют она подготавливает почву для этого контроля
8:52
потом запускает все автоматизированные тесты юнитест интеграционные тесты в основном это делается с Юнит тестами а
8:59
потом после того как тесты отработали Эта система проверяет Какое количество кода эти тесты
9:06
затронули покрыли Как говорится насколько они интенсивно прошли по тому
9:13
коду который мы написали и обычно Control он в самом примитивном
9:20
варианте он проверяет построчное покрытие То есть если слева мы можем представить себе программу которую мы
9:26
написали а справа мы представим себе тест который вызывает эту программу для того чтобы проверить что она рабочая то
9:32
мы можем эту программу слева представить покрытую в цветовом варианте закрашенную зелеными
9:39
или красными полосками зеленая полоска будет показывать что эту строчку наш
9:45
тест покрыл то есть Прошел по этой строчке пока происходило тестирование а
9:50
Красная будет показывать что это в эту строчку он не попал Потому что потому что не попал
9:56
это очевидные вещи тут я нет смысла погружаться глубже мы смотрели на занятиях с вами пару недель назад
10:03
примеры даже рассматривали как это выглядит Вы можете попробовать сами любой каварочный инструмент тест Cover
10:10
инструмент для того языка который вы используете но принципе я вам рассказал этот тест который проверит насколько
10:18
ваши тесты мощно покрыли или плотно покрыли Исходный код
10:23
это не гарантия что ваш код действительно хорошо работает если его покрыли на сто процентов если тест по
10:31
нему прошелся Ну прохождение теста по коду не совершенно не означает что тест его тестировал допустим у вас есть
10:37
функция которая складывает два числа калькулятор а плюс B в ней всего лишь
10:43
одна строчка она принимает Представьте эту функцию она принимает на вход А и Б внутри себе внутри себя происходит
10:49
сложение а плюс бы и Возвращение возврат результат то есть функция состоит из одной строки Return A + B и вот вы
10:57
хотите ее проверить как она работает вы подаете ей на вход два числа Один плюс два она вам возвращает 3 вы не
11:04
проверяете три это было или 33 и заканчивается Вот весь ваш тест он
11:10
вызвал эту функцию он отправил ей на вход две цифры Один плюс два и проигнорировал ее результат
11:17
вам покажет стопроцентное покрытие Вы действительно покрыли эту функцию тестами она Была выполнена по крайней
11:25
мере она не привела к остановке программы в этом в этой строчке по
11:31
крайней мере не произошло чего-то фатального того чего чего мы бы хоть
11:36
совсем не хотели видеть там сегментейшен фолд не произошел выход за границу памяти не произошел этого там не было но
11:43
сложила ли она два числа может быть она всегда три возвращает может длина цифру 3 возвращает на любом входе вы как раз
11:50
передали 12 она вам тройку вернула вы не проверяли два плюс два три плюс три и
11:55
так далее вас это каврич он вам никакой гарантии не дает
12:01
но по крайней мере как я говорю по крайней мере Вы убедились в том что эта функция жизнеспособна по крайней мере не
12:06
приводит к потере управления к полной потери контроля
12:13
вот так что я за то чтобы этот коврович был и он контролировался чтобы вы контролировали какой у вас уровень этого
12:20
ковры и он бывает не только построчный Бывает еще коврыч по бранчам еще когорроч по бранч каверыч лайн кавередж
12:29
Колл каверевич разные эти кавычки бывает Я тут неглубокий специалист Они разные эти
12:36
проценты покрытия и хорошо бы чтобы вы внутри своего проекта сделали так чтобы
12:41
когда этот каварович падает ниже какого-то предела то изменения от
12:47
программиста не принимаются вот есть у вас команда 10 человек вы архитектор Все программируют каждый
12:54
присылает свои изменения каждый день и вы как архитектор настраиваете механизм
12:59
приемки этих изменений какие-то изменения вы принимаете какие-то и отправляете на доработку Так вы должны
13:05
так настроить чтобы вы отправляли на доработку те изменения которые опускают ниже порога каверы всего кода
13:15
опять же безусловно к вам придут программисты и скажут что вы безграмотный человек что вы не понимаете
13:20
что этот каверш ничего не тестирует расскажет вам ровно то что то что я вам только что рассказал что ковры с не
13:26
гарантирует что код рабочий и так далее будет длинная история много слов вы все должны послушать и сказать я все равно
13:32
настаиваю что действительно что что мы будем принимать только те изменения которые выше этого порога порог
13:38
поставьте сами У нас например в проектах обычно мы где-то танцуем возле цифры 70-80 процентов вот мы ставим line
13:45
covery 70 процентов Иногда лучше выше 80 Просто после какой-то цифры допустим
13:50
после по моему 90 становится уже тяжеловато работать тяжело сделать так чтобы мы все уголки кода могли тестами
13:57
покрыть есть такие вещи которые не покрываем например как правило
14:03
конструкторы и есть вещи которые для покрытия которых нужно затрачивать много
14:09
усилий большие тесты Писать не всегда имеет смысл не всегда это ра правильно
14:15
тратить так много сил на то чтобы какую-то ерунду которая вот есть еще третья проблема Это просто дефекты этих
14:22
инструментов которые кавры считают они не идеальные и для языков
14:27
высокого уровня они еще более-менее для языков для Java например там для для
14:32
пайтона для высокоуровневых языков они более-менее мощные для языков низкого уровня типа C плюс например они слабые
14:39
Они могут целые блоки пропускать и не понимать что Вы на самом деле вызывали Эти строчки кода
14:45
они будут считать что их не вызывали для Раста Допустим мы используем последние
14:51
полгода этот коврич-контроль Он часто ерунду показывает видно что явно этот
14:57
блок кода был покрыт тестами А он говорит что у вас здесь красный цвет и поэтому низкий процент выдает то есть
15:03
тяжело программистов контролировать на высоких таких показателях требовать от них 90 5 процентов кадры если сам
15:10
инструмент ошибается Так что я бы вам посоветовал какую-то цифру выбрать около 70 Ну держаться ее то есть не опускать и
15:17
требовать чтобы тесты Что это значит Это значит что программист как это будет
15:22
выглядеть в реальности вы программист к вам придет с изменениями Вот вы архитектор к вам а я программист
15:28
Например я в вашей команде я пишу беру код из репозитория вношу в него
15:34
изменения исправляю что-то или добавляю новую фичу и присылаю вам падает кавыч это
15:42
индикатор прежде всего того что я не добавил Юнит тесты Свои Свои
15:50
это самая основная причина почему Пойдет ковры То есть я что-то внес какие-то изменения А тестами эти изменения не
15:56
покрыл или Ну вообще общая ошибка программистов который постоянно
16:01
сталкиваемся программисты фиксят что-то или нет что-то не покрывает тесты
16:07
Я таки просто всегда rejection и всегда причина реджета ровно Вчера такой был и
16:14
текст который я пишу всегда один и тот же откуда вы знаете что вы написали работает
16:19
вы присылаете в нем что-то изменилось какие-то строки тесты не изменились вы
16:26
не новый тест не добавили не существующий тесты не поменяли первый вопрос откуда вы знаете что это
16:31
изменилось второе что вы что-то сделали что то что вы сделали оно работает и второе Если вы пиксели баг то откуда вы
16:38
знаете что вы пофиксили его если у вас все тесты проходили до этого вы их не тронули прислали изменения в
16:47
коде значит тесты по-прежнему проходят так как вы тогда поняли что что-то
16:52
сломалось что вы фиксили вы же для того чтобы что-то пофиксить должны были сначала повторить эту проблему в тестах
16:58
то есть создать новый тест который бы подтвердил что Да действительно в этом блоке кода дефект а потом уже в этот
17:05
дефект исправляете и соответственно присылаете мне вдвоем эти изменения и кот который поменяли юнитест который вы
17:12
исправили Если вы присылаете просто код зачем эти изменения сделали
17:17
ничего не было поломано а мне объясняю так я живу запустил у
17:23
себя в консоли там открыл окно нажал я же увидел визуально Но это детский сад
17:30
визуально вы увидели А завтрак мы это не увидим визуально Ну так совершенно не
17:35
годится Все изменения должны приходить вместе с тестами если человек присылает эти изменения без тестов то это говорит
17:41
только о том что вернее с низким со сниженным код коврами Это говорит о том что у него нет теста все и у вас тогда
17:49
появляется объективный предлог отказать ему в этих
17:54
принятие этих изменений более того Вы даже можете ему не вступать с ним в диалог в этом случае потому что ему сама
18:00
машина откажет То есть у него просто сборка не пройдет если у вас внутри сборки вставлен этот контроль
18:06
не попадание ниже порога то он просто внесет свои изменения у него упадет
18:12
кавароч ниже 70 процентов просто сборка будет не проходить разговаривать не будет не будет к вам приходить и
18:18
пытаться вашу вас чем-то убедить просто у него Билд не проходит соответственно
18:23
пишет тесты вы себя избавляете от лишних переговоров с нарушителями режима
18:33
они сами все поймут у них это автоматически все случится Это хорошо Это здорово Чем меньше вы имеете
18:39
субъективности в процессе разработки тем лучше чем меньше зависит от вашего решения как человека тем лучше если вы
18:47
принимаете решение в проекте SMS Как сказать такие субъективные и используя
18:52
свой свою власть как архитектора Это плохо Это говорит лишь о том что вы не
18:58
сумели настроить проект грамотно так чтобы Без Вас принимались решения инструментами чтобы софт
19:06
принимал решение и вот Один из таких софтов это кавач-контроль Используйте его если его у вас еще нет
19:12
то Попробуйте по крайней мере узнаете Как это работает в серьезных проектах Вы должны с этого прям начинать приходя в
19:18
проект или начиная проект вы устанавливает создавая эту платформу
19:24
сборки вы начинаете с тестов
19:29
ставил чекинг Юнит тесты и кавер-контроль следующий инструмент здесь подсказывают
Mutation Testing
19:36
В чате это nutation testing действительно Это значительно более мощный инструмент чем коврыч-контроль но
19:44
он более дорогой по времени Такой тяжелый его конечно в сборку вставлять это трудно занимает
19:53
контроль он просто вместе с вами тестированием работает может быть немножко замедляя ваше тестирование
20:00
на какие-то проценты но не в разы а utation тестинг это из Юнит тестов
20:07
которые занимают 40 секунд он может сделать три часа То есть он может
20:12
серьезно очень Это совершенно другой Как это работает я вам расскажу что такое utation тестинг Вы можете почитать но на
20:19
словах это выглядит так вы берете [музыка] тесты вот у вас есть программа слева а
20:26
справа у вас тесты и вы запускаете инструмент который берет ваши тесты и
20:35
вернее берет вашу программу и в ней
20:43
[музыка] Я немножко запутался кого он меняет Ну
20:49
давайте начнем с этого он берет Вашу программу и в ней меняет какие-то в
20:54
каких-то местах меняет какие-то изменения делают мутацию ваша
21:00
программа мутирует она допустим была функция вас была калькулятор который
21:05
складывала два числа он заходит в нее меняет плюс на минус Раньше она
21:10
складывала он делает вычитание и запускается все ваши тесты и смотрит
21:16
Какие тесты хоть какой-то тест поймает эту ошибку или нет какой-то
21:23
какой-то тест хотя бы свалится в этом случае покажет зеленым красным цветом или нет допустим у вас был тест который
21:29
передавал этот калькулятор Один плюс два И как мы обсудили раньше игнорировал результат в этом случае он как был
21:35
зеленый так и после мутации он будет зеленый то есть в таком случае говорится что мутант не убит то есть мутант его
21:43
тесты не поймали не убили этого мутант соответственно этот мутант помещается как
21:49
ошибка Кстати как проблемный и записывается что смотрите в этой строчке
21:54
плюс на минус меняем они 1 ваш тест этого не поймал научитесь запускаются все тесты то есть
22:00
проходит по полной по полному он перекомпилирует все запускает все тесты потом он делает следующий проход Он
22:07
берет в другом месте меняет там плюсик на минусик оператор цифру на единичку на двоечку то сделать какие-то мутации по
22:13
коду и у него определенный набор этих мутаций ограниченный он эти мутации применяется сдает этих мутантов из
22:20
вашего из вашей программы делает такие мутанты этих мутантов много и опять запускает компиляцию опять всю сборку и
22:28
весь запуск тестов и опять смотрит Ну что среагировали тесты или нет И таких циклов он делает сотни Ну и подумайте
22:35
какое-то время будет занимать Как долго это будет происходить это будет долго В итоге конечно Это мощно потому что в
22:41
этом случае он вам покажет он проконтролирует качество ваших тестов Он Вам скажет что он действительно покажет
22:48
те места которые ваши тесты не покрыли не просто по строчкам что мы сюда
22:55
заходили Это хорошо ему этого недостаточно Он покажет что вы действительно не умеете ваши тесты не
23:00
умеют убивать мутантов вот такого вот такой конфигурации
23:06
и это этот результат будет мощный но я не видел такого чтобы этот такие такие
23:11
средства использовались при каждой сборке потому что они дорогие но иногда они должны использоваться Вы должны
23:17
как-то в какие-то промежутки времени может раз в месяц раз в неделю брать ваш
23:22
продукт и запускать все это мутационное тестирование пускай на несколько часов в итоге получать отчет подробный и вы
23:29
будете видеть в каких местах у вас этим мутанты неубиваемые и вы делаете Прочитав эту информацию вы делаете новые
23:36
тикеты для команды пишите новые новые задачи ставите здесь вот посмотрите тесты плохие здесь плохие здесь плохие и
23:43
команда их улучшает у вас это мутационное тестирование через неделю покажет что у нас нет 218 мутантов а 196
23:52
мутантов вот Прогресс еще через неделю вы опять их число снизите и так далее так вы будете постоянно обращать
23:59
внимание на количество этих мутантов и у вас их будет должно становиться все меньше меньше тех мутантов которые ваши тесты не умеют
24:05
ловить Вот это наверное наверное это Но это
24:11
мощный очень инструмент который второе то что я сказал это мутационное тестирование Используйте его оно вам
24:17
очень поможет Ну и расскажите если кто-нибудь Попробуйте это использовать и расскажите на следующих наших занятиях у
24:24
кого получится Будет очень интересно будет посмотреть я когда-то делал это ну несколько лет назад для джавы и
24:31
[музыка] такой был Экспериментальный подход мы Я не использую это в продуктах потому что
24:37
до этого как-то Руки не доходят потому что хватает и проблемы без этого Вот так мы как-то не доходим у меня не было
24:43
такого опыта чтобы я дошел до такого состояния проектов которым уже уже прям
24:49
все проблемы кончились и вот Давайте Ну если вы что-то серьезное
24:54
разрабатываете то мутационное тестирование это Маст хэв так это я вам рассказал второй
25:02
подход к
25:08
тестированию тестов значит Идем дальше
25:13
то что вот мы делаем не так давно и мне нравится все больше и больше мы делаем
Structural Tests
25:19
так называемые мы сами Их назвали так то есть тесты которые тестируют
25:26
структуру проекта вот есть у вас ваш
25:32
репозиторий с исходным кодом там лежат какие-то файлы они в каком-то
25:37
порядке разложены есть какие-то директории в этих директориях какие-то файлы в этих директориях под директории
25:44
и так далее в процессе жизни в течение жизни проекта
25:50
мы все как программисты работаем с этим всем контентом добавляя удаляя изменяя
25:57
двигая и так далее и опыт показывает что если команда более менее интенсивно работает она большая то там в итоге все
26:03
превращается в кашу не все на многое появляются какие-то непонятные файлы появляются непонятные директории
26:10
появляется размещение файлов как-то меняется переименовываются файлы как
26:15
каким-то способом почему-то По непонятным причинам особенно если в команде 10 плюс человек то через
26:22
некоторое количество месяцев многие вещи там становится уже не
26:27
не презентабельно выглядит Начинает все это поэтому мы можем написать тесты
26:33
которые запускаются вместе со всеми юнитами после точнее них и проверяют структуру
26:41
директория проверяют что структура файлов и их расположение внимание соответствует нашим ожиданиям
26:49
что у нас например в папке Test является только файлы с суффиксом Test что у нас
26:57
вот у нас например есть в одном репозитории [музыка] мы когда его мы запускаем тесты он во
27:05
временном директории тест наши наш юнитест создает временные папки эти
27:11
временные папки он именует там 1 2 3 4 5 и в них раскладывают контент который мы
27:17
дальше анализируем И вот со временем эти папки стали именоваться не один два три четыре пять Один два пять шесть
27:26
кто-то удалил третью папку мы не создаем больше И кто-то создал новую папку новый
27:32
сделал шаг который создает папку номер два Ну там она 2 дальше каким-то текстом
27:38
идет один с каким-то текстом два с каким-то суффиксом опять два с другим суффиксом 4 что-то такое потом 5 6
27:46
то есть произошла такая структурная дефект такой который естественно
27:51
выглядит странно когда человек А почему это обнаружилось что пришел человек в проект новый и открывает и смотрит и там
27:58
папки вот так поименованы 1224 он соответственно сделал тикет написал нам тикет что это все означает
28:05
Почему у вас папки так такими именами такими именами даются мы что мы сделали
28:10
в ответ мы не просто сказали секунду мы сейчас все исправим и перемены внутри кода сделали переименование мы сказали а
28:17
замечательно Значит нужно написать тест который будет проверять что эти папки
28:22
имеют имена идущие последовательно такой тест на таком вспомогательном
28:29
языке даже если сам весь проект мы написали тест на груве такой более скриптовой язык положили его рядышком и
28:36
он такой вот структурный тест straction не тестирует функциональность Не факт что тестирует структуру можно сказать
28:44
что он не такой важный как все остальные тесты потому что ну как бы там эти папки не именовались если оно работает и
28:50
функционально все устраивает то можно сказать что это Окей ну я думаю что это не так Я думаю что это важно
28:58
потому что как я много раз вам говорил по моему пониманию моим тайнобилити значительно важнее чем все остальные вот
29:06
эти биллитесь программного продукта если ваш продукт поддерживаемый если он красиво оформлен если он легко читается
29:12
если ваш код легко понимать то Это значительно важнее чем если ваш чем то что ваш продукт быстро работает
29:19
имеет много пользователей и так далее Почему так почему я так считаю потому что стоимость человеческих ресурсов она
29:29
значительно сейчас выше чем стоимость всех остальных ресурсов
29:36
чем стоимость процессоров памяти железо сетевых всех этих трафика и так далее
29:44
Все это дешевле чем люди раньше было не так много лет назад когда вы
29:51
еще когда вы не были студентами и вообще вас даже не было и
29:57
может быть даже меня то в те времена стоимость были наоборот то есть железо
30:02
было очень дорогим а программисты были очень относительно дешевые относительно оборудования каждый компьютер стоил как
30:08
сейчас как как дом как квартира наверное а программе труд программиста стоил
30:14
значительно меньше потому что тогда это было не такая профессия как сейчас и
30:20
соответственно неважно плохо написали мы наймем еще 5 программистов они там до пишут по-другому это неважно главное
30:26
чтобы то что они написали программа чтобы она быстро работала на компьютере потому что мы не сможем память добавить в компьютер так просто в компьютере были
30:33
ограничены вычислительные ресурсы вышли на мощности в нем была памяти допустим оперативной памяти были там килобайты
30:40
какие-то килобайты даже не гигабайты килобайт и соответственно оценили все программисты которые умеют сделать
30:46
программу компактной чтобы она быстро работала и мало места занимала и как она там написаны Сможем ли мы эту программу
30:52
понять завтра и модифицировать Это совершенно было в принципе наоборот считалось таким уровнем
30:59
профессионализма если человек писал программу которую никто не может понять Так я еще помню это еще когда я был
31:06
студентом было такое вот прям соревнование за непонятностью человек приносил программу в которой никто не
31:12
мог разобраться и он считал себя очень от этого очень был горд и считал себя профессионалом сейчас все
31:18
поменялось ног на голову сейчас наоборот если человек пишет программа в которой трудно разобраться то это просто плохой
31:24
программист это все потому что он требует его программирования Влечет за собой Дополнительные расходы для всех
31:31
остальных и конечно это не такой программист нам в команде Так точно не
31:37
нужен Может быть как бы работает самостоятельно и ни от кого не зависит то может быть как-то Ну и то какое
31:43
количество программ мы можем себе позволить иметь один раз и не поддерживать никогда такого не бывает
31:49
все программы имеют длительный жизненный цикл который зачастую длиннее чем чем
31:56
профессиональный интерес программиста к этому проект пришел и ушел Пришел полгода проработал год поработал в
32:02
проекте и пошел заниматься чем-то другим сейчас программисты очень часто меняют места работы проекты и так далее это
32:10
хорошо но только надо понимать что при этих всех изменениях надо чтобы программист надо контролировать
32:16
программиста как мы уже вначале сказали бить по рукам если он делает то что непонятно другому
32:22
программисту и эта структурные тесты тесты которые тестируют структуру кода это вот именно
32:27
бить по рукам того кто пишет чисто для себя он понимает как это должно
32:33
выглядеть Но всем остальным Это неведомо почему там называются директории 1 2 2 4
32:38
кто-то это понимает кто это сделал Но пришедший вновь человек совершенно логично пожал плечами и нас
32:46
обвинил в том что мы тут сказать неаккуратно работаем неаккуратно
32:53
раз мы неаккуратно работаем то грош нам цена Вот это наш уровень профессионализма и мы соответственно быстро написали эти тесты и продолжаем
33:00
их писать мы их написали и стали думать А можем ли вы какие-то еще тесты также написать Сразу возникает желание как я
33:06
вам вначале сказал о архитектора в этом я в этом проекте архитектор у меня возникает сразу мысль А еще как я могу
33:12
поймать нас нас на ошибках как я еще могу ужесточить контроль что еще могу
33:20
такого сделать чтобы еще было построено пока не так много придумалось мы пока
33:25
реагируем на тикеты тики человек написал сказал вот мне что не нравится мы на него отвечаем вообще как мы обсуждали
33:32
раньше изменения в проекте если проект уже идет
33:39
Не первый месяц в работе то конечно основные изменения которые мы вносим они являются реакцией на дефекты кто-то
33:46
должен репортить дефекты и показывать нам что у вас слабое в основном дефекты это индикатор
33:52
того что слабая система контроля качества Когда вам создают Банк в проекте Вы должны понимать что это
33:58
значит ваша система контроля качества недостаточно сильная это не ваша вы не
34:03
себя должны винить и не того программиста который написал этот код вы вините систему контроля качества она
34:09
пропустила эту проблему Продакшен или в репозитории думаете о
34:14
том как сделать так чтобы завтра на эту проблему не пропустил Вот это вам третий механизм третий такой
34:23
способ создания этих тестов второго порядка тесты такие
34:29
структурные что ли дальше Значит есть
34:36
то на что опять же я обратил бы внимание Как сделать тесты сильнее есть механизмы
Механизмы “рандомизации” тестирования
34:42
разные механизмы Я не знаю точно Какое правильное имя им всем дать совокупности
34:47
Ну давайте скажем механизмы рандомизации тестирования То есть когда вы пишете
34:53
тесты вы это делаете в неких таких тепличных условиях и делаете так чтобы
35:00
они в итоге у вас запустились где-то у вас на лаптопе Где вы это делаете Где вы программируете или даже в системе Какие
35:07
integration все равно прошли какие-то условия определенных заданных эти тесты
35:12
должны запуститься люди стараются это мы это понятно это уже обсуждалось люди
35:18
стараются эти условия сделать максимально
35:23
гетерогенными что ли сделать такими в которых много разных
35:30
переменных окружающей среды так бы я сказал например Вы когда настраиваете сборку на github Action к примеру Вы
35:38
стараетесь должны стараться использовать разные операционные системы там есть такой механизм матричной сборки так
35:45
называемые Где вы внутри github Action конфигурации вы указываете операционные системы на которых будет сборка
35:51
проходить и хороший практикой считается указанием всех трех доступных сейчас
35:56
настоящий момент там три доступно это Windows Ubuntu и macos и нужно все три указать в
36:04
идеале Если вы делаете какой-то любой софт для себя делаете софт все равно Старайтесь чтобы на трех операционках он
36:10
собирался и более того на разных версиях языков программирования которые вы
36:16
используете там Если вы на Джаве пишите то сделайте так чтобы он собирался и на Джаве 11 и
36:22
на 17 и на 8 Например если вы совсем хотите чтобы у вас было все очень так
36:28
надежно то Старайтесь использовать и старые версии тоже чтобы он и на старых версиях тоже тоже работал
36:35
это такой хороший хороший тоном хорошим тоном считается делать софт который бы
36:41
работал на достаточно старых версиях платформ на которых он на которых он
36:48
должен работать и вы получаете такую матричную сборку почему называется матричная потому что вы имеете матрицу
36:54
по горизонтали можно сказать что вы имеете операционной системы по вертикали Вы имеете например версии языка
37:00
программирования вот у вас есть 3 Java восьмая 11 и 17 и по горизонтали У вас
37:06
есть Ubuntu macos и Windows и вот получается 9 сборок то есть девять раз
37:13
запустит вашу сборку и в 9 раз попробовать ваши все тесты запустить
37:18
и все 9 должны быть зеленого цвета все 9 должны показать вам что сборка
37:25
сборка успешно Вот Но это все равно не все здесь нет
37:32
никакой неопределенности здесь все достаточно детерминировано то есть эти 9 Все сборок
37:39
вы их один раз настроите и они будут более-менее стабильно собираться Если вы
37:45
еще и укажете все версии фиксировано как я вам рекомендовал делать Вы скажете что это не просто ubuntual бунту 22.04 Это
37:53
не просто Windows Windows там 20 021 2021 и Java тоже это будет конкретная
38:01
Java 17 Причем сейчас там уже не просто Джава 17 указывается Именно какая какая
38:09
производитель несколько этих вот вы указываете конкретно какая это будет это хорошо Это
38:17
хорошая практика она ведет к стабилизации тестовой системы к её
38:22
детерминизм вы будете точно знать что если у вас вчера Этот тест проходил на
38:28
Ubuntu и Java 11 то очень высока очень высока вероятность что он будет И через
38:34
год тоже проходить она не сто процентов Потому что есть равно вещи которые переменные которые будут за этот год
38:40
изменятся Java останется та же да мы будем брать Ту же самую джагу мы будем брать тот же
38:45
самый бунту этот момент уже ubuntual идет вперед это будет уже не 22 26 например но вы по-прежнему выйти на
38:51
старой собираться и более-менее гарантия сохранится но при этом может быть какие-то внешние зависимости допустим
38:56
ваши тесты во время сборки к примеру у меня был такой случай
39:02
повторяется постоянно Я использовал систему для
39:09
нарубе использовал систему для каверч-контроля кстати и она была версии
39:14
что-то там ноль точка чего-то там 6.0
39:20
я им несколько лет использовал и оставил свои продукты зависимы от этой версии забыл давно про
39:27
них возвращаясь к ним они собираются этот продукт вот он не собирается и говорит нет такой версии 060 я сначала
39:34
не понимал как может быть такое если она была И вот поскольку врубе там есть возможность
39:41
удаления вот в Джаве в мейвинг-централи там нет возможности удалять артефакты они там и мьютабл один раз задеплоил и
39:48
он там пожизненно А врубе можно удалить и в npm можно удалить есть такие package
39:55
Manager package менеджмент платформы площадки на которых можно удалять артефакты это на мой взгляд плохая
40:03
практика Но вот Она присутствует его снесли я пытаюсь собрать зависимости от
40:08
дальше Вы понимаете что произошло не приходится открывать этот продукт который я писал три года назад вспоминать что там делать находить
40:15
альтернативу этой версии пытаться ее подставить соответственно не всегда это
40:21
может работать здесь слава Богу Она работала потому что не знаю почему они удалили ту версию
40:26
следующая версия у них все было более-менее также вот Это не единственное Почему может быть
40:32
детерминизм нарушится и почему вы можете через год обнаружить что ваш продукт не собирается он может быть например Вы же
40:40
ваш продукт имеет интеграционные тесты значит вы зависите как файловая система вы может быть зависеть от интернета Вы
40:47
может быть зависит от каких-то внешних обстоятельств многое может быть и через год вполне ваш продукт может не
40:53
собраться даже если вы все версии зафиксировать Но это одна сторона медаль другая сторона
41:00
медали Вы можете специально вносить Вы можете специально сделать так свои
41:07
тесты про дизайнить чтобы даже в этой матрице ваши тестовые сборочный сделать
41:14
так чтобы в этих ячейках Каждый раз когда Тест проходит чтобы у него
41:19
менялись обстоятельства которых он запускается вывод и вы их рандомизируете Ну например
41:26
самый простой способ во многих системах сборки автоматической есть
41:31
такой флажок даже флажки такие есть которых указывается запускать тесты случайные последовательности или в одно
41:37
и той вот я бы рекомендовал запускать случайные последовательности ни один за другим Как вы их написали Юнит тесты
41:44
потому что они могут зависеть друг от друга Они могут какие-то быть процессы между ними
41:49
которые запуская их последовательно не будут не видны они будут работать если у
41:55
вас 100 тестов они идут один за другим они будут этой последовательности эти 100 подряд они работать будут Я много
42:01
раз видел ситуации когда таких ситуаций когда 100 тестов подряд они проходят потом мы запускаем и эту же сборку на
42:09
другую операционке и почему-то она не проходит почему-то некоторые тесты падают и после анализа понимаешь что это
42:16
те же 100 тестов но запускаются в другой последовательности потому что на той операционке именование файлов но другое
42:23
Там они сортируются просто операционной системы по алфавиту и сортировка другая
42:29
по-другому операционка сортирует файлы получает другая последовательность
42:34
что мы в итоге имеем Там они не проходят здесь у нас они проходят И это хорошо
42:40
такая рандомизация вынуждена такая незапланированная что ли не задуманная
42:45
нами рандомизация она в итоге дает хороший эффект она показывает что тесты не зеленого цвета и мы их фиксим находим
42:53
эту зависимость между ними находим эту проблему и убираем но во многих это
43:00
бывает так что не будет такого не детерминизма не случится натуральным способом я вам предлагаю его
43:08
добавлять это еще один способ четвертый способ на сегодня такого
43:14
тестирования второго порядка то есть во время тестов Старайтесь эти тесты тоже
43:19
потестировать путем рандомизации путем например выставление в разном в разные
43:25
последовательности это первое второе Вы можете именно вход давать данные разного
43:30
генерировать данные чтобы они те данные которые они используют во время тестирования чтобы они все-таки
43:37
генерировали случайным образом не цеплялись зафиксированные строчки
43:42
фиксированные фиксированные блоки блоки данных а
43:47
пытались их случайным образом создавать Это создаст тоже не детерминизм дополнительный А значит
43:53
больше чувствительность ваших тестов к повышенную чувствительность это наверное
44:01
на этом можно поставить после этого точку у тестов будет выше чувствительность это хорошо
44:07
то есть тест будет такой fragile он будет А значит вы его в итоге исправить
44:13
В итоге его потратите время на его стабилизацию он станет лучше
44:19
Чем более тест фрейджайл тем это лучше
44:25
Так я считаю конечно Тут наверное такое радикальное такое заявление Она наверное
44:30
неправильно потому что мы будем идти дальше по этой шкале франжилете этой то мы попадем на В итоге
44:37
уткнемся в тесты которые просто [музыка] слишком франчай Хотя вот я думаю
44:42
возможно ли такое представить чтобы Тест был слишком франчайл чтобы он такой был флаки тест часто часто сбоил
44:50
[музыка] Ну это хорошо если это наверное хорошо если так происходит если мы в итоге его
44:58
если мы в итоге находим Почему он так себя ведет и его приводим состояние когда он стабилизирует но стабилизируем
45:05
его не путем убирание уничтожение из него не детерминизма и мы видим что он допустим
45:12
у нас какой-то тест который на допустим он тестирует наш калькулятор И вот он передает калькулятор разные цифры 2-3 мы
45:19
сделали допустим вы написали с тем стой философией которая вам сейчас
45:25
рассказываю в голове и сделали так чтобы два случайных числа передавал всегда каждый раз мы запускаем тест и всегда
45:31
это два рандомных рандомных и он передает и у нас он не
45:37
работает флаки становится Почему Потому что наш калькулятор допустим вместо сложения двух чисел возвращает всегда
45:42
тройку то конечно наш тест будет ну будет супер нестабильный В каких-то случаях очень
45:48
редких он будет показывать зеленый цвет потому что иногда эти два случайных числа будут попадать Так что сумма между
45:54
ними Тройка это будет редко подавляющем большинстве случаев наш тест будет падать Нужно ли нам менять тест и
46:04
говорить слушайте да давайте уберем рандомизацию Давайте поставим единичку и двоечку пусть он их складывает и все
46:10
будет спокойно Нет не нужно так делать надо все-таки посмотреть на код посмотреть Ну как же наш тест все-таки
46:16
он такой нестабильный что-то наверное с кодом поправить код сделать из него правильный
46:22
калькулятор То есть это хорошо когда тесты фрейджайлы Чем более вы будете делать
46:27
фрейджайл Чем больше вы будете вносить в них этой рандомизации этого не детерминизма Тем вы в итоге выиграете в
46:33
ваш проект будет более Ну более такой
46:39
В итоге качество будет выше потому что чувствительность у теста повысится Как вы эту трандомизацию будете делать Ну
Как делать “рандомизацию”
46:45
первое это флажок Вы можете ставить в билде посмотрите у каждого языка есть программирование такое такая опция текст
46:51
с которым я сталкивался везде это есть Попробуйте давать случайные числа на вход в каждом тесте не Используйте
46:58
константы Старайтесь не использовать константы Если вы пытаетесь использовать всегда всегда
47:05
если можно то генерируете случайное что-то что попадет в тест
47:10
модуль который вы тестируете вот Ну да менее порядка порядка теста
47:19
между собой Ну наверное еще третий способ это их параллелизация То есть вы
47:26
можете настроить настроить вашу систему сборки и тестирования продукта так чтобы
47:32
она выполняла тесты параллельно иногда это по умолчанию происходит как
47:39
по моему в последних версиях Java этого под Main плагина Вот но не всегда но
47:47
лучше это включать лучше чтобы тесты выполнялись параллельно потому что тогда вы будете иметь шанс поймать
47:52
ошибки с конкарте и это тяжелые ошибки для конечно для обнаружения но система
47:59
вам будет подсказывать что смотрите Эти ошибки имеют место Вы конечно их вам будет трудно их найти Почему они Где они
48:06
находятся Но вы по крайней мере будете видеть что они там присутствуют то есть включайте этот механизм парализация
48:12
тестов чтобы каждый каждый тест работал в своем потоке и этих потоков было там
48:18
можно настраивать почти всегда это настраивается вы говорите сколько этих потоков должно быть 4 8 10 какое-то
48:24
количество чтобы тесты шли все параллельно тогда конфликты между ними если они есть они будут вылазить наружу
48:30
и вы будете иметь будете иметь чувствительность ваши системы тестирования повысится ее
48:36
чувствительность повысится таким образом вы протестируете свои тест сделайте их более
48:45
поставить их тоже под под тест под анализ
48:51
Вот это следующее что я хотел сказать это по-моему четвертое уже до структурный мы поговорили ковридж
48:57
metation tasting структурные тесты и рандомизация
49:02
следующее еще два осталось значит следующее хотел
49:08
вам сказать что многие тесты
49:14
Я думаю что у многих у меня у меня это в практике часто встречается многие тесты
Зависимость тестов от интернета
49:19
зависят от интернета зависит от сети не просто от
49:25
сети от интернета Мы во время тестов Обращаемся каким-то внешним данным то ли
49:31
мы идем в какие-то ресурсы достаем снаружи то ли мы Обращаемся и что-то
49:39
что-то внешнее что-то вовне В общем мы используем это ну частый случай особенно
49:45
если разработка идет какого-то чего-то такого с вебом связаны Если вы
49:51
конечно разрабатываете приложение для командной строки то у вас не будет внешних внешних зависимостей Но если вы
49:58
делаете что-то более сложное такое несложное что-то более такое ориентированное на работу с сетью с
50:06
внешними ресурсами то вы будете ваши тесты будут идти в интернет давайте так скажем они будут идти в интернет и
50:12
оттуда что-то доставать своего выполнения и в большинстве случаев
50:18
Интернет будет в наличии у Вас он будет иметь будет работать и он есть
50:24
и у вас на лаптопе и на сервере везде он есть но когда вы начнете компилировать
50:30
это где-нибудь в самолете как у меня часто бывает то вы увидите что ваши тесты вдруг все вместе или большее
50:36
количество просто не справляется не может работать потому что у нее там Network из ноты вейла было что-то не
50:42
вела начинается Падение большого количества тестов У меня такое происходит периодически И в этот момент
50:48
мы понимаем что тест написано неправильно мы понимаем что тесты вместо того чтобы
50:54
использовать мокки использовать такие как мы это называли
51:01
фейк зависимости они этого не делают а опираются на реальные интернет-ресурсы
51:07
но выявить это не получается легко потому что мы не привыкли к тому не привыкли работать без интернета у нас
51:13
как бы есть всегда мы лаптоп открыли интернет у нас есть но сразу подключился но попав в самолет один раз Вы понимаете
51:20
что ваши тесты не написано неправильно так вот Я
51:25
рекомендую этот режим самолета включать преднамерен то есть пытаетесь собирая
51:32
свой продукт на сервере вы этого не сделаете вы не отключите к экшене
51:37
их сервере интернет и вы не Отключите интернет на каком-нибудь дженкинза который у вас компании допустим стоит
51:43
там он всегда присутствует значит ваши тесты всегда там будут проходить пробуйте делать выключать интернет на
51:49
лаптопе просто отключайте сеть и запускаете весь всю вашу сборку вы увидите что вы увидите
51:54
вы увидите в каких неожиданных местах ваши тесты оказывается зависит от
51:59
внешних от внешних обстоятельств очень неожиданных местах и вот
52:04
Попробуйте сделать так чтобы ваши тесты работали при выключенном интернете это
52:10
не задача не всегда простая не всегда это легко сделать иногда вам кажется вы
52:15
программируете и вам как-то кажется что это уже само собой разумеющееся ресурсы
52:20
типа типа каких-то файлов в интернете которые Ну да они там есть но просто их скачали и работаем Выключите интернет и
52:28
увидите как ваши тесты себя ведут если все пройдет чисто то скорее всего Либо вы разрабатываете какой-то ком онлайн
52:34
инструмент который ни от кого не зависит либо у вас все очень хорошо написано сомневаюсь что это будет так
52:42
вот такой Наверное пятый способ сделать проверку своим тестом как это
52:47
автоматизировать я не знаю я не представляю себе как можно этот механизм поставить под автомат Как сделать так
52:54
чтобы вся сборка где-то в автоматическом режиме проходила без включенной сети
53:01
Ну не знаю такого я не представляю если у кого-то есть идеи Напишите Я с удовольствием попробовал
53:07
потому что мы сталкиваемся этой проблемой часто вот у нас есть проект который зависит от внешних составляющих
53:13
и мы в каких-то местах я скажу как мы решили эту проблему мы просто мы просто написали такой Чекер который проверяет
53:21
что интернет есть или его нет и прикрепили его к ко всем тестам которые
53:27
зависят от интернета и такой читинг получился эти тесты перед тем как стартовать они просто проверяю есть
53:33
интернет используя этот Чекер такой микромодуль мы сделали который обращается в google.com если ничего туда
53:40
получить не может то он говорит у нас Интернет выключен и тогда тест просто говорит я себя игнорируется тест
53:45
делается дизейблт и он отключается и получается все работает но потом приходит какой-то Новый программист или
53:52
старый программист и делают какую-то новую задачу и соответственно не думает об этом о том что нужно добавить этот
53:57
чек во вновь созданный тест и он создает тест забывает этот чек у него все
54:04
срабатывает на сервере все срабатывает сборка срабатывает потом я открываю это все в самолете и у меня все падает я
54:10
понимаю что я вижу что а так мы добавили новый тест забыли прикрепить я прикрепляю этот Чекер у меня все условно
54:18
самолёте работает Как это сделать автоматически Я не знаю Если вы придумаете это будет здорово вот
54:24
такое такая вот рандомизация что такое детерминизм то есть сказать тестом что
54:29
вы сейчас данный момент работаете в выключенном интернете вот справитесь или нет И они должны
54:36
справиться они должны либо себя Дизей был Либо они должны сказать я тест который очень сильно зависит от
54:41
интернета поэтому я себя помечаю как дизейбл в данной текущей ситуации и прохожу дальше но там не должно быть
54:48
красный крэши ксепшен потому что это Мисс литинг Information уже там нет Exception на самом деле нет дефектов
54:55
программе нет Почему тесты падают с красными сообщениями с огромными стэктрейсами программа Рабочая это Фолз
55:03
Фолс Позитив response от них ложная срабатывание тесты срабатывают ложным образом и человек соответственно Сидя в
55:11
этом злополучном самолете Он не понимает что произошло и сначала Это требовала от
55:16
меня каких-то усилий понять разобраться почему только что вот я был в офисе у меня все собиралось А здесь вот я открыл
55:22
через час и мне ничего не собирается я потом понимаю а так это же вот интернет
55:28
Вы должны как-то подумать вы такие условия могли для ваших программ создавать Ну и последнее что я хотел
Структура тестов: 1. Assertions
55:34
рассказать это как мне кажется должны быть устроены должна выглядеть структура
55:41
тестов я написал статью на эту тему некоторые месяц назад такой блок
55:48
блокпост который рассказывает о том как мы можем что обращать внимание Когда вы дизайн тесты
55:53
Значит первое самое не самое начнем начнем с первого это когда мы пишем
56:01
тесты опять же это такой метод тестирования то есть тест работает мы вот я сейчас все это рассказываю исходя
56:07
из положения что все работает и продукт работает и тесты написанные тесты
56:12
проходят все как бы хорошо но нехорошо то есть мы сейчас начинаем анализировать все же как мы можем Наши тесты и их же
56:20
протестировать И проверить что они эффективно написаны первая проблема которую мы допускаем программисты очень
56:26
часто допускают это они пишут мы пишем вот такого вот рода
56:32
совершенно Вы знаете что тест обычно состоит из какой-то подготовки подготовки а потом идет команда которую
56:40
мы проверяем что то что мы там где-то посчитали равняется тому что мы ожидаем Вот такая формулировка этого шершено а
56:48
Серж она неправильная она неэффективная она не помогает программисту В каком
56:55
плане не помогает она не дает она Окей для того кто писал этот тест пока вы его
57:01
пишите вы его написали а сёрф сработал у вас все зеленое Вы закамители Вы счастливы но приходит момент когда тест
57:07
начинает выполнять свою работу по информированию нас о том что что-то мы
57:14
поломали вот я зайду в этот код через время которое вы написали и что-то в
57:19
этой Вот в этой модуле который вы тестируете что-то изменил и он перестает перестанет как-то работать что я увижу
57:26
на экране когда запущу этот тест я увижу просто сообщения которые мне выдаст Джей
57:32
Юнит например она будет что-то типа section fail sorrysentworkbuy
57:38
Мне нужно будет каким-то образом дешифровать это сообщение угадать Что
57:45
случилось Почему меня сейчас возвращается 5 Вы ожидаете один Я не
57:50
понимаю почему вы один ожидаете эта информация утеряна утрачена всегда она осталась в голове у того кто это писал
57:55
мне нужно будет долго Это декодировать дешифровать значительно удобнее Если вы
58:01
напишите в таком формате в этом случае во-первых Я рекомендую использовать хемкрест это библиотека Вы
58:08
можете использовать можете что-то другое Но самое важное что здесь мы во-первых сравниваем используем сравнение через
58:16
вспомогательные вот такие конструкции типа иквалту и мы еще и добавляем некий
58:21
вспомогательный текст который объяснит человеку когда это Серж работает негативно объяснит человеку что
58:29
случилось Вы должны думать о том кто будет придет после вас себе а будущих программистов
58:37
это вообще то Что отличает архитектора от кодера кодер думает о себе ходит
58:43
программирует для себя кодер делает так чтобы ему было комфортно архитектор думает о том что будет когда он уйдет из
58:49
проекта архитектор думает о следующих поколениях людей которые придут После него кулер Думает что он очень важен
58:56
незаменимый человек лучше него никого не бывает его никогда не уволят архитектор думает меня уволят Завтра что будет
59:02
после меня что после меня останется два два разных
59:08
я вам рекомендую Мыслить как архитекторы считайте что вас завтра из проекта уволят что после вас останется кто
59:14
поймет то что там написано Не считайте себя незаменимым ценным
59:20
персонажем вы просто ресурс который в проекте в данный момент находится чтобы проекту улучшить подходите к себе так
59:28
вот утилитарно мыслите как архитектор как люди которые на уровне проекта стоят не на уровне
59:35
кодеров которые не мыслят категориями проекта мысль
59:40
категориями Я моя зарплата мой стул мой стол и это все думаете категориями более крупными проект продукт компании на этом
59:48
уровне вы свою роль должны понимать что вы сейчас просто контрибьютер который который улучшает тот продукт который
59:56
приносит людям пользу вам соответственно деньги и нам всем вы делаете что-то
1:00:02
полезное значит вы контрибьютона вы контрибьютер вы не вы не вы ценность
1:00:07
контрибьюшен который вы делаете здесь контрибьюшен маленький здесь человек сделал маленький
1:00:14
контрибьюшн Он не подумал о том как как сделать его как этот contribution сделать так чтобы его можно было
1:00:19
использовать дальше Конечно мы понимаем что здесь он сделал вот какой-то контрибьюшн ценный но здесь вот он
1:00:25
поленился здесь его размер его contribution он не высок в этом же коде
1:00:30
программист постарался получше он сделал тот же контрибьюшен на входе в начале а потом он подумал так разберется ли кодер
1:00:37
который придет после меня через год Почему эта цифра там этот каунт не равен
1:00:43
единички будет тяжело давай-ка я ему допишу скажу что это Тотал каунтов Хотя это тоже не очень такое подробное
1:00:49
описание лучше было бы его сделать еще подробнее вот вам первая рекомендация тесты должны
1:00:55
быть написаны так чтобы вы как бы посылали сообщения будущим будущим людям будущим
1:01:01
программистом второе тест класса Когда вы создаете
Test Classes
1:01:09
классы тестовые то вы должны стараться точнее
1:01:14
обязательно допустим у нас есть реальный модуль который вы тестируете называется Фрейзер тот который мы только что
1:01:19
упоминали и вы пишите тест так вот ваш тест
1:01:25
должен называться вот так то есть ваш тест должен соответствовать
1:01:31
по имени по имени должен быть однозначный маппинг один к одному вашего
1:01:37
теста и вашего модуля который вы тестируете Хотя очень часто это не так очень часто
1:01:44
программисты совершают ошибку и у них бывает допустим один модуль а тесты именуются вот как им хочется этот тест
1:01:51
он рекомендует тесты потому что ему так удобнее сгруппировать было эти тест методы эти тесты потому что он забыл эти
1:01:58
тесты потому что потому что потому должно быть однозначно Иван туман Если у вас есть модуль который вы
1:02:05
тестируете называется А то тестовый блок тестов тестовый класс называется а тест
1:02:10
или почему это важно потому что когда я опять же думаю о будущем думаю других
1:02:17
программистов когда я приду в ваш проект и у меня начнет найти тесты падать я
1:02:23
хочу быстро найти Почему что я не так где я что поломал что тесты упали То есть я буду
1:02:30
использовать как помощников я возьму продукт изменю внесу какие-то изменения запущу все 500 тестов и из них 23 теста
1:02:38
будут красного цвета Я хочу по их имени сразу же понять о каком модуле идет речь
1:02:44
то есть они не должны быть как ну как сказать как такие гайдлайны для меня как
1:02:50
такие направляющие которые мне сразу покажут Иди в модуль фрейзис Там ошибка
1:02:55
ты там что-то поменял Оттуда пришла проблема если у вас такого однозначного мафинга
1:03:01
нет просто вы затрудняете работу будущих программистов И вообще делаете смысл
1:03:06
ваших тестов становится его меньше становится пользы и выгоды от
1:03:12
ваших тестов меньше Старайтесь делать один на один к одному не Старайтесь всегда так делаете Это жесткое правило
1:03:19
это не просто рекомендация прям жесткая Я бы рекомендовал вам даже написать какой-то инструмент какой-то контролер
1:03:24
который бы проверял Существует такой жесткий или нет если его нет это такой вопрос
1:03:31
структурных тестах Вы можете прям написать какой-то скрипт который это все анализирует и показывает что у вас есть
1:03:37
файлы в тестовых территориях находятся которые не матятся один на один предлагаем их переименовать удалить и
1:03:43
так далее То есть Прямо блокировать сборку если имеются такие
1:03:49
Ну тут маленький комментарий я добавил что мне могут сказать но если очень длинный тест-классы будут у меня есть
1:03:55
какой-то модуль там фей фрейзис Да я написал на него Фрейзер тест и он у меня получается длинный длинный длинный Я
1:04:01
говорю что это ноты проблемы То это совершенно не проблема потому что это не те классы которые из
1:04:07
объектно-ориентированного программирования это просто коллекции скриптов то есть тестовые класс это такая
1:04:16
синтетическая структура Которую люди придумали за неимением лучшего то есть языках программирования К сожалению нет
1:04:23
такого понятия как тест У нас есть классы У нас
1:04:28
есть объекты У нас есть методы У нас есть переменные у нас нет тестов по крайней
1:04:34
мере я не знаю такого языка программирования который был бы тест как сущность и Поэтому приходится Вот так
1:04:39
выкручиваться и брать класс то что есть у нас языке и брать из него метод то что
1:04:45
есть языке и называется тестами Поэтому если у вас один длинный тестовый класс который 5000 строк это вообще не
1:04:51
проблема потому что это не классно просто коллекция скрипт за скриптом идущий и зачастую у меня по крайней мере так
1:04:58
если я если продукт более-менее развитый то у меня бывает так что маленький САМ модуль который я тестирую огромный
1:05:05
тестовый класс которым в модуле Может быть 100 строк кода А в тестовом классе 2000 потому что там много скриптов много
1:05:11
этих методов которые с разными Под разными углами тестирует мой дальше следующая рекомендация существует
Test Prerequisites
1:05:18
такое большая боль для всех нас это тест вот эти вот при реквизиты то есть такой
1:05:25
тест так сказать компоненты модули которые нужны для
1:05:31
тестов и люди не знают куда их деть люди не знают куда их положить Вот например первый подход которым люди пользуются
1:05:37
это делают внутри тестового класса они делают приватные статические методы
1:05:42
которые подготавливают что-то для тестирования здесь вот мы
1:05:48
допустим делаем сначала Там наш модуль который мы хотим протестировать наш объект потом мы вызываем этот припер и
1:05:55
происходит подготовка и почему это нужно потому что может быть много тестовых методов которых нужна эта
1:06:02
подготовка и поэтому мы должны куда-то вынести мы должны куда-то положить не будем дублировать одно и то же это не
1:06:09
красиво если во многих методах этих тест методах будут повторяющиеся блоки поэтому люди выносят Это куда-то куда
1:06:15
выносить они не знают первое что они делают зачастую это делают статический приватные статический метод которым вся
1:06:21
эта какие-то вспомогательные действия повторяющиеся они там находятся
1:06:28
Ну это лучше чем повторять одно и то же конечно в кассу в каждом тестовом методом конечно это вот написал ронгуэй
1:06:34
но это хотя бы вэй какой-то он хотя и ронг но он даст вам возможность избежать повторения
1:06:42
то есть делайте Так ну можно пойти немножко дальше И эти статические методы
1:06:49
вытащить в некий некий вспомогательный утилитный класс так называем я в принципе против этих утилити-класса но
1:06:55
тем не менее это ронгуэй поэтому я его рассказываю Если вы его сделали этот утил класс то положите его в какой-то
1:07:01
отдельный директории чтобы он был не там где все тесты лежат тестовые классы чтобы он как-то в каком-то Саппорт
1:07:08
директории как-то все-таки в стороне Хотя это конечно криво Потому что если
1:07:14
вы допустим сделаете контролер проверяйте этих маппинга то это конечно контролер здесь работает и скажет что это утил здесь нет
1:07:22
никакого утилса наверху То есть это у нас основные классы А это тестовая инфраструктура куда Матрица вот никуда
1:07:29
не матрицы это выглядит достаточно коряво мне так не очень нравится Но все равно это лучше чем дублирование
1:07:35
есть правильный подход это сделать
1:07:42
так называемые тест extension во многих
1:07:48
этих фреймворках для тестирования существуют механизмы extensional Вот например в этом случае мы можем весь
1:07:54
этот же Юнит то мы можем сделать использовать такой класс параметр resolver с помощью которого мы его
1:08:00
имплементируем объясняем как его использовать и в итоге наш тест будет выглядеть вот так вот наш тест он стал
1:08:06
меньше и он стал компактнее у него появился вот такой параметр на вход этот
1:08:12
параметр мы говорим используя вот такую аннотацию мы говорим же юниту что когда ты увидишь этот параметр то будь добр
1:08:19
этот P Запомни вот как здесь тебе рассказали получается очень компактно и эффектно
1:08:25
потому что тест становится маленьким вся подготовка вынесена в правильное место как это понимает Сам
1:08:32
вы делаете таким образом красиво Старайтесь использовать этот подход если
1:08:37
можете знаете вот через этот экстент вниз Вы можете получить возможность
1:08:42
инжектить подготовку инжектить целые модули объекты внутрь теста уже внутри
1:08:49
теста происходит тестирование Вы ему говорите мне на вход подготовленный модуль с которым я как-то
1:08:56
поиграюсь и как-то его протестирую вот ну и Bestway тут Я рекомендую как
1:09:02
мне кажется еще более качественный способ это сделать так называемый фейк-объекты объекты которые будут
1:09:08
лежать уже не в тестовом не в тестовом разделе не в разделе репозитория где тесты они будут лежать в продакшн в Live
1:09:15
в разделе там где лежат весь ваш кот лежит это будут такие объекты которые они фейковые но они умеют создавать они
1:09:24
являются объектами которые более
1:09:31
умеют из тех объектов которые там уже были строить какие-то более сложные структуры которые можно использовать и
1:09:37
для тестов И не только для тестов вы подготовите такие фейк объекты я про это
1:09:43
писал когда-то на блоге очень давно много лет назад можете почитать эту идею фейк объектов это объекты которые
1:09:50
используются не нужны напрямую в продакшн-коде но они потенциально могут использоваться в тестах или где-то еще
1:09:57
Если вы это Превратите такие ваши вспо на эти блоки для тестирования Превратите
1:10:02
в эти фейк-объекты то вы только выиграете ваш код будет в итоге выглядит вот так нет никаких сюда инжекшенов вы
1:10:07
ни от кого не зависите вы просто берете берете тот класс который есть в продакшн
1:10:13
коде ему говорить я сделай ко мне вот это а потом его тестировать и тогда ваш
1:10:18
репозитории будет выглядеть так красиво здесь у вас остается все чисто тест мы не нарушаем правила здесь у нас те два
1:10:25
блока которые были продакшн-код и добавился третий который умеет создавать там что-то что-то красивое более сложное
1:10:34
чем умели вот эти двое друзей Теперь мы имеем абсолютно красивую
1:10:41
такую чистенькую структуру тест на тест как мы вначале хотели
1:10:48
Так ну интеграционные тесты небольшая рекомендация для Java больше людей Если вы делаете интеграционные тесты то
1:10:54
Называйте их it-кейс и укладываете их в как-то вот так такую структуру Я бы
1:11:01
рекомендовал это Не суть важно сейчас для нашего обсуждения Ну тем не менее знаете что it
1:11:08
тесты интеграционные тесты лучше выделять каким-то отдельным именованием отдельными названиями чтобы они вам
1:11:15
отдельно светились то есть структура Я за что сейчас выступаю больше всего структура вашего кода вот чтобы она
1:11:23
выглядела Вот так это очень важно Очень важно чтобы маппинг был один к одному очень важно
1:11:29
чтобы классы которые вы здесь нарисовали чтобы они ровно также тесные были отображены я уверен что если вы сейчас
1:11:36
посмотрите свои проекты вы увидите что у вас не так не всегда так Старайтесь делать всегда так жестко так максимально
1:11:44
не рекомендация еще раз это либо правила Либо вы ему следуете либо у вас
1:11:51
там бардак завершая еще раз подведу итог мысли основной что тесты это важный
Заключение
1:11:59
артефакт и вы думаете о том будучи архитекторами буду вы думаете о том как ужесточить контроль над вашими
1:12:06
артефактами я это все время повторяю Вы должны ужесточать контроль не мягко подходить к этому А искать пути Как вы
1:12:13
будете бить по рукам самого себя самих себя и ваших коллег программистов за что они
1:12:20
вас будут тихо ненавидеть Но это неизбежно приготовьтесь к этому если вы
1:12:26
будете добрый у вас будет много друзей и мало результатов Если вы будете
1:12:31
подходить к качеству жестко Если вы будете требовательным к себе и качеству то у вас будет мало друзей намного
1:12:37
результатов Это я больше Шучу конечно но тем не менее какая-то доля правды В этом есть

Поделиться: