---
# System prepended metadata

title: ТПО. Зачет

---

# ТПО. Зачет

### 1. Понятие тестирования ПО. Основные определения.

Тестирование -- это спобоб проверки ПО на соответствие ожиданиям. То есть это способ проверить, что программа работает так как мы от нее ожидаем.

В более широком смысле, тестирование -- это одна из техник контроля качества ПО в терминах найденных дефектов, включающая в себя работы по планированию, проектированию, выполнению и анализу тестов.

Тестирование ставит целью нахождение ошибкок. Но ошибки бывают разными: 

- Mistake -- ошибка, просчет (человека)
- Fault -- дефект, изъян (ПО в результате мистейка)
- Failure -- неисправность, отказ, сбой (проявление дефекта)
- Error -- невозможность выполнить задачу в результате отказа
- Bug -- неформальный термин, может означать любой тип ошибки

Валидация -- проверка ПО на соответствие ожиданиям от системы, удовлетворяет ли ПО требованиям пользователя (have we done the right thing).

Верификация -- Это процесс внутреннего управления качеством. Выполняет ли ПО требования спецификации. (have we done the thing right)

Тестовый случай -- stateless test case. То есть проверка одного набора входных данных 
input - compute - output
Тестовый сценарий -- stateful набор тестовых случаев, собирающихся в какую-то логичную (или поппулярную или ожидаемую) последовательность действий

### 2. Цели и принципы тестирования (ISTQB).

Цели тестирования:
- Обнаружение дефектов
- Повышение уверенности в качестве
- Предоставление информации для принятия решений
- Предотвращение дефектов

На самом деле основной целью тестирования, к которой стремятся в компаниях является повышение увровня пользовательского доверия в том, что система работает корректно во всех необходимых обстоятельствах

Принципы тестирования (ISTQB):
- Тестирование демонстрирует наличие дефектов
    - Чем больше ошибок находим, тем выше поднимаем пользовательское доверие
- Исчерпывающее тестирование недостижимо
- Ранее тестирование
    - Чем раньше мы найдем баг, тем дешевле нам это обойдется и тем менее печальными будут последствия
- Скопление дефектов
    - Обычно ошибки группируются в конкретных модулях, и эти модули надо более внимательно тестровать
- Парадокс пестицида
    - Чем больше мы будем концентрироваться на том чтоб удалить дефекты из одного модуля, тем меньше применяемые средства будут работать
- Тестирование зависит от контекста
- Заблужение об отсутствии ошибок

### 3. Основная цель тестирования. Уровень доверия, корректное поведение, реальное окружение.

Цели тестирования:
- Обнаружение дефектов
- Повышение уверенности в качестве
- Предоставление информации для принятия решений
- Предотвращение дефектов

На самом деле **основной целью тестирования**, к которой стремятся в компаниях является повышение увровня пользовательского доверия в том, что система работает корректно во всех необходимых обстоятельствах

Но просто зеленые тесты не всегда могут повышать уровень доверия пользователей, поэтому есть некоторые другие метрики:
- Уровень остаточного обнаружения дефектов
- Требования к надежности

Дальше встает вопрос -- а как это самое корректное поведение установить, чтобы по нему написать тесты?
- Из требований
- Спецификации, описаний
- Зависит от уровня тестирования

При этом тут важно учитывать окружение, в котором система будет использоваться. Например, если системой будут пользоваться 10к людей, то нам вряд ли нужны тесты на 100к клиентов

### 4. Тестирование и качество. Уровни восприятия тестирования в компании

- Уровень 0 -- тестирование == отладка
    - Не повторяемый, работает только на самых ранних этапах
    - Не отличает некорректное поведение и ошибки в программе
    - Не учитывает требования к надежности и безопасности

- Уровень 1 -- тестирование -- способ доказать что в программе нет багов
    - Чаще всего это сделать невозможно, либо очень дорого
    - Нет формальных правил
- Уровень 2 -- тестирование -- способ найти баги в программе
    - Приводит к конфликту отделов
- Уровень 3 -- тестирование -- это способ проверки программы на соответствие ожиданиям
    - Тестировщики и разработчики совместно снижают риски
    - Последствия рисков могут быть как незначительными, так и катастрофическими
- Уровень 4 -- тестирование -- это один из методов проверки качества ПО в терминах найденных дефектов
    - Функциональное
    - Нефункциональное - надежность, практичность, сопровождаемость, переносимость

Есть таже другие способы оценки качества:
- Разработка стандартов (известная методика скорее всего без багов)
- Обучение (умные люди знают как делать без ошибок)
- Анализ дефектов

### 5. Участники тестирования, их роль, квалификация и обязанности.

При тестировании ПО, существует несколько различных ролей, которые могут на себя брать разные люди, в зависимости от их компетенции и навыков

- Проектирование тестов
    - На основании формальных критериев
    - На основании знания предметной области, опыта, экспертизы
- Автоматизация
    - Знание тестов, скриптов. Обычно сильных навыков программирования не требуется, однако иногда они все-таки нужны (например, написать хороший селениум тест может быть не так просто -- нужно работать с разными АПИ)
- Исполнение
    - Не требует особой квалификации
- Анализ
    - Знания предметной области

### 6. Мониторинг прогресса и контроль тестирования (ISTQB)

**Целью мониторинга тестирования** является обзор процесса тестирования и представление результата заинтересованным лицам. Информация отслеживается вручную и может быть использована для изменения метрик (например покрытие). Метрики могут быть использованы для прогресса тестирования по сравнению с планами

Метриками могут являться тестовое покрытие, количество пройденных тестов, количество
найденных дефектов и т.д.

**Контроль тестирования** описывает любые направляющие или корректирующие действия, принятые как результат по полученной собранной информации и значениям метрик в результате мониторинга.

Контроль тестирования может затрагивать любые
действия по тестированию, а также воздействовать на другие действия и задачи
жизненного цикла ПО. Такими действиями могут быть правильная приоритизация усилий
тестирования, привлечение большего количества ресурсов на тестирование, уменьшение
объема предстоящего релиза и т.д.

