0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<h2>Введение</h2>
1
<h2>Введение</h2>
2
<p>Данный урок открывает череду обучающих материалов на тему "Тестирование в Python". В данном мини-курсе будет рассказано об основных инструментах применяющиеся для тестирования.</p>
2
<p>Данный урок открывает череду обучающих материалов на тему "Тестирование в Python". В данном мини-курсе будет рассказано об основных инструментах применяющиеся для тестирования.</p>
3
<p>Этот урок имеет вводный характер и знакомит с общей информацией о тестировании и простой конструкцией, которая позволяет значительно улучшить Python-код.</p>
3
<p>Этот урок имеет вводный характер и знакомит с общей информацией о тестировании и простой конструкцией, которая позволяет значительно улучшить Python-код.</p>
4
<h2>Определение</h2>
4
<h2>Определение</h2>
5
<p><strong>Тестирование программного обеспечения (Software Testing)</strong>- проверка соответствия между реальным и ожидаемым поведением программы, осуществляемая при конечном наборе тестов, выбранном определенным образом. [IEEE Guide to Software Engineering Body of Knowledge, SWEBOK, 2004].</p>
5
<p><strong>Тестирование программного обеспечения (Software Testing)</strong>- проверка соответствия между реальным и ожидаемым поведением программы, осуществляемая при конечном наборе тестов, выбранном определенным образом. [IEEE Guide to Software Engineering Body of Knowledge, SWEBOK, 2004].</p>
6
<p>В более широком смысле,<strong>тестирование</strong>- это одна из техник контроля качества, включающая в себя действия по планированию работ (Test Management), проектированию тестов (Test Design), выполнению тестирования (Test Execution) и анализу полученных результатов (Test Analysis).</p>
6
<p>В более широком смысле,<strong>тестирование</strong>- это одна из техник контроля качества, включающая в себя действия по планированию работ (Test Management), проектированию тестов (Test Design), выполнению тестирования (Test Execution) и анализу полученных результатов (Test Analysis).</p>
7
<p>Для разработчика же интересней следующее определение:</p>
7
<p>Для разработчика же интересней следующее определение:</p>
8
<p><strong>Тестирование</strong>- это проверка соответствия программы требованиям, осуществляемая путём наблюдения за её работой в специальных, искусственно созданных ситуациях, выбранных определённым образом.</p>
8
<p><strong>Тестирование</strong>- это проверка соответствия программы требованиям, осуществляемая путём наблюдения за её работой в специальных, искусственно созданных ситуациях, выбранных определённым образом.</p>
9
<p>Хочется обратить внимание на слова “искусственно созданных ситуациях, выбранных определённым образом”. Это означает, что не имеет смысла тестировать вообще все ситуации, стоит выбирать критически важные места и сценарии.</p>
9
<p>Хочется обратить внимание на слова “искусственно созданных ситуациях, выбранных определённым образом”. Это означает, что не имеет смысла тестировать вообще все ситуации, стоит выбирать критически важные места и сценарии.</p>
10
<h2>Уровни тестирования</h2>
10
<h2>Уровни тестирования</h2>
11
<p>Тестирование для разработчика состоит из написания тестов. Тест - это такой же программный код, который пишется аналогично коду для реализации бизнес-логики. Тесты проверяют сценарии работы программы (test-case).</p>
11
<p>Тестирование для разработчика состоит из написания тестов. Тест - это такой же программный код, который пишется аналогично коду для реализации бизнес-логики. Тесты проверяют сценарии работы программы (test-case).</p>
12
<p>Тест-кейсы встречаются самые различные, один от другого может резко отличаться. По желанию можно тестировать ВСЕ возможные и невозможные ситуации. Однако стоит соблюдать адекватность и покрывать код тестами ровно настолько, насколько требуется для уверенного понимания, что бизнес-логика работает как задумано.</p>
12
<p>Тест-кейсы встречаются самые различные, один от другого может резко отличаться. По желанию можно тестировать ВСЕ возможные и невозможные ситуации. Однако стоит соблюдать адекватность и покрывать код тестами ровно настолько, насколько требуется для уверенного понимания, что бизнес-логика работает как задумано.</p>
13
<blockquote><p>Например, функция, которая возвращает числовое значение от 0 до 100. В тестах стоит проверить не только правильность значений из этого диапазона, но и то, что других значений не возникает.</p>
13
<blockquote><p>Например, функция, которая возвращает числовое значение от 0 до 100. В тестах стоит проверить не только правильность значений из этого диапазона, но и то, что других значений не возникает.</p>
14
</blockquote><p>Негласное правило - если на участке кода проявилась ошибка, то стоит написать тест на этот случай.</p>
14
</blockquote><p>Негласное правило - если на участке кода проявилась ошибка, то стоит написать тест на этот случай.</p>
15
<p>Тестирование смело делится на несколько уровней глубины. Наиболее показательная классификация по уровням тестирования в данном случае такая:</p>
15
<p>Тестирование смело делится на несколько уровней глубины. Наиболее показательная классификация по уровням тестирования в данном случае такая:</p>
16
<ul><li>Системное тестирование - тестирование полностью интегрированного программного приложения</li>
16
<ul><li>Системное тестирование - тестирование полностью интегрированного программного приложения</li>
17
<li>Интеграционное тестирование - тестирование интегрированных групп программных модулей</li>
17
<li>Интеграционное тестирование - тестирование интегрированных групп программных модулей</li>
18
<li>Модульное тестирование или юнит-тестирование - тестирование отдельных модулей исходного кода приложения</li>
18
<li>Модульное тестирование или юнит-тестирование - тестирование отдельных модулей исходного кода приложения</li>
19
</ul><p>Когда говорят "тестирование", не выделяя конкретный тип, то говорят скорее всего о модульном тестировании.</p>
19
</ul><p>Когда говорят "тестирование", не выделяя конкретный тип, то говорят скорее всего о модульном тестировании.</p>
20
<p>Пойдем с низу вверх (от 3 к 1)</p>
20
<p>Пойдем с низу вверх (от 3 к 1)</p>
21
<h3>Модульное тестирование</h3>
21
<h3>Модульное тестирование</h3>
22
<p>Модульное тестирование, или юнит-тестирование (англ. unit testing) - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.</p>
22
<p>Модульное тестирование, или юнит-тестирование (англ. unit testing) - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.</p>
23
<p>Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже протестированных местах программы и облегчает обнаружение и устранение таких ошибок.</p>
23
<p>Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже протестированных местах программы и облегчает обнаружение и устранение таких ошибок.</p>
24
<h4>Инструменты</h4>
24
<h4>Инструменты</h4>
25
<p>В Python для модульного тестирования применяют</p>
25
<p>В Python для модульного тестирования применяют</p>
26
<ul><li>PyUnit</li>
26
<ul><li>PyUnit</li>
27
<li>PyTest</li>
27
<li>PyTest</li>
28
<li>Nose</li>
28
<li>Nose</li>
29
</ul><p>Об этих инструментах будет описано в следующих статьях.</p>
29
</ul><p>Об этих инструментах будет описано в следующих статьях.</p>
30
<h3>Интеграционное тестирование</h3>
30
<h3>Интеграционное тестирование</h3>
31
<p>Интеграцио́нное тестирование или функциональное тестирование предназначено для проверки связи между компонентами, а также взаимодействия с различными частями системы (операционной системой, оборудованием либо связи между различными системами).</p>
31
<p>Интеграцио́нное тестирование или функциональное тестирование предназначено для проверки связи между компонентами, а также взаимодействия с различными частями системы (операционной системой, оборудованием либо связи между различными системами).</p>
32
<h4>Подходы к интеграционному тестированию</h4>
32
<h4>Подходы к интеграционному тестированию</h4>
33
<ul><li>Снизу вверх (Bottom Up Integration)<ul><li>Все низкоуровневые модули, процедуры или функции собираются воедино и затем тестируются. После чего собирается следующий уровень модулей для проведения интеграционного тестирования. Данный подход считается полезным, если все или практически все модули разрабатываемого уровня готовы.</li>
33
<ul><li>Снизу вверх (Bottom Up Integration)<ul><li>Все низкоуровневые модули, процедуры или функции собираются воедино и затем тестируются. После чего собирается следующий уровень модулей для проведения интеграционного тестирования. Данный подход считается полезным, если все или практически все модули разрабатываемого уровня готовы.</li>
34
</ul></li>
34
</ul></li>
35
<li>Сверху вниз (Top Down Integration)<ul><li>Вначале тестируются все высокоуровневые модули, и постепенно, один за другим добавляются низкоуровневые. Все модули более низкого уровня симулируются заглушками с аналогичной функциональностью, затем по мере готовности они заменяются реальными активными компонентами.</li>
35
<li>Сверху вниз (Top Down Integration)<ul><li>Вначале тестируются все высокоуровневые модули, и постепенно, один за другим добавляются низкоуровневые. Все модули более низкого уровня симулируются заглушками с аналогичной функциональностью, затем по мере готовности они заменяются реальными активными компонентами.</li>
36
</ul></li>
36
</ul></li>
37
<li>Большой взрыв ("Big Bang" Integration)<ul><li>Все или практически все разработанные модули собираются вместе в виде законченной системы или ее основной части, и затем проводится интеграционное тестирование. Такой подход очень хорош для сохранения времени. Однако, если тест кейсы и их результаты записаны не верно, то сам процесс интеграции сильно осложнится, что станет преградой для команды тестирования при достижении основной цели интеграционного тестирования</li>
37
<li>Большой взрыв ("Big Bang" Integration)<ul><li>Все или практически все разработанные модули собираются вместе в виде законченной системы или ее основной части, и затем проводится интеграционное тестирование. Такой подход очень хорош для сохранения времени. Однако, если тест кейсы и их результаты записаны не верно, то сам процесс интеграции сильно осложнится, что станет преградой для команды тестирования при достижении основной цели интеграционного тестирования</li>
38
</ul></li>
38
</ul></li>
39
</ul><h4>Инструменты</h4>
39
</ul><h4>Инструменты</h4>
40
<p>Для автоматизации интеграционного тестирования применяются системы непрерывной интеграции (Continuous Integration System, CIS). Принцип действия таких систем состоит в следующем:</p>
40
<p>Для автоматизации интеграционного тестирования применяются системы непрерывной интеграции (Continuous Integration System, CIS). Принцип действия таких систем состоит в следующем:</p>
41
<ol><li>CIS производит мониторинг системы контроля версий;</li>
41
<ol><li>CIS производит мониторинг системы контроля версий;</li>
42
<li>При изменении исходных кодов в репозитории производится обновление локального хранилища;</li>
42
<li>При изменении исходных кодов в репозитории производится обновление локального хранилища;</li>
43
<li>Выполняются необходимые проверки и модульные тесты;</li>
43
<li>Выполняются необходимые проверки и модульные тесты;</li>
44
<li>Исходные коды компилируются в готовые выполняемые модули;</li>
44
<li>Исходные коды компилируются в готовые выполняемые модули;</li>
45
<li>Выполняются тесты интеграционного уровня;</li>
45
<li>Выполняются тесты интеграционного уровня;</li>
46
<li>Генерируется отчет о тестировании.</li>
46
<li>Генерируется отчет о тестировании.</li>
47
</ol><p>Примеры инструментов:</p>
47
</ol><p>Примеры инструментов:</p>
48
<ul><li>Bamboo</li>
48
<ul><li>Bamboo</li>
49
<li>Hudson и Jenkins</li>
49
<li>Hudson и Jenkins</li>
50
<li>CruiseControl</li>
50
<li>CruiseControl</li>
51
<li>TeamCity</li>
51
<li>TeamCity</li>
52
<li>BuildBot</li>
52
<li>BuildBot</li>
53
<li>Travis CI</li>
53
<li>Travis CI</li>
54
<li>Team Foundation Server</li>
54
<li>Team Foundation Server</li>
55
</ul><h3>Системное тестирование</h3>
55
</ul><h3>Системное тестирование</h3>
56
<p>Основной задачей системного тестирования является проверка как функциональных, так и не функциональных требований в системе в целом. При этом выявляются дефекты:</p>
56
<p>Основной задачей системного тестирования является проверка как функциональных, так и не функциональных требований в системе в целом. При этом выявляются дефекты:</p>
57
<ul><li>Неверное использование ресурсов системы</li>
57
<ul><li>Неверное использование ресурсов системы</li>
58
<li>Непредусмотренные комбинации данных пользовательского уровня</li>
58
<li>Непредусмотренные комбинации данных пользовательского уровня</li>
59
<li>Несовместимость с окружением</li>
59
<li>Несовместимость с окружением</li>
60
<li>Непредусмотренные сценарии использования</li>
60
<li>Непредусмотренные сценарии использования</li>
61
<li>Отсутствующая или неверная функциональность</li>
61
<li>Отсутствующая или неверная функциональность</li>
62
<li>Неудобство использования</li>
62
<li>Неудобство использования</li>
63
<li>И другие</li>
63
<li>И другие</li>
64
</ul><p>Для минимизации рисков, связанных с особенностями поведения системы в той или иной среде, во время тестирования рекомендуется использовать окружение максимально приближенное к тому, на которое будет установлен продукт после выдачи.</p>
64
</ul><p>Для минимизации рисков, связанных с особенностями поведения системы в той или иной среде, во время тестирования рекомендуется использовать окружение максимально приближенное к тому, на которое будет установлен продукт после выдачи.</p>
65
<p>Стоит выделить два подхода к системному тестированию:</p>
65
<p>Стоит выделить два подхода к системному тестированию:</p>
66
<ul><li>на базе требований (requirements based). Для каждого требования пишутся тестовые случаи (test cases), проверяющие выполнение данного требования.</li>
66
<ul><li>на базе требований (requirements based). Для каждого требования пишутся тестовые случаи (test cases), проверяющие выполнение данного требования.</li>
67
<li>на базе случаев использования (use case based). На основе представления о способах использования продукта создаются случаи использования системы (Use Cases).</li>
67
<li>на базе случаев использования (use case based). На основе представления о способах использования продукта создаются случаи использования системы (Use Cases).</li>
68
</ul><p>По конкретному случаю использования можно определить один или более сценариев. На проверку каждого сценария пишутся тест кейсы (test cases), которые реализуются в виде тестов.</p>
68
</ul><p>По конкретному случаю использования можно определить один или более сценариев. На проверку каждого сценария пишутся тест кейсы (test cases), которые реализуются в виде тестов.</p>
69
<h4>Инструменты</h4>
69
<h4>Инструменты</h4>
70
<p>Для описания сценариев можно использовать BDD (behavior-driven development)</p>
70
<p>Для описания сценариев можно использовать BDD (behavior-driven development)</p>
71
<ul><li>pytest-bdd</li>
71
<ul><li>pytest-bdd</li>
72
<li>behave</li>
72
<li>behave</li>
73
<li>freshen</li>
73
<li>freshen</li>
74
</ul><h2>Простой инструмент проверки данных - assert</h2>
74
</ul><h2>Простой инструмент проверки данных - assert</h2>
75
<p>Так как этот урок почти полностью состоит из теории, то разбавлю конструкцией языка, которая помогает писать код и тесты более высокого качества.</p>
75
<p>Так как этот урок почти полностью состоит из теории, то разбавлю конструкцией языка, которая помогает писать код и тесты более высокого качества.</p>
76
<p>Python - язык с динамической типизацией. Это значит, что при написании Python-кода мы явно не указываем тип данных, а во время исполнения не гарантируется явный тип переменной.</p>
76
<p>Python - язык с динамической типизацией. Это значит, что при написании Python-кода мы явно не указываем тип данных, а во время исполнения не гарантируется явный тип переменной.</p>
77
<p>В следствии этого возникают сложности. Например, в функции ожидаем целое число, а нам передали list. Это может привести к самым неожиданным ошибками. Чтобы попытаться обойти эту проблему стоит воспользоваться assert.</p>
77
<p>В следствии этого возникают сложности. Например, в функции ожидаем целое число, а нам передали list. Это может привести к самым неожиданным ошибками. Чтобы попытаться обойти эту проблему стоит воспользоваться assert.</p>
78
<blockquote><p>Assert - это специальная конструкция, позволяющая проверять предположения о значениях произвольных данных в произвольном месте программы.</p>
78
<blockquote><p>Assert - это специальная конструкция, позволяющая проверять предположения о значениях произвольных данных в произвольном месте программы.</p>
79
</blockquote><p>Assert'ы позволяют отлавливать ошибки в программах на этапе компиляции либо во время исполнения.</p>
79
</blockquote><p>Assert'ы позволяют отлавливать ошибки в программах на этапе компиляции либо во время исполнения.</p>
80
<p>Использование конструкции весьма простое:</p>
80
<p>Использование конструкции весьма простое:</p>
81
<p>Assert вызывает ошибку, если аргумент равен False. Например так:</p>
81
<p>Assert вызывает ошибку, если аргумент равен False. Например так:</p>
82
<p>Traceback показывает строчку, с которой полетело исключение AssertionError, что порой открывает много нового в понимании, как же в реальности работает написанный код.</p>
82
<p>Traceback показывает строчку, с которой полетело исключение AssertionError, что порой открывает много нового в понимании, как же в реальности работает написанный код.</p>
83
<h2>Выводы</h2>
83
<h2>Выводы</h2>
84
<p>В уроке были кратко описаны виды тестирования: модульное или юнит-тестирование, интеграционное, системное. Для каждого озвучен список инструментов для создания тестов.</p>
84
<p>В уроке были кратко описаны виды тестирования: модульное или юнит-тестирование, интеграционное, системное. Для каждого озвучен список инструментов для создания тестов.</p>
85
<p>В качестве практики описана конструкция assert, позволяющая проверять предположения о значениях произвольных данных в произвольном месте программы.</p>
85
<p>В качестве практики описана конструкция assert, позволяющая проверять предположения о значениях произвольных данных в произвольном месте программы.</p>