ук 03.007.02 2011
TRANSCRIPT
![Page 1: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/1.jpg)
LOGO
Части I, II, III
Тестирование
hwdtech.com УК 03.007.02-2011
![Page 2: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/2.jpg)
Цели тестирования
![Page 3: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/3.jpg)
Зачем тестирование нужно?
1
2
3
Полностью протестировать любую программу.
Тестирование позволит убедиться, что программа
работает правильно.
Тестировщик должен гарантировать правильность
выполнения программы.
![Page 4: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/4.jpg)
Это были самые распространенные заблуждения о тестировании
![Page 5: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/5.jpg)
Разберемся с ними подробнее…
![Page 6: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/6.jpg)
Стандартные возражения
Почему программисты вообще делают ошибки? Пусть они их не делают.
Сначала все напишем по-быстрому, а потом поправим все ошибки.
Сколько ошибок мы нашли? N – это много или мало?
Почему наши пользователи находят ошибки, если мы потратили на тестирование столько времени?!
Мы нашли N ошибок – мы можем остановить тестирование?
А как будет себя вести наше приложение в эксплуатации?
Заблуждения – это реакция на неудовлетворительные ответы на данные вопросы.
![Page 7: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/7.jpg)
Полностью протестировать любую
программу невозможно
• Проверить реакцию программы на каждую комбинацию входных данных – Есть корректные и некорректные входные данные
• Проверить каждую возможную последовательность выполнения команд программы – Мейерс, 1979
Написал программу из 100 строк, имеющую 108 последовательностей выполнения
![Page 8: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/8.jpg)
Тестирование позволит убедиться,
что программа работает правильно
• Правильность программы нельзя доказать логически – Можно проверить только соответствие спецификации
![Page 9: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/9.jpg)
Тестировщик должен гарантировать
правильность выполнения
программы
• 40-80% времени тратится на исправление ошибок
• 1,5 ошибки на один оператор программы
• Тестировщик тоже человек!
![Page 10: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/10.jpg)
Обсуждение
Ваши версии – зачем нужно тестирование?
![Page 11: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/11.jpg)
Качество
![Page 12: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/12.jpg)
Что такое качество?
• Качество ≠ отсутствие ошибок
В самом качественном автомобиле 2010 года выявляется в среднем 59 дефектов на 100 автомобилей в первые 90 дней.
• Удовлетворенность заказчика? Пациент, которому действия доктора причиняют боль.
• Соответствие ожиданиям: делает то, что должен, не делает того, что не должен
![Page 13: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/13.jpg)
Определение качества
ISO 9126
Качество ПО – совокупная характеристика ПО с учетом следующих составляющих: – Надежность
– Сопровождаемость
– Практичность
– Эффективность
– Мобильность
– Функциональность
![Page 14: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/14.jpg)
Определение качества
Надежность – набор атрибутов, относящихся к способности ПО сохранять свой уровень качества функционирования в установленных условиях за определенный период времени
• Уровень завершенности (отсутствие ошибок)
• Устойчивость к дефектам
• Восстанавливаемость
• Доступность
• Готовность
![Page 15: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/15.jpg)
Определение качества
Мобильность — набор атрибутов, относящихся к способности ПО быть перенесенным из одного окружения в другое
• Адаптируемость
• Простота установки
• Сосуществование
• Замещаемость
![Page 16: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/16.jpg)
Определение качества
Сопровождаемость - набор атрибутов, относящихся к объему работ, требуемых для проведения конкретных изменений (модификаций)
• Удобство анализа
• Изменяемость
• Стабильность
• Тестируемость
![Page 17: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/17.jpg)
Определение качества
Практичность (применимость) — набор атрибутов, относящихся к объему работ, требуемых для исполнения и индивидуальной оценки такого исполнения определенным или предполагаемым кругом пользователей
• Понятность
• Простота использования
• Изучаемость
• Привлекательность
![Page 18: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/18.jpg)
Определение качества
Эффективность — набор атрибутов, относящихся к соотношению между уровнем качества функционирования ПО и объемом используемых ресурсов при установленных условиях
• Временная эффективность
• Используемость ресурсов
![Page 19: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/19.jpg)
Определение качества
Функциональность — набор атрибутов характеризующий, соответствие функциональных возможностей ПО набору требуемой пользователем функциональности
• Пригодность к применению
• Корректность
• Способность к взаимодействию
• Защищенность
![Page 20: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/20.jpg)
Как получается Качество ПО
• Качество ПО зависит только от качества его процесса разработки
• Качество процесса разработки зависит только от культуры разработки самой проектной команды
![Page 21: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/21.jpg)
Определение тестирования
Тестирование ПО - процесс исследования программного обеспечения (ПО) с целью получения информации о качестве продукта.
(Толковый словарь)
Дефект - изъян, порча, повреждение; недостаток, несовершенство.
![Page 22: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/22.jpg)
Влияние дефектов
PMBOK
![Page 23: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/23.jpg)
Влияние дефектов
Водопадная модель
![Page 24: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/24.jpg)
Влияние дефектов
По виду артефактов
![Page 25: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/25.jpg)
Влияние дефектов
Итеративная модель (снижение рисков)
![Page 26: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/26.jpg)
Влияние дефектов
С точки зрения управление рисками
![Page 27: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/27.jpg)
Влияние дефектов
С точки зрения размера проекта (Панкратов В.)
![Page 28: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/28.jpg)
Влияние дефектов
По степени автоматизации действий
![Page 29: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/29.jpg)
Соберем идеи
• Тестирование ПО больше, чем просто поиск дефектов!!!
• Тестирование – это часть процесса разработки, которое занимает 40-80% всего процесса разработки и стоит 30-50% от общей стоимости проекта
• Тестирование не только может выявлять дефекты, но и предотвращать их.
• Эффективность тестирования сильно влияет на стоимость проекта и сроки его завершения.
• Отказ от тестирования – это стратегия пассивного принятия рисков.
• Автоматизация тестирования должна приводить к снижению расходов на тестирование.
![Page 30: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/30.jpg)
Классификация видов
тестирования
По объекту тестирования:
• Функциональное тестирование
• Тестирование производительности – Нагрузочное тестирование
– Тестирование стабильности
– Стресс-тестирование
• Тестирование удобства использования
• Тестирование интерфейса пользователя
• Тестирование безопасности
• Тестирование локализации
• Тестирование совместимости
![Page 31: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/31.jpg)
По знанию системы: • Тестирование белого ящика
– Соответствие кода соглашениям по наименованию и по кодированию
– Корректная обработка ошибок – Выделение памяти – Покрытие кода: все ли операторы были выполнены хотя бы один
раз – Проверка всех путей управления модуля
• Тестирование черного ящика • Тестирование серого ящика По степени автоматизации: • Ручное тестирование • Автоматизированное тестирование • Полуавтоматизированное тестирование
![Page 32: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/32.jpg)
По степени автоматизации:
• Ручное тестирование
• Автоматизированное тестирование
• Полуавтоматизированное тестирование
По степени изолированности системы:
• Модульное тестирование
• Интеграционное тестирование
• Системное тестирование
![Page 33: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/33.jpg)
По степени позитивности сценариев:
• Позитивное тестирование
• Негативное тестирование
По степени подготовленности к тестированию:
• Тестирование по документации (формальное тестирование)
• Тестирование как есть (интуитивное тестирование)
![Page 34: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/34.jpg)
По времени проведения тестирования:
• Альфа-тестирование – Тестирование при приемке
– Тестирование новой функциональности
– Регрессионное тестирование
– Тестирование при сдаче
• Бета-тестирование
• Приемочное тестирование
![Page 35: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/35.jpg)
Логика Хоара
• Контрактная модель программирования
• Используется для доказательства частичной и полной корректности компьютерных программ
• Тройка Хоара {pred} statement {post}, где pred, post – утверждения (assertions), pred – предусловие, post - постусловие, statement – оператор языка программирования
Пример:
{x+1 == 43} y=x+1; {y == 43 ^ x == 42}
• Логика Хоара определяет аксиомы и правила вывода для императивного языка программирования
(http://ru.wikipedia.org/wiki/Логика_Хоара)
![Page 36: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/36.jpg)
Правила Логики Хоара
Аксиома пустого оператора
{P} skip {P}
Аксиома присваивания
{P[E/x]} x := E {P}
Правило композиции
{P} S {Q}, {Q} T {R} ╞ {P} S;T {R}
Правило условного оператора
{B ^ P} S {Q}, {B’ ^P} T {Q} ╞ {P} if B then S else T endif {Q}
Правило вывода
P1 → P, {P} S {Q}, Q → Q1 ╞ {P1} S {Q1}
Правило оператора цикла
{P ^ B} S {P} ╞ {P} while B do S done {B’ ^ P}
![Page 37: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/37.jpg)
От формальной системы к
автоматическому тестированию
• Все последовательности операторов протестировать
невозможно
• Часто тестирование – это многократно повторяющиеся рутинные действия
• Человек преимущественно необходим только на этапе оценки результатов, выданных ПО, на их соответствие требованиям заказчика.
• Часто проверку результатов на соответствие требованиям заказчика также можно автоматизировать.
![Page 38: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/38.jpg)
Разминка
Соберите фигуру на слайде
![Page 39: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/39.jpg)
Модульное (юнит)
тестирование
• С помощью правила композиции и/или правила вывода объединяем несколько операторов в один общий блок. Проверка предусловия и постусловия для блока операторов равносильна проверке пост- и предусловий каждого из операторов в этом блоке.
Пример: {x + 1 ==43 } y = x + 1; {y == 43}
{y == 43} z = y; {z == 43}
По правилу композиции
{x + 1 == 43} y = x + 1; z = y; {z == 43}
![Page 40: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/40.jpg)
• Какие границы блоков удобнее выбирать для целей тестирования? – Методы (см. Контрактная модель программирования)
{pred} void f(object arg1)… {post}
– Классы (как контейнер методов)
• Часто при разработке кода делаются неявные предположения о состоянии программы (Asserts) Исследования: На каждые 5-6 строк делается как минимум одно
неявное предположение о состоянии программы
Вывод: Рекомендация по рефакторингу – методы должны быть короткими (5-7 строк)
![Page 41: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/41.jpg)
Следствия
• Пишутся на том же языке, что и тестируемая процедура или класс
• Юнит-тесты должны быть простыми!!!
Плюсы
• Стимулируют рефакторинг
• Поощряют написание слабосвязанного кода
• Упрощают регрессионное тестирование
• Юнит-тесты = документация
Ограничения
• Не проверяют взаимодействие компонентов
• Не дают 100% гарантии
• Сложно покрывать тестами уже написанное приложение
![Page 42: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/42.jpg)
Интеграционное тестирование с
точки зрения автоматизации
• Есть несколько методов, каждый из которых покрыт тестами
• Эти методы используются для реализации функции верхнего уровня
• Покрытие тестами этой функции и есть интеграционное тестирование
Замечание: Покрытие тестами только
верхнеуровневой функции не принесет много пользы, т.к. не проведено модульное тестирование самой функции, а значит нет возможности локализовать ошибку
![Page 43: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/43.jpg)
Критерий остановки
• На один метод как правило пишется несколько тестов
Когда пора остановиться?
Варианты:
• По времени – очень плохой критерий
• Вычислять коэффициент покрытия кода – не всегда есть под рукой инструменты для вычисления покрытия кода, нет 100% гарантии
• Test Driven Development
![Page 44: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/44.jpg)
Test-Driven Development
Написание тестов
Тесты не компилируются
Определение интерфейсов
Тесты не проходят
Написание кода
Тесты проходят
Рефакторинг
![Page 45: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/45.jpg)
Разминка
Загадано слово.
Можно задавать вопросы только с ответами да/нет.
Угадайте за минимальное количество вопросов.
![Page 46: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/46.jpg)
Критерий “хорошего” теста
• Существует обоснованная вероятность выявления тестом ошибки
• Набор тестов не должен быть избыточным
• Тест должен быть наилучшим в своей категории
• Не должен быть слишком простым и слишком сложным
![Page 47: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/47.jpg)
Разработка тестов
• Классы эквивалентности
• Граничные условия
• Stubs
• Mocks
![Page 48: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/48.jpg)
JUnit
import org.junit.Test;
import junit.framework.Assert;
public class MathTest
{
@Test
public void testEquals()
{
Assert.assertEquals(4, 2 + 2);
Assert.assertTrue(4 == 2 + 2);
}
@Test
public void testNotEquals()
{
Assert.assertFalse(5 == 2 + 2);
}
}
public class TestClass extends TestCase
{
public TestClass(String testName)
{ super(testName); }
@Test
public void testFactorialNull()
{
MathFunc math = new MathFunc(); assertTrue(math.factorial() == 1);
}
@Test
public void testFactorialPositive()
{
MathFunc math = new MathFunc(5); assertTrue(math.factorial() == 120);
}
@Test
public void testPlus()
{
MathFunc math = new MathFunc(45); assertTrue(math.plus(123) == 168);
}
}
![Page 49: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/49.jpg)
junit.framework.Assert
• assertEquals
• assertFalse
• assertNotNull
• assertNull
• assertNotSame
• assertSame
• assertTrue
![Page 50: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/50.jpg)
Классы эквивалентности
Если при выполнении двух тестов ожидается один и тот же результат, то они считаются эквивалентными.
Группа тестов представляет собой класс эквивалентности, если:
![Page 51: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/51.jpg)
Классы эквивалентности
• Все тесты предназначены для выявления одной и той же ошибки
• Если один из тестов выявит ошибку, то остальные скорее всего тоже это сделают
• Если один из тестов не выявит ошибки, то остальные скорее всего тоже этого не сделают
![Page 52: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/52.jpg)
Классы экивалентности
• Тесты включают значения одних и тех же входных данных
• Для их проведения выполняются одни и те же операции
• В результате тестов формируются значения одних и тех же выходных данных
• Либо не один из тестов не вызывает обработку ошибок в программе, либо всеми тестами вызывается одна и та же обработка ошибок
![Page 53: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/53.jpg)
Пример классов
эквивалентности
Решение квадратного уравнения в вещественных числах
Result SquareRoot(double a, double b, double c);
• Уравнение, имеющее решение в виде двух корней кратности 1 – (1, -1, -2)
• Уравнение, имеющее решение в виде одного корня кратности 2 – (1, 2, 1)
• Уравнение, не имеющее решений – (1, 0, 1)
• Коэффициент a = 0
![Page 54: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/54.jpg)
Разминка
Определить класс эквивалентности
![Page 55: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/55.jpg)
Способы выявления
классов эквивалентности
• Заведомо неверные или недопустимые данные Пример: a = 0 с предыдущего слайда
![Page 56: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/56.jpg)
• Диапазоны числовых значений I. Для диапазона значений есть три недопустимых класса
экивалентности:
– Числа меньше диапазона
– Числа больше диапазона
– Нечисловые данные
Замечание: Иногда некоторые из этих классов могут отсутствовать, например, нет ограничения сверху. Лучше явно убедиться, что этого ограничения нет, взяв очень большое число.
II. Поддиапазоны, например, 1-5, 9, 10, 12, 14, 16 – этажность зданий
![Page 57: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/57.jpg)
• Фиксированные перечни значений – Все значения данного перечня
– Любое значение, не входящее в перечень
Например, улицы г. Омска
Идеи для поиска классов эквивалентности
– Аббревиатуры
– Сокращения
– Ошибки при написании
– Старые названия
![Page 58: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/58.jpg)
• Списки меню, выбора Любой элемент меню может представлять отдельный класс
эквивалентности
• Переменные, значения которых должны быть равными Значения, которые являются приемлемыми, но не принимаются в
данном месте программы, образуют отдельные эквивалентности
Пример: дата 13-07-2011, 07-13-2011, 13.07.2011, 13/07/2011 числа с плавающей точкой 12,43 12.43
![Page 59: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/59.jpg)
• Значения, зависящие от времени Пример: запрос серверу, когда
– Ничего не обрабатывается
– Идет обработка другого запроса
– Сразу после завершения обработки другого запроса
• Группы переменных, результат которых ограничивается определенным набором или диапазоном значений Пример: квадратное уравнение
![Page 60: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/60.jpg)
• Действия, на которые программа отвечает эквивалентными событиями Пример, обработка ошибок
• Различные варианты окружения Пример, объем оперативный памяти:
– Проектный
– Недостаточный
– Больше, чем проектный
![Page 61: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/61.jpg)
Граничные условия
• Для каждого класса эквивалентности нужно провести минимальное число тестов Следовательно: Лучшие тесты – те, которые лежат на границах
классов эквивалентности
Пример, для квадратного уравнения лучше брать не 0, а число, чуть меньше “эпсилон”
![Page 62: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/62.jpg)
Разминка
“Самолетики”
![Page 63: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/63.jpg)
Stubs
Зависимость – это объект системы, с котором взаимодействует тестируемый код и над которым нет контроля у разработчика тестов.
Примеры: – Объекты операционной системы
– Объекты, разработка которых еще не была завершена/начата
– Сторонние библиотеки
Заглушка – контролируемая замена зависимости в разрабатываемой системе
![Page 64: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/64.jpg)
Когда применяются
заглушки
• Создать имитацию загрузки или ограниченности ресурсов
• Создать имитацию сбоя в системе
• Выполнить тестирование, когда зависимость еще не реализована
• Гарантировать отсутствие влияния зависимости на результаты тестирования
• Отладка тестов для фасада
![Page 65: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/65.jpg)
Идеи по реализации
заглушек
• Заглушка имитирует поведение реального объекта – применяем паттерн Прокси
• Код должен, использующий базовый интерфейс для Заглушек и реальных объектов, должен удовлетворять принципу подстановки Лисков
• Тестируемые классы должны либо конфигурироваться интерфейсами, либо использовать фабрики
![Page 66: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/66.jpg)
Mocks
Тестирование основанное на состояниях (традиционный подход)
Недостатки: – Требует знания о внутреннем состоянии объекта –возможно
нарушение инкапсуляции
– Нарушает принципы ООП
![Page 67: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/67.jpg)
Тестирование основанное на поведении – сосредоточено на том, какие методы вызываются, в какой последовательности, какие результаты выдают
Поведенческое тестирование – тестирование того, как объект взаимодействует с другими объектами, то есть посылает выходные данные и принимает входные от других объектов.
![Page 68: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/68.jpg)
Mock-объект – прокси-объект, который определяет прошел ли тестируемый объект тест или нет
Различие между Stub и Mock:
• Stub подменяет реальный объект с целью имитации реального функционала
• Mock подменяет реальный объект с целью оценки правильности взаимодействия тестируемого объекта с подменяемым.
![Page 69: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/69.jpg)
Подходы к реализации mock
• Proxy (easymock, jmock, moq, rhino.mocks)
• Подгрузка класса mock объекта вместо реального класса
(jmockit, powermock, DI контейнеры)
![Page 70: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/70.jpg)
Библиотека EasyMock
IFoo mock = EasyMock.createMock(IFoo.class);
EasyMock.expect(mock.doSomething(“argument”)).andReturn(true);
EasyMock.replay(mock);
bool result = test.perform();
EasyMock.verify(mock);
![Page 71: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/71.jpg)
Проверка поведения метода
• andExpectThrow(exception)
• ExpectLastCall();
• times(min, max)
• AnyTimes()
• AtLeastOnce()
![Page 72: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/72.jpg)
Параметры метода
• eq(value)
• isA(class)
• anyBoolean(), anyByte(), anyChar(), anyDouble(), …
• IsNull()
• NotNull()
• startsWith(string), contains(string), endsWith(string)
• matches(regexp), find(regexp)
expect(mockDao.loadByUsernameAndPassword(eq(userName),
eq(passwordHash))) .andReturn(results);
![Page 73: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/73.jpg)
Пример теста
import junit.framework.TestCase;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.easymock.EasyMock.eq;
public class LoginServiceTest extends TestCase
{
private LoginServiceImpl service;
private UserDAO mockDao;
@Override public void setUp()
{
service = new LoginServiceImpl();
mockDao = createStrictMock(UserDAO.class);
service.setUserDAO(mockDao);
}
![Page 74: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/74.jpg)
public void testSuccsessScenario()
{
User results = new User();
String userName = "testUserName";
String password = "testPassword";
String passwordHash = " Ӷ&I7 Ni=.";
expect(mockDao.loadByUsernameAndPassword(eq(userName), eq(passwordHash))) .andReturn(results);
replay(mockDao);
assertTrue(service.login(userName, password));
verify(mockDao);
}
}
![Page 75: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/75.jpg)
Библиотека Moq
Методы
1. Вызов метода
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
2. Выходные параметры var outString = "ack";
mock.Setup(foo => foo.TryParse("ping", out outString)).Returns(true);
3. Входно-выходные параметры var instance = new Bar();
mock.Setup(foo => foo.Submit(ref instance)).Returns(true);
![Page 76: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/76.jpg)
4. Досуп к параметру
mock.Setup(x => x.DoSomething(It.IsAny<string>()))
.Returns((string s) => s.ToLower());
5. Генерация исключений
mock.Setup(foo =>
foo.DoSomething("reset")).Throws<InvalidOperationException>();
mock.Setup(foo => foo.DoSomething("")).Throws(new
ArgumentException("command");
6. Подстановка возвращаемого значения
mock.Setup(foo => foo.GetCount()).Returns(() => count);
![Page 77: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/77.jpg)
7. Возврат разных значений на каждый вызов функции
var mock = new Mock<IFoo>();
var calls = 0;
mock.Setup(foo => foo.GetCountThing())
.Returns(() => calls)
.Callback(() => calls++);
Console.WriteLine(mock.Object.GetCountThing());
![Page 78: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/78.jpg)
8. Возращение значений в зависимости от значений входных параметров
mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(true);
mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);
mock.Setup(foo => foo.Add(It.IsInRange<int>(0, 10,
Range.Inclusive))).Returns(true);
mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+",
RegexOptions.IgnoreCase))).Returns("foo");
![Page 79: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/79.jpg)
9. Свойства mock.Setup(foo => foo.Name).Returns("bar");
mock.Setup(foo => foo.Bar.Baz.Name).Returns("baz");
mock.SetupSet(foo => foo.Name = "foo");
mock.VerifySet(foo => foo.Name = "foo");
mock.SetupProperty(f => f.Name);
mock.SetupProperty(f => f.Name, "foo");
![Page 80: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/80.jpg)
10. Обратный вызов функций из mock-объекта
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.Execute("ping")).Returns(true).Callback(() =>
calls++);
mock.Setup(foo => foo.Execute(It.IsAny<string>())).Returns(true)
.Callback((string s) => calls.Add(s));
mock.Setup(foo => foo.Execute(It.IsAny<string>())).Returns(true)
.Callback<string>(s => calls.Add(s));
mock.Setup(foo => foo.Execute(It.IsAny<int>(), It.IsAny<string>()))
.Returns(true)
.Callback<int, string>((i, s) => calls.Add(s));
![Page 81: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/81.jpg)
mock.Setup(foo => foo.Execute("ping"))
.Callback(() => Console.WriteLine("Before returns"))
.Returns(true)
.Callback(() => Console.WriteLine("After returns"));
![Page 82: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/82.jpg)
Проверки 1. Вызов метода
mock.Verify(foo => foo.Execute("ping"));
mock.Verify(foo => foo.Execute("ping"), "When doing operation X, the
service should be pinged always");
2. Количество вызовов метода
mock.Verify(foo => foo.Execute("ping"), Times.Never());
mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce());
![Page 83: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/83.jpg)
3. Свойства
mock.VerifyGet(foo => foo.Name);
mock.VerifySet(foo => foo.Name);
mock.VerifySet(foo => foo.Name ="foo");
mock.VerifySet(foo => foo.Value = It.IsInRange(1, 5, Range.Inclusive));
![Page 84: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/84.jpg)
Пример: восстановление
пароля – шаг 1
public void When_user_forgot_password_should_save_user()
{
var stubUserRepository = mockRepository.Create<IUserRepository>();
var stubbedSmsSender = mockRepository.Create<ISmsSender>();
var theUser = new User{HashedPassword = "this is not hashed password"};
stubUserRepository.Setup(x => x.GetUserByName("ayende")).Return(theUser).Verifiable();
var controllerUnderTest = new LoginController(stubUserRepository.Object, stubbedSmsSender.Object);
controllerUnderTest.ForgotMyPassword("ayende");
stubUserRepository.AssertWasCalled( x => x.Save(user));
}
public void ForgotMyPassword(string username)
{
var user = users.GetUserByName(username);
users.Save(user);
}
![Page 85: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/85.jpg)
Пример: восстановление
пароля – шаг 2
public void When_user_forgot_password_should_reset_password()
{
var stubUserRepository = mockRepository.Create<IUserRepository>();
var stubbedSmsSender = MockRepository.Create<ISmsSender>();
var theUser = new User{HashedPassword = "this is not hashed password"}; stubUserRepository.Setup(x => x.GetUserByName("ayende")).Return(theUser);
var controllerUnderTest = new LoginController(stubUserRepository.Object, stubbedSmsSender.Object);
controllerUnderTest.ForgotMyPassword("ayende");
Assert.AreNotEqual("this is not hashed password", theUser.HashedPassword);
}
public void ForgotMyPassword(string username)
{
var user = users.GetUserByName(username);
user.HashedPassword = "new pass";
users.Save(user);
}
![Page 86: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/86.jpg)
Пример: восстановление
пароля – шаг 3
public void When_user_forgot_password_should_save_user()
{
var mockUserRepository = mockRepository.Create<IUserRepository>();
var stubbedSmsSender = mockRepository.Create<ISmsSender>();
var theUser = new User{HashedPassword = "this is not hashed password"};
mockUserRepository.Setup(x => x.GetUserByName("ayende")).Return(theUser);
mockUserRepository.Setup ( x => x.Save(theUser) ).Verifiable();
var controllerUnderTest = new LoginController(mockUserRepository.Object, stubbedSmsSender.Object);
controllerUnderTest.ForgotMyPassword("ayende");
mockUserRepository.VerifyAll();
}
public void ForgotMyPassword(string username)
{
var user = users.GetUserByName(username);
user.HashedPassword = "new pass";
users.Save(user);
}
![Page 87: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/87.jpg)
Пример: восстановление
пароля – шаг 4
public void When_user_forgot_password_should_sms_user()
{
var stubUserRepository = mockRepository.Create<IUserRepository>();
var stubbedSmsSender = mockRepository.Create<ISmsSender>();
var theUser = new User{HashedPassword = "this is not hashed password", Phone = "1234-1234"};
stubUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);
var controllerUnderTest = new LoginController(stubUserRepository.Object, stubbedSmsSender.Object);
controllerUnderTest.ForgotMyPassword("ayende");
stubbedSmsSender.AssertWasCalled( x => x.Send( Arg.Is.Equal("1234-1234"), Arg.Text.StartsWith("Password was changed to:") ));
}
public void ForgotMyPassword(string username)
{
var user = users.GetUserByName(username);
user.HashedPassword = "new pass";
users.Save(user);
smsSender.Send(user.Phone, "Password was changed to: new pass");
}
![Page 88: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/88.jpg)
Пример: заглушка для еще
не написанного объекта
Interface IUserStorage
{
bool Save(User user);
bool Connect(string userName);
}
![Page 89: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/89.jpg)
Пример: заглушка для еще
не написанного объекта
class AbstractFactory
{
IUserStorage Create()
{
Mock<IUserStorage> storage = mockRepository.Create<IUserStrorage>();
storage.Setup( s => s.Save(It.IsAny<User>())).Returns(true);
storage.Setup(s => s.Connect(“ayende”)).Returns(true);
storage.Setup(s => s.Connect(It.Not.IsEqual<string>(“ayende”))).Returns(false);
return storage.Object; }
MockRepository mockRepository = new MockRepository(MockBehavior.Strict);
}
![Page 90: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/90.jpg)
Пример тестирования через
mock-объект
Пример 03.007.02-2011.01
![Page 91: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/91.jpg)
Пример: модульное
тестирование
Пример 03.007.02-2011.03
![Page 92: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/92.jpg)
Пример: отладка тестов
через mock-объекты
Пример 03.007.02-2011.02
Мок-объекты использованы для отладки самих тестов
![Page 93: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/93.jpg)
Пример: нагрузочные тесты
Пример 03.007.02-2011.05
![Page 94: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/94.jpg)
Идеи для применения mock
• Тестирование сложности алгоритмов
• Графический интерфейс
![Page 95: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/95.jpg)
Пример: тестирование
пользовательского интерфейса
Puppeteer, Вальтер Антон (http://blogr.avalter.net/2009/06/puppeteer.html)
• АОП или использование aссessors
• Требует написания кода для обработки элементарных типов пользовательского интерфейса
![Page 96: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/96.jpg)
[PuppetMethod("Click",typeof(ClickParamCreator))]
private void button1_Click_1(object sender, EventArgs e)
{ //.....
}
public class ClickParamCreator : Puppeteer.IParamsCreator { public object[] CreateParams(Dictionary<string,string> parameters)
{ object[] res = new object[2]; res[0] = null; res[1] = new EventArgs(); return res; } }
![Page 97: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/97.jpg)
public partial class Form1 : Form
{ // ............ [PuppetChild("TextBox")] [ReflectedPuppetProperty("Text","Text",typeof(SingleStringParamCreator))] private System.Windows.Forms.TextBox textBox1; // ............
}
![Page 98: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/98.jpg)
Puppeteer.Puppeteer puppeteer = new Puppeteer.Puppeteer();
puppeteer.LoadApplication(PathToExe); ITestAction action = new Puppeteer.Actions.Action(new SetProperty("Name", "Text", "Иванов Иван action.PreConditions.Add(new AssertEqual(new GetProperty("Name", "Text"), "")); action.PostConditions.Add(new AssertEqual(new GetProperty("Name", "Text"), "Иванов Иван")); puppeteer.AddAction(action);
action = new Puppeteer.Actions.Action(new SetProperty("EMail", "Text", "[email protected]")); action.PreConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "")); action.PostConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "[email protected]")); puppeteer.AddAction(action); action = new Puppeteer.Actions.Action(new SetProperty("Private", "Selected", true.ToString())); action.PostConditions.Add(new AssertEqual(new GetProperty("Private", "Selected"), true.ToString())); puppeteer.AddAction(action); action = new Puppeteer.Actions.Action(new InvokeMethod("Main", "Click"));
action.PreConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "[email protected]")); action.PreConditions.Add(new AssertEqual(new GetProperty("Name", "Text"), "Иванов Иван")); action.PreConditions.Add(new AssertEqual(new GetProperty("Private", "Selected"), true.ToString())); action.PostConditions.Add(new AssertEqual(new GetProperty("List", "Items", 0), "[P] Иванов Иван [email protected]")); puppeteer.AddAction(action);
![Page 99: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/99.jpg)
puppeteer.Run(new Dictionary<string, string>());
textBox1.Text = puppeteer.Result;
PuppetHolder.Clear();
![Page 100: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/100.jpg)
Пример: тестирование
сложности алгоритмов
Пример 03.007.02-2011.04
![Page 101: ук 03.007.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022052901/55669e32d8b42acd288b47e9/html5/thumbnails/101.jpg)
LOGO hwdtech.com