То есть в мониторинге мониторим, а в контроле принимаем решения основываясь на том что мы намониторили

### 7. Модульное тестирование. Понятие модуля. Драйверы и заглушки

Модульное тестирование -- тестирование отдельных модулей (компонентов) системы

Модуль -- это какой-то компонент нашей системы. Это может быть функция, класс, либо набор классов, которые вместе ответсвенны за конкретную часть логики работы системы. Модули обычно описаны в дизайне

Чтобы протестировать модуль отдельно от остальной системы, его сначала надо изолировать. Но ведь для его работы должно осуществляться взаимодействие с другими модулями!

Чтобы от этого избавиться, зависящие и зависимые модули надо заменить на драйверы и заглушки

![](https://hackmd.io/_uploads/S1x444Gw2.png)

- Заглушка эмулирует поведение подчиненной программы (подпрограмма)
Интерфейс заглушки совпадает с реальным модулем, но реализация нет:
Предопределенные овтеты для заданных аргументов
Постоянная генерация прерываний
Заглушка должна быть простая. Ее не должно быть необходимо тестировать

- Драйвер эмулирует вызывающий компонент
Обычно более сложный чем заглушка
Подготавливает входные данные
Может запускать серию тестов, настраивать заглушки, формировать лог результатов

### 8. V-образная модель. Статическое и динамическое тестирование.

Это методология, при которой каждому этапу разработки системы соответствует свой тип тестирования.

![](https://hackmd.io/_uploads/H19QPGMw3.png)

Можно заметить, что пока кода нет, то есть перед этапом разработки, применяются методы статического тестирования, а после - динамическое

- Статическое тестирование
    - Применяется без выполнения кода
    - Ручное, автоматизированное
    - Неформальное, сквозной контроль, инспекция
- Динамическое тестирование
    - Запуск модулей, групп модулей, всей системы

### 9. Валидация и верификация. Тестирование методом "чёрного" и "белого" ящика.

- Валидация -- проверка ПО на соответствие ожиданиям от системы, удовлетворяет ли ПО требованиям пользователя (have we done the right thing).
То есть пирожок (мясной, вегитарианский, сладкий)

- Верификация -- Это процесс внутреннего управления качеством. Выполняет ли ПО требования спецификации. (have we done the thing right).
То есть пирожок (размер, степень прожарки, качество начинки)

- Тестирование методом "чёрного" ящика
Метод тестирования, при котором никак не используются знания о внутреннем устройстве системы. (Спецификации, требования, дизайн). В данном случае мы можем найти какой-то непокрытый кодом сценарий, так как смотрим только снаружи
- Тестирование методом "белого" ящика
В данном методе мы обладаем информацией об устройстве реализации. (Переходы, утверждения, условия, анализ путей)

### 10. Тестовый случай, тестовый сценарий и тестовое покрытие.

Тестовый случай -- stateless test case. То есть проверка одного набора входных данных 
input - compute - output

Входные значения -- данные или управляющее воздействие

Также тестовый случай описывает необходимые предусловия, условия выполнения и постусловия

Ожидаемый результат: Выходные данные и состояния, изменения в них.
Важно, чтобы ожидаемый результат был определен до запуска теста (в идеале и TDD)

Важно, чтобы тестовый случай был повторяемым и автоматизируемым. То есть он учитывает состояния автомата программы и переходы между ними

Тестовый сценарий -- stateful набор тестовых случаев, собирающихся в какую-то логичную (или популярную или ожидаемую) последовательность действий

| Начальное состояние | Input | Действие системы | Output | Конечное состояние |
| :---------: |:-------------:| :-----:| :-----:| :-----:|
| ГОТОВ | Пользователь вставляет карточку  | Успешное чтение карточки | Приглашение "введите pin" | Ожидание pin-кода |
| Ожидание pin-кода | П-ль вводит верный пин-код | Проверка пин-кода | Приглашение к выбору транзакции | Ожидание выбора транзакции |
| Ожидание выбора транзакции | Выбор выдачи 5000 рублей | Проверка баланса, возможности выдачи | Деньги | Выдача денег |
| Выдача денег | П-ль берет деньги и карточку | Завершение выдачи | Благодарность за использование | ГОТОВ |

Также важно составлять еще и на ошибочные тестовые сценарии

| Начальное состояние | Input | Действие системы | Output | Конечное состояние |
| :---------: |:-------------:| :-----:| :-----:| :-----:|
| ГОТОВ | Пользователь вставляет карточку  | Успешное чтение карточки | Приглашение "введите pin" | Ожидание pin-кода |
| Ожидание pin-кода | П-ль вводит неверный пин-код | Проверка пин-кода | Сообщение об ошибке | Ожидание pin-кода |
| Ожидание pin-кода | П-ль вводит неверный пин-код | Проверка пин-кода | Сообщение об ошибке | Ожидание pin-кода |
| Ожидание pin-кода | П-ль вводит неверный пин-код | Проверка пин-кода, блокировка карточки | Сообщение об ошибке и блокировка | ГОТОВ |

При этом также важно помнить, что нужно откуда-то взять опеределение корректного (ожидаемого) поведения

- Требования (системное, приемочное, интеграционное тестирование)
- Архитектура (интеграционное)
- Проектные документы (модульное)

Сами сценарии можно можно взять из документации к проекту

Тестовое покрытие:

Много тестов -> большое покрытие -> выше качество
Но дольше этап тестирования, и можно не успеть выйти на рынок

Меньше тестов -> выше скорость разработки -> быстрее выход на рынок

Поэтому нужно всегда искать нужную середину

- Анализ эквивалентности
- Таблица решений
- Таблица перходов
- Сценарии

### 11. Полное тестовое покрытие. Оценка объема и времени полного покрытия.

На самом деле нам всегда надо думать над тем, на каких данных тестировать нашу программу. Дело в том, что просто взять и проверить ее на вообще всех возможных входных данных, скорее всего невозможно

Допустим, мы хотим сделать полное тестовое покрытие функции, которая просто умножает два инта

`public long mult(int a, int b);`

Получается у нас будет `2^32 * 2^32` тестовых случаев. Оказывается, что на обычном 3Ггц процессоре это будет тестироваться примерно 185 лет

Более того, все эти данные (то есть ожидаемые результаты) еще надо откуда-то взять. То есть нужен человек, который перед этим посчитает это все и запишет в табличку. 

Поэтому надо всегда применять какие-либо техники сокращения тестового покрытия

### 12. Повторяемость тестового сценария. Автоматизированное тестирование. Регрессионное тестирование.


Тестовый случай -- stateless test case. То есть проверка одного набора входных данных 
input - compute - output

Тестовый сценарий -- stateful набор тестовых случаев, собирающихся в какую-то логичную (или популярную или ожидаемую) последовательность действий

Важно, чтобы тестовый сценарий был поторяемым. То есть он должен описывать работу системы целиком, вместе со всеми предусловиями, условиями выполнения и постусловиями. Это позволит непрерывно тестировать нашу систему и, что не менее важно, проверять каждое изменение в одинаковых обстоятельствах

Также тесты важно автоматизировать. Это важно, чтобы во-первых исключить человеческий фактор, во-вторых, запускать тесты чаще и больше, то есть ускорить процесс тестирования, а также делать это автоматически при изменениях в коде. Помимо этого, так можно будет проще проверять ПО в разных окружениях

Регрессионное тестирование - собирательное название для всех видов тестирования ПО, направленных на обнаружение ошибок в старой функциональности. Такие ошибки возникают, когда после внесения изменений в программу перестает работать то, что должно было продолжать работать. Их называют регрессионными ошибками. Регрессионные тесты удобно автоматизировать и запускать после каждого изменения/добавления участка кода, проверяя, что не сломалось ничего из ранее работающего.

То есть регрессионное тестирование направлено на проверку того, что новый код не ломает старые контракты

### 13. Цели и задачи интеграционного тестирования. Алгоритм интеграционного тестирования. Стратегии интеграции.

Интеграционное тестирование -- следующий шаг в тестировании после модульного. На данном этапе мы уже убедились, что каждый модуль по отдельности корректно работает и делает то, что мы от него ожидаем. Теперь пришло время проверить как эти самые модули взаимодействуют между собой

Внешне интеграционные тесты похожи на модульные, однако акцент сделан на другом

То есть интеграционное тестирование проверяет интерфейсы и взаимодействие модулей или систем, а именно
- Вызовы API, сообщения между компонентами
- Взаимодействие с БД и GUI
- Интерфейсы взаимодействия

Может начинать проводиться, когда готовы уже хотя бы 2 связанных компонента

Но обычно интеграцию модулей проводят не в произвольном порядке, а так, чтобы это было наиболее эффективно (наименнее трудозатратно)

- Сверху вниз (Наиболее быстро можно показать что-то работабщее, то есть начать с UI, а потом тестировать что-то более серьезное)
- Снизу вверх (Исп если есть аппаратура которая подключается к системе)
- Функциональная (Собираем сначала один полностью работающий функциональный блок, затем второй и тд)
- Ядро (Сначала ядро, потом наращиваем функционал)
- big bang

Принципы:

- Интегрировать в первую очередь наиболее сложные компоненты
- Порядок интеграции зависит от порядка разрабоки
- Использовать регрессионное тестирование
- Автоматизировать тесты

### 14. Тестирование системы целиком - системное тестирование.

После того как мы провели модульное и интеграционное тестирование и убедились в работоспособночти, наступает этап тестирования системы в целом

Он состоит из нескольких этапов. Методики в них одинаковые, различаются условия проведения тестирования
- Системное тестирование (внутри организации разработчика)
- Альфа и Бета тестирование (выполняется пользователями, но под контролем разработчиков)
- Приемочное тестирование (выполняется пользователями)

На этапе тестирования фокусируемся на проверке функциональности системы именно с точки зрения пользователя

Обычно проводится верификация, а затем валидация. При этом применяется метод черного ящика

Важно, чтобы при системном тестировании контекст был максимально приближен к реальному
- Оборудование
- ОС
- Сетевое окружение
- В аппаратуре -- частота, тайминги и тд

На этом этапе нам необходимы те самые прецеденты использования и тестовые сценарии, которые тестировщики должны зашить в скрипты

Важно начинать тестирование системы в целом от простого. То есть сначала надо проверить общее функционирование системы. Затем уже проверять стабильность, устойчивость к сбоям, совместимость и происзводительность

![](https://hackmd.io/_uploads/S1bpgImD2.png)


### 15. Тестирование возможностей, стабильности, отказоустойчивости, совместимости. Тестирование производительности - CARAT. 

После того как мы провели модульное и интеграционное тестирование и убедились в работоспособности, наступает этап тестирования системы в целом

На этапе тестирования системы в целом фокусируемся на проверке функциональности системы именно с точки зрения пользователя

Важно начинать тестирование системы в целом от простого. То есть сначала надо проверить общее функционирование системы. Затем уже проверять стабильность, устойчивость к сбоям, совместимость и происзводительность

![](https://hackmd.io/_uploads/S1bpgImD2.png)

- **Возможности**
    - Один пользователь, одна транзакция, корректные данные в БД, корректные переходы между состояниями, среднее аппаратное обеспечение
- **Стабильность** (более реалистичная ситуация)
    - Все транзакции и входные данные валидны
    - Несколько пользователей
    - Реальные последовательности транзакций
    - Одновременно несколько транзакций от одного пользователя
    - Запуск системы на длительный период (утечки памяти, переполнения диска)
- **Устойчивость к сбоям**
    - Пользователи вводят неправильные данные
    - Сбои сети, файлов
    - Неправильные переходы между состояниями
    - Выполнение операций в неправильном порядке
    - Аварийные отключения
- **Совмеситмость**
    - Разные версии библиотек, браузеров
    - Разные ОС, версии ОС
    - Локальные и удаленные машинки
- **Производительность**
    - CARAT:
        - Capacity
        - Accuracy
        - Responce Time
        - Availability
        - Throughput

### 16. Альфа и Бета тестирование. Приемочное тестирование.

После того как мы провели модульное и интеграционное тестирование и убедились в работоспособночти, наступает этап тестирования системы в целом

Он состоит из нескольких этапов. Методики в них одинаковые, различаеются условия проведения тестирования
- Системное тестирование (внутри организации разработчика)
- Альфа и Бета тестирование (выполняется пользователями, но под контролем разработчиков)
- Приемочное тестирование (выполняется пользователями)

На этапе тестирования фокусируемся на проверке функциональности системы именно с точки зрения пользователя

Важно, чтобы при системном тестировании контекст был максимально приближен к реальному
- Оборудование
- ОС
- Сетевое окружение
- В аппаратуре -- частота, тайминги и тд

Альфа-тестирование - имитация реальной работы с системой штатными
разработчиками, либо реальная работа с системой потенциальными
пользователями/заказчиком.
- Может проводиться до окончания системного тестирования
- Ранние отзывы пользователей об использовании системы в рабочем окружении

Иногда при Бета-тестировании может распространяться бета-версия ПО на всех пользователей (как это делает Windows), чтобы найти больше багов

Приемочное тестирование -- формальный процесс тестирования, который проверяет соответствие системы требованиям и проводится с целью: определения удовлетворяет ли система приемочным критериям; вынесения решения заказчиком

### 17. Статическое тестирование. Рецензия, технический анализ, сквозной контроль.

Статическое тестирование -- тестирование, которое может начать применяться до написания первого кода (при этом может продолжаться и после)

Сделано оно для того, чтоб покрывать один из принципов тестирования -- находить ошибки в ПО как можно раньше. Дело в том, что как мы помним, чем раньше заложен баг, тем дороже будет его пофиксить

Объекты тестирования:
- Политики, стратегии, планы
- Технические задания, спецификации
- Код
- Планы и подохды к тестированию
- Архитектура
- и тд

Одной из самых простых техник статического тестирования является **рецензия**. То есть мы делаем такой "звонок другу" -- идем к коллеге и спрашиваем что он думает насчет нашего кода

Тут идея просто во взгляде со стороны -- таким образом можно находить не только опечатки, но и разные не очень удачные подходы к проектированию например кода.

Этот метод не очень эффективен, так как он во-первых неформальный, а значит непонятно чего вообще ожидать, а во-вторых коллеги обычно не будут тратить время и хорошо вникать в твои задачи, так как у них есть свои

Второй подход -- **технический анализ**. 

Этот метод больше всего похож на стадию ревью в проектах, когда несколько коллег просматривают код, могут предложить другие подходы и решения, проверяют кодстайл и тд

В этом подходе уже можно использовать как формальные так и неформальные техники, что улучшает качество такого тестирования

Также может применяться **сквозной контроль**

Тут идея в том, что автор собирает встречу и рассказывает про свое решение. То есть он "ведет" аудиторию "через" артефакт

То есть это, напримерр, может быть расссказ про архитектуру нового компонента системы, на котором автор делится с остальными и идет обсуждение

Это позволяет находить 
- Ошибки, аномалии, неэффективности
- Спецификации, которые не могут быть проверены
- Проблемы интерфейсов
- Отколнение от практик, стиля

### 18. Статическое тестирование. Инспекции.

Статическое тестирование -- тестирование, которое может начать применяться до написания первого кода (при этом может продолжаться и после)

Сделано оно для того, чтоб покрывать один из принципов тестирования -- находить ошибки в ПО как можно раньше. Дело в том, что как мы помним, чем раньше заложен баг, тем дороже будет его пофиксить

Объекты тестирования:
- Политики, стратегии, планы
- Технические задания, спецификации
- Код
- Планы и подохды к тестированию
- Архитектура
- и тд

Инспекции -- это способ еще больше формализовать методы статического тестирования, в которых основную роль занимают люди

Целью является обнаружение и идентификация аномалий в ПО

Основной объект инспекции -- ведущий (не автор). Он:
- Назначает инспекторов
- Распространяет подготовленные документы
- Ведет встречу
- Убеждается в том, что нужные решения приняты
- Определяет и контролиуер различные метрики

Каждый инспектор тут занимается какими-то своими делами (не более двух). Идея в том, чтобы люди не распылялись и сосредоточились на свох зонах ответственности. Тогда каждый из них сможет эффективно выполнить свои задачи, а затем при обсуждениях уже принимаются совместные решения

То есть инспекция состоит из таких шагов:
- Вход
- Планирование и обзор
- Повторяется:
    - Подготовка
    - Обсуждение
    - Переработка
    - Выработка рекомендаций
- Выход

И повторяется до тех пор, пока все участники (включая модератора) не удовлетворены

Также во время обсуждений ведущий следит за тем, чтобы не было пустых разговоров, чтобы обсуждения не затягивались, так как это будет менее эффективно
Также он следит, чтобы до начала и после конца были сформированы входные и выходные критерии

Каждый этап сопровождается документами контроля процесса

### 19. Статическое тестирование. Статический анализ кода.

Статическое тестирование -- тестирование, которое может начать применяться до написания первого кода (при этом может продолжаться и после)

Сделано оно для того, чтоб покрывать один из принципов тестирования -- находить ошибки в ПО как можно раньше. Дело в том, что как мы помним, чем раньше заложен баг, тем дороже будет его пофиксить

Объекты тестирования:
- Политики, стратегии, планы
- Технические задания, спецификации
- Код
- Планы и подохды к тестированию
- Архитектура
- и тд

Статические анализаторы кода -- это программные средства, которые проверяют корректность программ без выполнения

Например, существуют различные линтеры (Lint для Си), которые могут проверять
- Непредсказуемое поведение, неопределенное поведение
- Нарушение контрактов библиотек
- Переполнение буффера
- Разрушение кроссплатформенности
- Дублирование кода
- Код, который не соответствует кодстайлу (clang-tidy, clang-format)

Также в некоторых современных языках в анализаторы встроены дополнительные статические проверки (например, проверки владения и лайфтаймом в расте)

Все это позволяет быстро находить и исправлять какие-то ошибки, которые разработчик допустил по неосторожности

### 20. Выбор тестового покрытия с помощью анализа эквивалентности. Анализ граничных значений.

> Полное тестовое покрытие сделать нельзя

Один из способов решения данной проблемы -- анализ эквивалентности. Идея: давайте разобьем возможные входные значение для нашей программы на блоки, внутри которых программа, по нашему мнению, ведет себя одинаково. Тогда мы сможем выбрать всего несколько тестов внутри каждого блока, а также рассмотреть граничные случаи

Например, если мы тестируем выдачу денег в банкомате

- Купюры по 100
- За раз максимум 2000
- За день 10000
- Комиссия 1% но не меньше 5

В таком примере можно сделать такой анализ:

![](https://hackmd.io/_uploads/HkWHvHmw3.png)

Тут надо обратить внимание на класс эквивалентности, который означает невалидный результат

Другой пример разбиения на классы эквивалентности:

![](https://hackmd.io/_uploads/rJqcwrQvn.png)

### 21. Выбор тестового покрытия с помощью таблицы решений.

Таблица решений это один из подходов к снижению размера количества тестов.

Идея в том, что мы описываем работу программы как набор условий, приводящих к конкретному ответу и описываем это в виде таблицы

В ней первая часть -- это возможные входные условия, а вторая часть -- ожидаемые выходные значения

![](https://hackmd.io/_uploads/HkE-dSmPh.png)

### 22. Выбор тестового покрытия с помощью диаграммы состояний и таблицы переходов

Диаграмма состояний и таблицы переходов -- это один из подходов к снижению размера количества тестов.

В данном методе идея в том, что мы представляем нашу программу (или тестируемый кусок программы) как конечный автомат, и в таком виде можно оценивать возможные состояния программы и переходы между ними

![](https://hackmd.io/_uploads/H1d1YBXD2.png)

Если так посмотреть на систему, то можно легко определить похожие состояния. Для этого из автомата составляется таблица, которая описывает все возможные состояния и переходы. А затем каждая строка анализируется отдельно и выбираются только нужные

![](https://hackmd.io/_uploads/ByynFHXw3.png)


### 23. Выбор тестового покрытия с помощью функционального тестирования.

Пользовательские сценарии -- это один из подходов к снижению размера количества тестов.

В этом методе идея наиболее естественная -- давайте тестировать реальные возможнные сценарии использования нашей программы

![](https://hackmd.io/_uploads/SkdLqSQDn.png)

Таким образом мы составляем несколько сценариев испоьлзования системы, и исходя из них формирует тесты. Это позволяет выкинуть из тестирования сценарии, которые все равно никогда бы не воспроизводилиьсь в реальном использовании

### 24. Библиотека JUnit. Класс junit.framework.Assert. Основные аннотации для исполнения тестов.

JUnit -- фреймворк для модульного тестирования java-программ.

Позволяет писать классы тестов и настраивать состояния вызова. Работет на основе аннотаций

С помощью аннотаций `@Test`, `ParametrizedTest` можно указать, что метод является тестом

Для кода вне тестов (до, после) также есть аннотации -- `@Before`, `@BeforeAll`, `@After`, `@AfterAll`, `@Before/AfterClass`

Чтобы проверять желаемые условия есть специальные методы (assertion)

Также есть более-менее удобный UI, лог тестов

![](https://hackmd.io/_uploads/Hy0_szXD2.png)

*Важно обратить внимание на то, что ассерты импортятся через static

### 25. Библиотека JUnit. Дополнительные возможности, запуск с параметрами.

JUnit -- фреймворк для модульного тестирования java-программ.

Позволяет писать классы тестов и настраивать состояния вызова. Работет на основе аннотаций

С помощью аннотаций `@Test`, `@ParametrizedTest` можно указать, что метод является тестом

Для кода вне тестов (до, после) также есть аннотации -- `@Before`, `@BeforeAll`, `@After`, `@AfterAll`, `@Before/AfterClass`

Чтобы проверять желаемые условия есть специальные методы (assertion)

**Дополнительные возможности:**

- Запуск тестов с таймаутом `@Test(timeout=10)`
- Запуск тестов, которые ожидают исключения `@Test(expected=Exception.class)`
- Параметризированные тесты
```java
@ParametrizedTest
@ValueSource(ints={1, 3, 5})
void smthTest(int number) {
    assertTrue(smth.isOdd(number));
}
```
- Игнорирование `@Ignore("help me pls")`


### 26. Анализ эквивалентности с использованием JUnit.

JUnit -- фреймворк для модульного тестирования java-программ.

Позволяет писать классы тестов и настраивать состояния вызова. Работет на основе аннотаций

С помощью аннотаций `@Test`, `@ParametrizedTest` можно указать, что метод является тестом

Для кода вне тестов (до, после) также есть аннотации -- `@Before`, `@BeforeAll`, `@After`, `@AfterAll`, `@Before/AfterClass`

Чтобы проверять желаемые условия есть специальные методы (assertion)

Анализ эквивалентности -- это способ уменьшить тестовое покрытие, при этом не потеряв релевантности. Оно реализуется через выделение эквивалентных участков работы программы

Сам по себе JUnit не предоставляет средств для проведения анализа эквиваентности, но позволяет удобно реализовать уже проведенный анализ в коде

Так, например, можно воспользоваться механизмом параметризованных тестов

```java
@ParametrizedTest
@ValueSource(ints={1, 3, 5})
void smthTest(int number) {
    assertTrue(smth.isOdd(number));
}
```

Также мжоно запускать тесты с разными типами параметров

### 27. Тестирование алгоритмов с использованием JUnit.

JUnit -- фреймворк для модульного тестирования java-программ.

Позволяет писать классы тестов и настраивать состояния вызова. Работет на основе аннотаций

С помощью аннотаций `@Test`, `@ParametrizedTest` можно указать, что метод является тестом

Для кода вне тестов (до, после) также есть аннотации -- `@Before`, `@BeforeAll`, `@After`, `@AfterAll`, `@Before/AfterClass`

Чтобы проверять желаемые условия есть специальные методы (assertion)

Для тестирования алгоритмов удобно использовать параметризированные тесты

```java
@ParametrizedTest
@ValueSource(ints={1, 3, 5})
void smthTest(int number) {
    assertTrue(smth.isOdd(number));
}
```

Также, чтобы протестировать алгоритм, реализуемый одним из модулей нашей системы и не думать про остальные, можно изолировать его с помощью заглушек из Mockito

```java
@ParametrizedTest
@ValueSource(ints = 0)
public void test (int result){
    Student student = Mockito.mock(Student.class)
    Mockito.when(student.getDolgs()).thenReturn(result);
    assertEquals(“Обучается”, ISU.getStatus(student))
}
```

### 28. Модульное тестирование доменной модели с использованием JUnit.

JUnit -- фреймворк для модульного тестирования java-программ.

Позволяет писать классы тестов и настраивать состояния вызова. Работет на основе аннотаций

С помощью аннотаций `@Test`, `@ParametrizedTest` можно указать, что метод является тестом

Для кода вне тестов (до, после) также есть аннотации -- `@Before`, `@BeforeAll`, `@After`, `@AfterAll`, `@Before/AfterClass`

Чтобы проверять желаемые условия есть специальные методы (assertion)

Чтоб протестировать доменную модель можно изолировать его с помощью заглушек из Mockito. Заглушки позволят изолировать модуль из системы, чтобы быть уверенными, что возникающие ошибки происходят именно из-за неверной реализации конкретного модуля

```java
@ParametrizedTest
@ValueSource(ints = 0)
public void test (int result){
    Student student = Mockito.mock(Student.class)
    Mockito.when(student.getDolgs()).thenReturn(result);
    assertEquals(“Обучается”, ISU.getStatus(student))
}
```

Помимо этого, можно активно использовать `@Before*` и `@After*`

### 29. Система Selenium. Архитектура, основные команды написания сценариев

Selenium -- набор средств для автоматизации тестирования веб-приложений

В его состав входят
- IDE
- Selenium Grid
- WebDriver

Одна из главных его особенностей -- кросс-браузерность. Благодаря набору драйверов браузеров он позволяет один раз сделать тест и потом использовать его на разных браузерах

Также он поддерживает написание и генерацию тестов не только на джаве, а на многих языках, в том числе c#, php, python6 etc

**Selenium IDE** -- это интегрированная среда исполнения и разработки тестов. Изначально придумалась как расширение firefox. Можно добавлять assert'ы и команды

Однако у него есть и проблемы: Он запускает тесты только в firefox, у него слабо развито управление логикой теста, он умеет запускать только свои сценарии. Поэтому часто используют SeleniumServer

**Selenium WebDriver** -- это по сути API для рабоы с браузерами. Он представляет набор драйверов браузеров + набор клиентских библиотек для этих драйверов на разных языках. То есть это прокси между селениумом и браузером

**Selenium Grid** -- с помощью него можно запускать тесты на разных машинах, разных браузерах, при этом делать это параллельно. На самом деле grid - это кластер, состоящий из нескольких selenium серверов. Selenium Grid имеет топологию «звезда», то есть в его составе имеется выделенный сервер, который носит название «хаб» или «коммутатор», а остальные сервера называются «ноды» или «узлы».

Команды:
- click, clickAndWait 
- type - ввод значений
- select - выбор значений из списка
- open - открывает страницу
- assert**
- wait**
- verify *
- store
- echo

assert и verify нужны для проверок. Обычно проверяетс, есть ли элемент на странице, есть ли заданный текст

Разница между ними в том, что verify не останавливает тест если проверка не прошла

### 30. Система Selenium. Assertion & Verification. Команды. Команды wait**.

Selenium -- набор средств для автоматизации тестирования веб-приложений

В его состав входят
- IDE
- Selenium Grid
- WebDriver

Одна из главных его особенностей -- кросс-браузерность. Благодаря набору драйверов браузеров он позволяет один раз сделать тест и потом использовать его на разных браузерах

Также он поддерживает написание и генерацию тестов не только на джаве, а на многих языках, в том числе c#, php, python6 etc

Команды:
- click, clickAndWait 
- type - ввод значений
- select - выбор значений из списка
- open - открывает страницу
- assert**
- verify *
    - verifyTextPresent
    - verifyTitle
    - verifyElementPresent
    - verifyValue
    - *у assert команды аналогичные
- wait**
    - waitForPageLoad
    - waitForAlert
    - waitForTable
    - waitForTitle
- store
- echo

assert и verify нужны для проверок. Обычно проверяетс, есть ли элемент на странице, есть ли заданный текст

Разница между ними в том, что verify не останавливает тест если проверка не прошла

### 31. Система Selenium. Selenium RC, WebDriver, Grid.

Selenium -- набор средств для автоматизации тестирования веб-приложений

В его состав входят
- IDE
- Selenium Grid
- WebDriver

Одна из главных его особенностей -- кросс-браузерность. Благодаря набору драйверов браузеров он позволяет один раз сделать тест и потом использовать его на разных браузерах

Также он поддерживает написание и генерацию тестов не только на джаве, а на многих языках, в том числе c#, php, python6 etc

**Selenium IDE** -- это интегрированная среда исполнения и разработки тестов. Изначально придумалась как расширение firefox. Можно добавлять assert'ы и команды

Однако у него есть и проблемы: Он запускает тесты только в firefox, у него слабо развито управление логикой теста, он умеет запускать только свои сценарии. Поэтому часто используют SeleniumServer

**Selenium WebDriver** -- это по сути API для рабоы с браузерами. Он представляет набор драйверов браузеров + набор клиентских библиотек для этих драйверов на разных языках. То есть это прокси между селениумом и браузером

**Selenium Grid** -- с помощью него можно запускать тесты на разных машинах, разных браузерах, при этом делать это параллельно. На самом деле grid - это кластер, состоящий из нескольких selenium серверов. Selenium Grid имеет топологию «звезда», то есть в его составе имеется выделенный сервер, который носит название «хаб» или «коммутатор», а остальные сервера называются «ноды» или «узлы».

**Selenium RC** -- предыдущая версия библиотеки управления браузерами. RC означает remote control. То есть это средство *удаленного* управления браузерами. Сейчас уже устарел и предлагается использовать WebDriver

### 32. Язык XPath. Основные конструкции, оси. Системные функции.

XPath -- это язык запросов к html-документу

- `div` -- выбирает узлы с именем div
- `/` -- осуществляет поиск на текущем уровне документа относительно местоположения
- `//` -- поиск по всему документу
- `.` -- текущий узел
- `..` -- родительский узел

`/` это также разделитель пути и корень. То есть `/div` -- это множество div'ов на первом уровне вложенности
`[]` -- для обозначения предиката. Внутри можно использовать функции, пути и тд
`|` -- union

`//div[contains(@class, 'article-heading')]`

ОСИ -- один из основных способов добираться от одного узла документа до другого

`child::` -- множество элементов-потомков (на один уровень ниже)
`parent::` -- множество элементов-родителей (то же что `..`)
`self::` -- текущий элемент (то же что `.`)
`following::` -- множество элементов, ниже по уровню

Системные функции:

`document(object, node-set?)` -- возвращает документ, указанный в пером аргументе
`format-number(number, string, string?)` -- формирует число по образцу
`generate-id(node-set?)` -- возвращает уникальный id

### 33. Язык XPath. Функции с множествами. Строковые, логические и числовые функции.

XPath -- это язык запросов к html-документу

- `div` -- выбирает узлы с именем div
- `/` -- осуществляет поиск на текущем уровне документа относительно местоположения
- `//` -- поиск по всему документу
- `.` -- текущий узел
- `..` -- родительский узел

`/` это также разделитель пути и корень. То есть `/div` -- это множество div'ов на первом уровне вложенности
`[]` -- для обозначения предиката. Внутри можно использовать функции, пути и тд
`|` -- union

`//div[contains(@class, 'article-heading')]`

- Функции с множествами
    - `count()`
    - `position()`
    - `text()`
    - `last()`
- Строковые
    - `string-length()`
    - `matches()`
    - `contains()`
    - `start-with()`
- Логические
    - `true()`
    - `false()`
    - `not()`
    - `boolean()`
- Числовые
    - `sum()`
    - `round()`
    - `number()`
    - `ceiling()`
    - `floor()`

### 34. Apache JMeter. Архитектура, Элементы тестового плана. Последовательность выполнения.

JMeter -- бесплатный инструмент нагрузочного тестирования, позволяющий разрабатывать и запускать нагрузочные тесты в разных режимах, в том числе распределенно

Плюсы:
- Бесплатный, кроссплатформенный
- Есть простой GUI
- Возможность создания распределенной нагрузки
- Эмуляция одновременной работы пользователей
- Снятие метрик
- Возможность разрабатывать плагины
- Планы тестирования в XML

Тестовый план:

- Thread Group 
    - Описывает пул пользователей для выполнения теста
- Семплеры
    - Формируют запросы, генерируют результаты
- Логические контроллеры
    - Определяют порядок вызова семплеров
    - Есть конструкции управления
- Слушатели
    - Получают ответы
    - Обрабатывают результаты
- Таймеры
    - Контролируют задержки между запросами
- Assertions
- Элементы конфигурации
- Препроцессоры
- Постпроцессоры

Порядок работы при составленном тестовом плане такой:

- Элементы конфигурации
- Препроцессоры
- Таймеры
- Семплеры
- Постпроцессоры
- Assertions
- Слушатели

### 35. Apache Jmeter. Дополнительные возможности. Распределенное тестирование.

JMeter -- бесплатный инструмент нагрузочного тестирования, позволяющий разрабатывать и запускать нагрузочные тесты в разных режимах, в том числе распределенно

Плюсы:
- Бесплатный, кроссплатформенный
- Есть простой GUI
- Возможность создания распределенной нагрузки
- Эмуляция одновременной работы пользователей
- Снятие метрик
- Возможность разрабатывать плагины
- Планы тестирования в XML

Также у него есть разные дополнительные возможности, позволяющие корректно составить нагрузочное тестирование 

- Автоматическая генерация CSV файла
- Ограничение полосы пропускания
- IP Spoofing
- Поддержка различных специальных тестов (например на OLTP нагрузку)

Также поддерживается возможность тестировать сервер распределенно, чтобы найти ботлнеки именно в работе сервера, а не тестовой инфраструктуры

![](https://hackmd.io/_uploads/S1iBsqEv3.png)


### 36. Область деятельности тестирования безопасности. Риски безопасности. Цифровые активы (digital assets). Методы доступа и обеспечения безопасности. Политики безопасности

Тестирование безопасности -- одна из стадий тестирования, на которой, как и везде, преследуются классические цели: повысить уверенность в качестве ПО

В этом виде тестирования фокус делается на проверке безопасности функциональности, которая обычно определена в:
- Спецификации и требованиях
- Сценариях использования
- Анализе рисков

Дополнительное внимание уделяется
- Политике и процедурам безопасности
- Поведению взломщика
- Известным уязвимостям и дефектам

Обычно существует отдельная группа рисков в разрабоке ПО:
- Опасность нарушения конфиденциальности, целостности или доступности

Экспозиция риска = вероятность ущерба * цена ущерба

Стандартные методы работы с рисками: Оценка, контроль и управление

При этом есть конкретные цифровые активы, которые мы хотим защитить:
- Данные пользователей, бизнес-планы
- Документация, код, модели, диаграммы
- Документы, процессы
- Финансовая и налоговая отчетности
- Презентации и обучающие курсы
- Сообщения и емейлы
- Прототипы устройств
- Возможность оказывать услуги
- Репутация

Чтобы защищиаться от таких проблем можно например предлагать определенные правила доступа сотрудников с системе компании:
- VPN из публичных сетей (да или нет)
- Внутренный wi-fi
- Физическая передача объектов
- Почта и мессенджеры

И решением могут быть:
- Шифрование
- Аутентификация и токены
- Авторизация и права доступа

Возможные политики безопасности:
- Приемлемое использование, минимальный уровень доступа, управление аккаунтами пользователей
- Классификация информации
- Безопасность серверов и моб устройств
- Реакция на инциденты, мониторинг безопасности
- Защита от закладок, тесты

### 37. Тестирование безопасности. Практически используемые методы. Безопасный код. Основные подходы. Common Weakness Enumeration

Тестирование безопасности -- одна из стадий тестирования, на которой, как и везде, преследуются классические цели: повысить уверенность в качестве ПО

В этом виде тестирования фокус делается на проверке безопасности функциональности, которая обычно определена в:
- Спецификации и требованиях
- Сценариях использования
- Анализом рисков

Дополнительное внимание уделяется
- Политике и процедурам безопасности
- Поведению взломщика
- Известным уязвимостям и дефектам

Обычно существует отдельная группа рисков в разрабоке ПО:
- Опасность нарушения конфиденциальности, целостности или доступности

Важно помнить, что как и любое тестирование, тестирование безопасности не может найти все дефекты и не может доказать, что их нет

Используется несколько подходов:
- Статические анализаторы безопасного кода
- Фаззи тестирование (Фаззинг)
- Тестирование на проникновение

Также есть основные подходы к написанию безопасного кода:
- Проверяйте все входные значения
- Следуйте варнингам компилятора
- Проектируйте и устанавливайте политики безопасности
- keep it simple
- Запрещайте доступ если явно не разрешено
- Реализуйте принцип минимальных доступных привилегий
- Очищайте данные отправленные к другим системам
- Практикуйте многоуровневую защиту
- Проверяйте качество при помощи тестирования
- Реализуйте стандарты безопасного кодирования

Common Weakness Enumeration - набор из документов и статей, содержащих основные уязвимости, практики и советы по их избежанию. То есть это общая база уязвимостей, отсортированная и удобная для прочтения

### 38. Fuzzy testing (Фаззинг). Типы фаззинга

Тестирование безопасности -- одна из стадий тестирования, на которой, как и везде, преследуются классические цели: повысить уверенность в качестве ПО

В этом виде тестирования фокус делается на проверке безопасности функциональности, которая обычно определена в:
- Спецификации и требованиях
- Сценариях использования
- Анализом рисков

Дополнительное внимание уделяется
- Политике и процедурам безопасности
- Поведению взломщика
- Известным уязвимостям и дефектам

Обычно существует отдельная группа рисков в разрабоке ПО:
- Опасность нарушения конфиденциальности, целостности или доступности

Важно помнить, что как и любое тестирование, тестирование безопасности не может найти все дефекты и не может доказать, что их нет

Используется несколько подходов:
- Статические анализаторы безопасного кода
- Фаззи тестирование (Фаззинг)
- Тестирование на проникновение

Фаззинг -- один из методов тестирования безопасности. Тут идея такая: раньше мы тестировали программу на данных, которые считали заведомо корректными (или нарочно ошибочными) и брали из из требований или спецификации. А теперь давайте просто нагрузим ее какими-то произвольными данными (аномальными, случайными)

Типы:
- Dump Fuzzing -- изменение существующих тестов для создания новых
- Smart Fuzzing -- Определение новых тестов на основе моделей входных данных
- Evolutionary -- Генерирование тестов на основе ответов специальных программ

### 39. Penetration Testing. Тестирование на проникновение. Dynamic Application Security Testing (DAST) Tools

Тестирование безопасности -- одна из стадий тестирования, на которой, как и везде, преследуются классические цели: повысить уверенность в качестве ПО

В этом виде тестирования фокус делается на проверке безопасности функциональности, которая обычно определена в:
- Спецификации и требованиях
- Сценариях использования
- Анализом рисков

Дополнительное внимание уделяется
- Политике и процедурам безопасности
- Поведению взломщика
- Известным уязвимостям и дефектам

Обычно существует отдельная группа рисков в разрабоке ПО:
- Опасность нарушения конфиденциальности, целостности или доступности

Важно помнить, что как и любое тестирование, тестирование безопасности не может найти все дефекты и не может доказать, что их нет

Используется несколько подходов:
- Статические анализаторы безопасного кода
- Фаззи тестирование (Фаззинг)
- Тестирование на проникновение

Тестирование на проникновение -- один из видов тестирования безопасности. Он в общем случае ничем не отличается от хакинга, то есть является незаконным

То есть это попытка проникнуть в систему любым способом. По этой дисциплине даже есть соревнования

Имеет много разных типов (auth, ddos, password steal, ...)

В наборе тулзов DAST Tools собраны многие известные уязвимости, которые могут сломать систему. Это также можно использовать только при согласии разработчиков системы

Среди них также есть множество коммерческих продуктов

### 40. Организация тестов безопасности в циклах и типах разработки. Тестирование общих механизмов безопасности.


Тестирование безопасности -- одна из стадий тестирования, на которой, как и везде, преследуются классические цели: повысить уверенность в качестве ПО

В этом виде тестирования фокус делается на проверке безопасности функциональности, которая обычно определена в:
- Спецификации и требованиях
- Сценариях использования
- Анализом рисков

Дополнительное внимание уделяется
- Политике и процедурам безопасности
- Поведению взломщика
- Известным уязвимостям и дефектам

Обычно существует отдельная группа рисков в разрабоке ПО:
- Опасность нарушения конфиденциальности, целостности или доступности

Важно помнить, что как и любое тестирование, тестирование безопасности не может найти все дефекты и не может доказать, что их нет

Используется несколько подходов:
- Статические анализаторы безопасного кода
- Фаззи тестирование (Фаззинг)
- Тестирование на проникновение

Подход также не очень отличается от других тестов:
- Планирование
- Проектирование
- Реализация и выполнение
- Отчеты по результатам
- Анализ
- ИНтеграция в процесс разработки

При этом при последовательно разрабоке важно помнить, что такое тестирование проводится в конце, а значит может выявить очень дорогие проблемы

При инкрементальной разработке могут применяться в процессе спринтов, и требования могут меняться также в процессе спринтов. Такие тестиы могут проводиться в течение всего проекта

