ук 03.007.02 2011

Тестирование

Части I, II, III

LOGO
УК 03.007.02-2011

hwdtech.com
Цели тестирования
Зачем тестирование нужно?

1

Полностью протестировать любую программу.

2
Тестирование позволит убедиться, что программа
работает правильно.

3
Тестировщик должен гарантировать правильность
выполнения программы.
Это были самые
распространенные
заблуждения о тестировании

Разберемся с ними подробнее…
Стандартные возражения
Почему программисты вообще делают ошибки? Пусть они их
не делают.
Сначала все напишем по-быстрому, а потом поправим все
ошибки.
Сколько ошибок мы нашли? N – это много или мало?
Почему наши пользователи находят ошибки, если мы
потратили на тестирование столько времени?!
Мы нашли N ошибок – мы можем остановить тестирование?
А как будет себя вести наше приложение в эксплуатации?
Заблуждения – это реакция на неудовлетворительные
ответы на данные вопросы.
Полностью протестировать любую
программу невозможно
• Проверить реакцию программы на каждую комбинацию
входных данных
– Есть корректные и некорректные входные данные

• Проверить каждую возможную последовательность
выполнения команд программы
– Мейерс, 1979
Написал программу из 100 строк, имеющую 108
последовательностей выполнения
Тестирование позволит убедиться,
что программа работает правильно
• Правильность программы нельзя доказать логически
– Можно проверить только соответствие спецификации
Тестировщик должен гарантировать
правильность выполнения
программы
• 40-80% времени тратится на исправление ошибок
• 1,5 ошибки на один оператор программы
• Тестировщик тоже человек!
Обсуждение
Ваши версии – зачем нужно тестирование?
Качество
Что такое качество?
• Качество ≠ отсутствие ошибок
В самом качественном автомобиле 2010 года выявляется в среднем 59
дефектов на 100 автомобилей в первые 90 дней.

• Удовлетворенность заказчика?
Пациент, которому действия доктора причиняют боль.

• Соответствие ожиданиям: делает то, что должен, не
делает того, что не должен
Определение качества
ISO 9126
Качество ПО – совокупная характеристика ПО с учетом
следующих составляющих:
–
–
–
–
–
–

Надежность
Сопровождаемость
Практичность
Эффективность
Мобильность
Функциональность
Определение качества
Надежность – набор атрибутов, относящихся к способности
ПО сохранять свой уровень качества функционирования в
установленных условиях за определенный период
времени
• Уровень завершенности
(отсутствие ошибок)
• Устойчивость к дефектам
• Восстанавливаемость
• Доступность
• Готовность
Определение качества
Мобильность — набор атрибутов, относящихся к
способности ПО быть перенесенным из одного окружения
в другое
• Адаптируемость
• Простота установки
• Сосуществование
• Замещаемость
Определение качества
Сопровождаемость - набор атрибутов, относящихся к
объему работ, требуемых для проведения конкретных
изменений (модификаций)
• Удобство анализа
• Изменяемость
• Стабильность
• Тестируемость
Определение качества
Практичность (применимость) — набор атрибутов,
относящихся к объему работ, требуемых для исполнения
и индивидуальной оценки такого исполнения
определенным или предполагаемым кругом
пользователей
• Понятность
• Простота использования
• Изучаемость
• Привлекательность
Определение качества
Эффективность — набор атрибутов, относящихся к
соотношению между уровнем качества
функционирования ПО и объемом используемых ресурсов
при установленных условиях
• Временная эффективность
• Используемость ресурсов
Определение качества
Функциональность — набор атрибутов характеризующий,
соответствие функциональных возможностей ПО набору
требуемой пользователем функциональности
• Пригодность к применению
• Корректность
• Способность к взаимодействию
• Защищенность
Как получается Качество ПО
• Качество ПО зависит только от качества его процесса
разработки
• Качество процесса разработки зависит только от культуры
разработки самой проектной команды
Определение тестирования
Тестирование ПО - процесс исследования программного
обеспечения (ПО) с целью получения информации о
качестве продукта.
(Толковый словарь)
Дефект - изъян, порча, повреждение; недостаток,
несовершенство.
Влияние дефектов
PMBOK
Влияние дефектов
Водопадная модель
Влияние дефектов
По виду артефактов
Влияние дефектов
Итеративная модель (снижение рисков)
Влияние дефектов
С точки зрения управление рисками
Влияние дефектов
С точки зрения размера проекта (Панкратов В.)
Влияние дефектов
По степени автоматизации действий
Соберем идеи
• Тестирование ПО больше, чем просто поиск дефектов!!!
• Тестирование – это часть процесса разработки, которое
занимает 40-80% всего процесса разработки и стоит 3050% от общей стоимости проекта
• Тестирование не только может выявлять дефекты, но и
предотвращать их.
• Эффективность тестирования сильно влияет на стоимость
проекта и сроки его завершения.
• Отказ от тестирования – это стратегия пассивного
принятия рисков.
• Автоматизация тестирования должна приводить к
снижению расходов на тестирование.
Классификация видов
тестирования
По объекту тестирования:
• Функциональное тестирование
• Тестирование производительности
– Нагрузочное тестирование
– Тестирование стабильности
– Стресс-тестирование

•
•
•
•
•

Тестирование удобства использования
Тестирование интерфейса пользователя
Тестирование безопасности
Тестирование локализации
Тестирование совместимости
По знанию системы:
• Тестирование белого ящика
– Соответствие кода соглашениям по наименованию и по
кодированию
– Корректная обработка ошибок
– Выделение памяти
– Покрытие кода: все ли операторы были выполнены хотя бы один
раз
– Проверка всех путей управления модуля

• Тестирование черного ящика
• Тестирование серого ящика
По степени автоматизации:
• Ручное тестирование
• Автоматизированное тестирование
• Полуавтоматизированное тестирование
По степени автоматизации:
• Ручное тестирование
• Автоматизированное тестирование
• Полуавтоматизированное тестирование
По степени изолированности системы:
• Модульное тестирование
• Интеграционное тестирование
• Системное тестирование
По степени позитивности сценариев:
• Позитивное тестирование
• Негативное тестирование
По степени подготовленности к тестированию:
• Тестирование по документации (формальное
тестирование)
• Тестирование как есть (интуитивное тестирование)
По времени проведения тестирования:
• Альфа-тестирование
–
–
–
–

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

• Бета-тестирование
• Приемочное тестирование
Логика Хоара
• Контрактная модель программирования
• Используется для доказательства частичной и полной
корректности компьютерных программ
• Тройка Хоара {pred} statement {post}, где pred, post –
утверждения (assertions), pred – предусловие, post постусловие, statement – оператор языка программирования
Пример:
{x+1 == 43} y=x+1; {y == 43 ^ x == 42}
• Логика Хоара определяет аксиомы и правила вывода для
императивного языка программирования
(http://ru.wikipedia.org/wiki/Логика_Хоара)
Правила Логики Хоара
Аксиома пустого оператора
{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}
От формальной системы к
автоматическому тестированию

• Все последовательности операторов протестировать
невозможно
• Часто тестирование – это многократно повторяющиеся
рутинные действия
• Человек преимущественно необходим только на этапе
оценки результатов, выданных ПО, на их соответствие
требованиям заказчика.
• Часто проверку результатов на соответствие требованиям
заказчика также можно автоматизировать.
Разминка
Соберите фигуру на слайде
Модульное (юнит)
тестирование
• С помощью правила композиции и/или правила вывода
объединяем несколько операторов в один общий блок.
Проверка предусловия и постусловия для блока
операторов равносильна проверке пост- и предусловий
каждого из операторов в этом блоке.
Пример:
{x + 1 ==43 } y = x + 1; {y == 43}
{y == 43} z = y; {z == 43}
По правилу композиции
{x + 1 == 43} y = x + 1; z = y; {z == 43}
• Какие границы блоков удобнее выбирать для целей
тестирования?
– Методы (см. Контрактная модель программирования)
{pred} void f(object arg1)… {post}
– Классы (как контейнер методов)

• Часто при разработке кода делаются неявные
предположения о состоянии программы (Asserts)
Исследования: На каждые 5-6 строк делается как минимум одно
неявное предположение о состоянии программы

Вывод: Рекомендация по рефакторингу – методы должны
быть короткими (5-7 строк)
Следствия
• Пишутся на том же языке, что и тестируемая процедура или класс
• Юнит-тесты должны быть простыми!!!
Плюсы
• Стимулируют рефакторинг
• Поощряют написание слабосвязанного кода
• Упрощают регрессионное тестирование
• Юнит-тесты = документация
Ограничения
• Не проверяют взаимодействие компонентов
• Не дают 100% гарантии
• Сложно покрывать тестами уже написанное приложение
Интеграционное тестирование с
точки зрения автоматизации
• Есть несколько методов, каждый из которых покрыт
тестами
• Эти методы используются для реализации функции
верхнего уровня
• Покрытие тестами этой функции и есть интеграционное
тестирование
Замечание: Покрытие тестами только
верхнеуровневой функции не
принесет много пользы, т.к. не
проведено модульное тестирование
самой функции, а значит нет
возможности локализовать ошибку
Критерий остановки
• На один метод как правило пишется несколько тестов
Когда пора остановиться?
Варианты:
• По времени – очень плохой критерий
• Вычислять коэффициент покрытия кода – не всегда есть
под рукой инструменты для вычисления покрытия кода,
нет 100% гарантии
• Test Driven Development
Test-Driven Development
Написание
тестов

Рефакторинг

Тесты не
компилируются

Определение
интерфейсов

Тесты проходят

Написание кода

Тесты не
проходят
Разминка
Загадано слово.
Можно задавать вопросы только с ответами да/нет.
Угадайте за минимальное количество вопросов.
Критерий “хорошего” теста
• Существует обоснованная вероятность выявления тестом
ошибки
• Набор тестов не должен быть избыточным
• Тест должен быть наилучшим в своей категории
• Не должен быть слишком простым и слишком сложным
Разработка тестов
•
•
•
•

Классы эквивалентности
Граничные условия
Stubs
Mocks
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);
}
}
junit.framework.Assert
• assertEquals
• assertFalse
• assertNotNull
• assertNull
• assertNotSame
• assertSame
• assertTrue
Классы эквивалентности
Если при выполнении двух тестов ожидается один и тот же
результат, то они считаются эквивалентными.
Группа тестов представляет собой класс эквивалентности,
если:
Классы эквивалентности
• Все тесты предназначены для выявления одной и той же
ошибки
• Если один из тестов выявит ошибку, то остальные скорее
всего тоже это сделают
• Если один из тестов не выявит ошибки, то остальные
скорее всего тоже этого не сделают
Классы экивалентности
• Тесты включают значения одних и тех же входных данных
• Для их проведения выполняются одни и те же операции
• В результате тестов формируются значения одних и тех же
выходных данных
• Либо не один из тестов не вызывает обработку ошибок в
программе, либо всеми тестами вызывается одна и та же
обработка ошибок
Пример классов
эквивалентности
Решение квадратного уравнения в вещественных числах
Result SquareRoot(double a, double b, double c);
• Уравнение, имеющее решение в виде двух корней
кратности 1 – (1, -1, -2)
• Уравнение, имеющее решение в виде одного корня
кратности 2 – (1, 2, 1)
• Уравнение, не имеющее решений – (1, 0, 1)
• Коэффициент a = 0
Разминка
Определить класс эквивалентности
Способы выявления
классов эквивалентности
• Заведомо неверные или недопустимые данные
Пример: a = 0 с предыдущего слайда
• Диапазоны числовых значений
I. Для диапазона значений есть три недопустимых класса
экивалентности:
– Числа меньше диапазона
– Числа больше диапазона
– Нечисловые данные
Замечание: Иногда некоторые из этих классов могут отсутствовать,
например, нет ограничения сверху. Лучше явно убедиться, что
этого ограничения нет, взяв очень большое число.
II. Поддиапазоны, например, 1-5, 9, 10, 12, 14, 16 – этажность зданий
• Фиксированные перечни значений
– Все значения данного перечня
– Любое значение, не входящее в перечень
Например, улицы г. Омска
Идеи для поиска классов эквивалентности
– Аббревиатуры
– Сокращения
– Ошибки при написании
– Старые названия
• Списки меню, выбора
Любой элемент меню может представлять отдельный класс
эквивалентности

• Переменные, значения которых должны быть равными
Значения, которые являются приемлемыми, но не принимаются в
данном месте программы, образуют отдельные эквивалентности
Пример: дата 13-07-2011, 07-13-2011, 13.07.2011, 13/07/2011 числа с
плавающей точкой 12,43 12.43
• Значения, зависящие от времени
Пример: запрос серверу, когда
– Ничего не обрабатывается
– Идет обработка другого запроса
– Сразу после завершения обработки другого запроса

• Группы переменных, результат которых ограничивается
определенным набором или диапазоном значений
Пример: квадратное уравнение
• Действия, на которые программа отвечает
эквивалентными событиями
Пример, обработка ошибок

• Различные варианты окружения
Пример, объем оперативный памяти:
– Проектный
– Недостаточный
– Больше, чем проектный
Граничные условия
• Для каждого класса эквивалентности нужно провести
минимальное число тестов
Следовательно: Лучшие тесты – те, которые лежат на границах
классов эквивалентности
Пример, для квадратного уравнения лучше брать не 0, а число, чуть
меньше “эпсилон”
Разминка
“Самолетики”
Stubs
Зависимость – это объект системы, с котором
взаимодействует тестируемый код и над которым нет
контроля у разработчика тестов.
Примеры:
– Объекты операционной системы
– Объекты, разработка которых еще не была завершена/начата
– Сторонние библиотеки

Заглушка – контролируемая замена зависимости в
разрабатываемой системе
Когда применяются
заглушки
• Создать имитацию загрузки или ограниченности ресурсов
• Создать имитацию сбоя в системе
• Выполнить тестирование, когда зависимость еще не
реализована
• Гарантировать отсутствие влияния зависимости на
результаты тестирования
• Отладка тестов для фасада
Идеи по реализации
заглушек
• Заглушка имитирует поведение реального объекта –
применяем паттерн Прокси
• Код должен, использующий базовый интерфейс для
Заглушек и реальных объектов, должен удовлетворять
принципу подстановки Лисков
• Тестируемые классы должны либо конфигурироваться
интерфейсами, либо использовать фабрики
Mocks
Тестирование основанное на состояниях (традиционный
подход)
Недостатки:
– Требует знания о внутреннем состоянии объекта –возможно
нарушение инкапсуляции
– Нарушает принципы ООП
Тестирование основанное на поведении – сосредоточено на
том, какие методы вызываются, в какой
последовательности, какие результаты выдают
Поведенческое тестирование – тестирование того, как
объект взаимодействует с другими объектами, то
есть посылает выходные данные и принимает входные
от других объектов.
Mock-объект – прокси-объект, который определяет
прошел ли тестируемый объект тест или нет
Различие между Stub и Mock:
• Stub подменяет реальный объект с целью имитации
реального функционала
• Mock подменяет реальный объект с целью оценки
правильности взаимодействия тестируемого объекта с
подменяемым.
Подходы к реализации mock
• Proxy (easymock, jmock, moq, rhino.mocks)
• Подгрузка класса mock объекта вместо реального класса
(jmockit, powermock, DI контейнеры)
Библиотека EasyMock
IFoo mock = EasyMock.createMock(IFoo.class);
EasyMock.expect(mock.doSomething(“argument”)).andReturn(t
rue);
EasyMock.replay(mock);
bool result = test.perform();
EasyMock.verify(mock);
Проверка поведения метода
•
•
•
•
•

andExpectThrow(exception)
ExpectLastCall();
times(min, max)
AnyTimes()
AtLeastOnce()
Параметры метода
•
•
•
•
•
•
•

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);
Пример теста
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);
}
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);
}
}
Библиотека 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);
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);
7. Возврат разных значений на каждый вызов функции
var mock = new Mock<IFoo>();
var calls = 0;
mock.Setup(foo => foo.GetCountThing())
.Returns(() => calls)
.Callback(() => calls++);
Console.WriteLine(mock.Object.GetCountThing());
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");
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");
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));
mock.Setup(foo => foo.Execute("ping"))
.Callback(() => Console.WriteLine("Before returns"))
.Returns(true)
.Callback(() => Console.WriteLine("After returns"));
Проверки
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());
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));
Пример: восстановление
пароля – шаг 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);
}
Пример: восстановление
пароля – шаг 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);
}
Пример: восстановление
пароля – шаг 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);
}
Пример: восстановление
пароля – шаг 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");
}
Пример: заглушка для еще
не написанного объекта
Interface IUserStorage
{
bool Save(User user);
bool Connect(string userName);
}
Пример: заглушка для еще
не написанного объекта
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);
}
Пример тестирования через
mock-объект
Пример 03.007.02-2011.01
Пример: модульное
тестирование
Пример 03.007.02-2011.03
Пример: отладка тестов
через mock-объекты
Пример 03.007.02-2011.02
Мок-объекты использованы для отладки самих тестов
Пример: нагрузочные тесты
Пример 03.007.02-2011.05
Идеи для применения mock
• Тестирование сложности алгоритмов
• Графический интерфейс
Пример: тестирование
пользовательского интерфейса
Puppeteer, Вальтер Антон
(http://blogr.avalter.net/2009/06/puppeteer.html)
• АОП или использование aссessors
• Требует написания кода для обработки элементарных
типов пользовательского интерфейса
[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;
}
}
public partial class Form1 : Form
{
// ............
[PuppetChild("TextBox")]
[ReflectedPuppetProperty("Text","Text",typeof(SingleStringParamCreator))]
private System.Windows.Forms.TextBox textBox1;
// ............
}
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", "name@mail.com"));
action.PreConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), ""));
action.PostConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "name@mail.com"));
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"), "name@mail.com"));
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] Иванов Иван name@mail.com"));
puppeteer.AddAction(action);
puppeteer.Run(new Dictionary<string, string>());
textBox1.Text = puppeteer.Result;
PuppetHolder.Clear();
Пример: тестирование
сложности алгоритмов
Пример 03.007.02-2011.04
LOGO
hwdtech.com
1 von 101

Recomendados

Тестирование ПО von
Тестирование ПОТестирование ПО
Тестирование ПОseleznev_stas
1.9K views15 Folien
технология и отладка по (47) von
технология и отладка по (47)технология и отладка по (47)
технология и отладка по (47)romachka_pole
449 views23 Folien
Continious integration-Automated Testing-Solid-Agile von
Continious integration-Automated Testing-Solid-AgileContinious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileKairat Yussupov
412 views25 Folien
Unit testing von
Unit testingUnit testing
Unit testingISsoft
593 views10 Folien
JavaTalks.Unit Testing.Part 1 von
JavaTalks.Unit Testing.Part 1JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1sgdread
1K views30 Folien
Управление конфигурациями и артефакты тестирования von
Управление конфигурациями и артефакты тестированияУправление конфигурациями и артефакты тестирования
Управление конфигурациями и артефакты тестированияSQALab
1.2K views21 Folien

Más contenido relacionado

Was ist angesagt?

QA Fest 2016. Андрей Мясников. Тест-дизайн для чайников von
QA Fest 2016. Андрей Мясников. Тест-дизайн для чайниковQA Fest 2016. Андрей Мясников. Тест-дизайн для чайников
QA Fest 2016. Андрей Мясников. Тест-дизайн для чайниковQAFest
3.4K views44 Folien
Тестирование ПО (лекция 2) von
Тестирование ПО (лекция 2)Тестирование ПО (лекция 2)
Тестирование ПО (лекция 2)Igor Khmelnytskyy
1.1K views21 Folien
Unit testing best practices von
Unit testing best practicesUnit testing best practices
Unit testing best practicesAlexander Masalov
785 views41 Folien
Тестирование ПО (лекция 1) von
Тестирование ПО (лекция 1)Тестирование ПО (лекция 1)
Тестирование ПО (лекция 1)Igor Khmelnytskyy
880 views21 Folien
3 лекция. презентация von
3 лекция. презентация3 лекция. презентация
3 лекция. презентацияvyacheslavmaslov
352 views21 Folien
02-lection-ka von
02-lection-ka02-lection-ka
02-lection-kavyacheslavmaslov
742 views22 Folien

Was ist angesagt?(18)

QA Fest 2016. Андрей Мясников. Тест-дизайн для чайников von QAFest
QA Fest 2016. Андрей Мясников. Тест-дизайн для чайниковQA Fest 2016. Андрей Мясников. Тест-дизайн для чайников
QA Fest 2016. Андрей Мясников. Тест-дизайн для чайников
QAFest3.4K views
Тестирование ПО (лекция 2) von Igor Khmelnytskyy
Тестирование ПО (лекция 2)Тестирование ПО (лекция 2)
Тестирование ПО (лекция 2)
Igor Khmelnytskyy1.1K views
Тестирование ПО (лекция 1) von Igor Khmelnytskyy
Тестирование ПО (лекция 1)Тестирование ПО (лекция 1)
Тестирование ПО (лекция 1)
Igor Khmelnytskyy880 views
3 лекция. презентация von vyacheslavmaslov
3 лекция. презентация3 лекция. презентация
3 лекция. презентация
vyacheslavmaslov352 views
Александр Александров -- Надёжный тест-дизайн (мастер-класс) von sqadays8
Александр Александров -- Надёжный тест-дизайн (мастер-класс)Александр Александров -- Надёжный тест-дизайн (мастер-класс)
Александр Александров -- Надёжный тест-дизайн (мастер-класс)
sqadays810.9K views
Андрей Сильчук: "Автоматическое тестирование". von Hub-IT-School
Андрей Сильчук: "Автоматическое тестирование".Андрей Сильчук: "Автоматическое тестирование".
Андрей Сильчук: "Автоматическое тестирование".
Hub-IT-School524 views
Тестирование ПО (лекция 3) von Igor Khmelnytskyy
Тестирование ПО (лекция 3)Тестирование ПО (лекция 3)
Тестирование ПО (лекция 3)
Igor Khmelnytskyy377 views
Сергей Семашко "End to end test: cheap and effective" von EPAM Systems
Сергей Семашко "End to end test: cheap and effective"Сергей Семашко "End to end test: cheap and effective"
Сергей Семашко "End to end test: cheap and effective"
EPAM Systems4.2K views
Модульное тестирование. von Unguryan Vitaliy
Модульное тестирование. Модульное тестирование.
Модульное тестирование.
Unguryan Vitaliy4.9K views
Тестирование весна 2013 лекция 2 von Technopark
Тестирование весна 2013 лекция 2Тестирование весна 2013 лекция 2
Тестирование весна 2013 лекция 2
Technopark966 views
Тестирование весна 2013 лекция 5 von Technopark
Тестирование весна 2013 лекция 5Тестирование весна 2013 лекция 5
Тестирование весна 2013 лекция 5
Technopark438 views
TAP von miraj84
TAPTAP
TAP
miraj84468 views
Разработка через тестирование (TDD и BDD) von Vyacheslav Lyalkin
Разработка через тестирование (TDD и BDD)Разработка через тестирование (TDD и BDD)
Разработка через тестирование (TDD и BDD)
тестирование по стратегии черного ящика von vyacheslavmaslov
тестирование по стратегии черного ящикатестирование по стратегии черного ящика
тестирование по стратегии черного ящика
vyacheslavmaslov1.9K views

Destacado

ЮНИТЕСТ. Нагрузочное тестирование von
ЮНИТЕСТ. Нагрузочное тестированиеЮНИТЕСТ. Нагрузочное тестирование
ЮНИТЕСТ. Нагрузочное тестированиеUNITEST.BIZ
845 views19 Folien
Тестирование весна 2013 лекция 1 von
Тестирование весна 2013 лекция 1Тестирование весна 2013 лекция 1
Тестирование весна 2013 лекция 1Technopark
815 views55 Folien
Тестирование в диджитал проектах von
Тестирование в диджитал проектахТестирование в диджитал проектах
Тестирование в диджитал проектахАндрей Медведев
578 views35 Folien
Разработка через приемочное тестирование с FIT von
Разработка через приемочное тестирование с FITРазработка через приемочное тестирование с FIT
Разработка через приемочное тестирование с FITDmitry Lobasev
1.1K views21 Folien
Паззл целей. Как найти потерянные фрагменты? von
Паззл целей. Как найти потерянные фрагменты?Паззл целей. Как найти потерянные фрагменты?
Паззл целей. Как найти потерянные фрагменты?Vladimir Zheleznyak
3.2K views20 Folien
О тестирование софта: мир качества, жуков и информации. Атрощенков Сергей. von
О тестирование софта: мир качества, жуков и информации.   Атрощенков Сергей.О тестирование софта: мир качества, жуков и информации.   Атрощенков Сергей.
О тестирование софта: мир качества, жуков и информации. Атрощенков Сергей.IT-Доминанта
11.4K views79 Folien

Destacado(7)

ЮНИТЕСТ. Нагрузочное тестирование von UNITEST.BIZ
ЮНИТЕСТ. Нагрузочное тестированиеЮНИТЕСТ. Нагрузочное тестирование
ЮНИТЕСТ. Нагрузочное тестирование
UNITEST.BIZ845 views
Тестирование весна 2013 лекция 1 von Technopark
Тестирование весна 2013 лекция 1Тестирование весна 2013 лекция 1
Тестирование весна 2013 лекция 1
Technopark815 views
Разработка через приемочное тестирование с FIT von Dmitry Lobasev
Разработка через приемочное тестирование с FITРазработка через приемочное тестирование с FIT
Разработка через приемочное тестирование с FIT
Dmitry Lobasev1.1K views
Паззл целей. Как найти потерянные фрагменты? von Vladimir Zheleznyak
Паззл целей. Как найти потерянные фрагменты?Паззл целей. Как найти потерянные фрагменты?
Паззл целей. Как найти потерянные фрагменты?
Vladimir Zheleznyak3.2K views
О тестирование софта: мир качества, жуков и информации. Атрощенков Сергей. von IT-Доминанта
О тестирование софта: мир качества, жуков и информации.   Атрощенков Сергей.О тестирование софта: мир качества, жуков и информации.   Атрощенков Сергей.
О тестирование софта: мир качества, жуков и информации. Атрощенков Сергей.
IT-Доминанта11.4K views
Black box techniques von QA Guards
Black box techniquesBlack box techniques
Black box techniques
QA Guards4.5K views

Similar a ук 03.007.02 2011

Надежный тест-дизайн von
Надежный тест-дизайнНадежный тест-дизайн
Надежный тест-дизайнSQALab
3.8K views31 Folien
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщика von
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщикаПромышленная разработка ПО. Лекция 5. Особенности работы тестировщика
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщикаMikhail Payson
1.2K views27 Folien
Mva stf module 2 - rus von
Mva stf module 2 - rusMva stf module 2 - rus
Mva stf module 2 - rusMaxim Shaptala
691 views39 Folien
3 лекция. презентация von
3 лекция. презентация3 лекция. презентация
3 лекция. презентацияvyacheslavmaslov
433 views21 Folien
Who is a functional tester von
Who is a functional testerWho is a functional tester
Who is a functional testerVitebsk Miniq
68 views30 Folien
Тимур Шевляков von
Тимур ШевляковТимур Шевляков
Тимур ШевляковCodeFest
519 views49 Folien

Similar a ук 03.007.02 2011(20)

Надежный тест-дизайн von SQALab
Надежный тест-дизайнНадежный тест-дизайн
Надежный тест-дизайн
SQALab3.8K views
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщика von Mikhail Payson
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщикаПромышленная разработка ПО. Лекция 5. Особенности работы тестировщика
Промышленная разработка ПО. Лекция 5. Особенности работы тестировщика
Mikhail Payson1.2K views
3 лекция. презентация von vyacheslavmaslov
3 лекция. презентация3 лекция. презентация
3 лекция. презентация
vyacheslavmaslov433 views
Тимур Шевляков von CodeFest
Тимур ШевляковТимур Шевляков
Тимур Шевляков
CodeFest519 views
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops von QAFest
QA Fes 2016. Анастасия Асеева. Роль тестирования в DevopsQA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QA Fes 2016. Анастасия Асеева. Роль тестирования в Devops
QAFest1.6K views
Сергей Ревко von SQALab
Сергей РевкоСергей Ревко
Сергей Ревко
SQALab393 views
тестирование по von Ion Griu
тестирование потестирование по
тестирование по
Ion Griu549 views
Марина Широчкина — «Тестирование» von Yandex
Марина Широчкина — «Тестирование»Марина Широчкина — «Тестирование»
Марина Широчкина — «Тестирование»
Yandex2.2K views
Tech Talks @NSU: Организация тестирования в IT-компаниях Академгородка. Карье... von Tech Talks @NSU
Tech Talks @NSU: Организация тестирования в IT-компаниях Академгородка. Карье...Tech Talks @NSU: Организация тестирования в IT-компаниях Академгородка. Карье...
Tech Talks @NSU: Организация тестирования в IT-компаниях Академгородка. Карье...
Tech Talks @NSU210 views
Модели в профессиональной инженерии и тестировании программ. Александр Петрен... von yaevents
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
yaevents1.9K views
Марина Широчкина - Тестирование von Yandex
Марина Широчкина - ТестированиеМарина Широчкина - Тестирование
Марина Широчкина - Тестирование
Yandex2.3K views
Викторина для тестировщиков von Uladzimir Kryvenka
Викторина для тестировщиковВикторина для тестировщиков
Викторина для тестировщиков
Uladzimir Kryvenka12.6K views
Test levels von QA Guards
Test levelsTest levels
Test levels
QA Guards864 views

Más de etyumentcev

Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016 von
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016etyumentcev
750 views21 Folien
Платформа SmartActors von
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActorsetyumentcev
424 views22 Folien
Как жить в согласии с SOLID? von
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?etyumentcev
1.1K views45 Folien
Программирование глазами математика von
Программирование глазами математикаПрограммирование глазами математика
Программирование глазами математикаetyumentcev
736 views30 Folien
Большие данные: как могут навредить и ка могут помочь? von
Большие данные: как могут навредить и ка могут помочь?Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?etyumentcev
539 views22 Folien
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск... von
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...etyumentcev
3.1K views71 Folien

Más de etyumentcev(20)

Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016 von etyumentcev
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
etyumentcev750 views
Платформа SmartActors von etyumentcev
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActors
etyumentcev424 views
Как жить в согласии с SOLID? von etyumentcev
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
etyumentcev1.1K views
Программирование глазами математика von etyumentcev
Программирование глазами математикаПрограммирование глазами математика
Программирование глазами математика
etyumentcev736 views
Большие данные: как могут навредить и ка могут помочь? von etyumentcev
Большие данные: как могут навредить и ка могут помочь?Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?
etyumentcev539 views
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск... von etyumentcev
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
etyumentcev3.1K views
матлогика для программистов von etyumentcev
матлогика для программистовматлогика для программистов
матлогика для программистов
etyumentcev500 views
Математическое обоснование S.O.L.I.D принципов von etyumentcev
Математическое обоснование S.O.L.I.D принциповМатематическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принципов
etyumentcev1.7K views
Как 7 студентов и филолог делали сложный проект von etyumentcev
Как 7 студентов и филолог делали сложный проектКак 7 студентов и филолог делали сложный проект
Как 7 студентов и филолог делали сложный проект
etyumentcev1.2K views
разработка серверов и серверных приложений лекция №4 von etyumentcev
разработка серверов и серверных приложений лекция №4разработка серверов и серверных приложений лекция №4
разработка серверов и серверных приложений лекция №4
etyumentcev550 views
разработка серверов и серверных приложений лекция №3 von etyumentcev
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
etyumentcev419 views
разработка серверов и серверных приложений лекция №2 von etyumentcev
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
etyumentcev441 views
разработка серверов и серверных приложений лекция №1 von etyumentcev
разработка серверов и серверных приложений лекция №1разработка серверов и серверных приложений лекция №1
разработка серверов и серверных приложений лекция №1
etyumentcev812 views
высокопроизводиетльные системы без доп затрат von etyumentcev
высокопроизводиетльные системы без доп затратвысокопроизводиетльные системы без доп затрат
высокопроизводиетльные системы без доп затрат
etyumentcev673 views
зачем нужны системы управления проектами von etyumentcev
зачем нужны системы управления проектамизачем нужны системы управления проектами
зачем нужны системы управления проектами
etyumentcev1.1K views
введение в Sql von etyumentcev
введение в Sqlвведение в Sql
введение в Sql
etyumentcev818 views
почему буксует тайм менеджмент von etyumentcev
почему буксует тайм менеджментпочему буксует тайм менеджмент
почему буксует тайм менеджмент
etyumentcev554 views
ук 03.011.01 2011 von etyumentcev
ук 03.011.01 2011ук 03.011.01 2011
ук 03.011.01 2011
etyumentcev745 views
ук 03.010.01 2011 von etyumentcev
ук 03.010.01 2011ук 03.010.01 2011
ук 03.010.01 2011
etyumentcev733 views
ук 03.009.01 2011 von etyumentcev
ук 03.009.01 2011ук 03.009.01 2011
ук 03.009.01 2011
etyumentcev388 views

ук 03.007.02 2011

  • 1. Тестирование Части I, II, III LOGO УК 03.007.02-2011 hwdtech.com
  • 3. Зачем тестирование нужно? 1 Полностью протестировать любую программу. 2 Тестирование позволит убедиться, что программа работает правильно. 3 Тестировщик должен гарантировать правильность выполнения программы.
  • 5. Разберемся с ними подробнее…
  • 6. Стандартные возражения Почему программисты вообще делают ошибки? Пусть они их не делают. Сначала все напишем по-быстрому, а потом поправим все ошибки. Сколько ошибок мы нашли? N – это много или мало? Почему наши пользователи находят ошибки, если мы потратили на тестирование столько времени?! Мы нашли N ошибок – мы можем остановить тестирование? А как будет себя вести наше приложение в эксплуатации? Заблуждения – это реакция на неудовлетворительные ответы на данные вопросы.
  • 7. Полностью протестировать любую программу невозможно • Проверить реакцию программы на каждую комбинацию входных данных – Есть корректные и некорректные входные данные • Проверить каждую возможную последовательность выполнения команд программы – Мейерс, 1979 Написал программу из 100 строк, имеющую 108 последовательностей выполнения
  • 8. Тестирование позволит убедиться, что программа работает правильно • Правильность программы нельзя доказать логически – Можно проверить только соответствие спецификации
  • 9. Тестировщик должен гарантировать правильность выполнения программы • 40-80% времени тратится на исправление ошибок • 1,5 ошибки на один оператор программы • Тестировщик тоже человек!
  • 10. Обсуждение Ваши версии – зачем нужно тестирование?
  • 12. Что такое качество? • Качество ≠ отсутствие ошибок В самом качественном автомобиле 2010 года выявляется в среднем 59 дефектов на 100 автомобилей в первые 90 дней. • Удовлетворенность заказчика? Пациент, которому действия доктора причиняют боль. • Соответствие ожиданиям: делает то, что должен, не делает того, что не должен
  • 13. Определение качества ISO 9126 Качество ПО – совокупная характеристика ПО с учетом следующих составляющих: – – – – – – Надежность Сопровождаемость Практичность Эффективность Мобильность Функциональность
  • 14. Определение качества Надежность – набор атрибутов, относящихся к способности ПО сохранять свой уровень качества функционирования в установленных условиях за определенный период времени • Уровень завершенности (отсутствие ошибок) • Устойчивость к дефектам • Восстанавливаемость • Доступность • Готовность
  • 15. Определение качества Мобильность — набор атрибутов, относящихся к способности ПО быть перенесенным из одного окружения в другое • Адаптируемость • Простота установки • Сосуществование • Замещаемость
  • 16. Определение качества Сопровождаемость - набор атрибутов, относящихся к объему работ, требуемых для проведения конкретных изменений (модификаций) • Удобство анализа • Изменяемость • Стабильность • Тестируемость
  • 17. Определение качества Практичность (применимость) — набор атрибутов, относящихся к объему работ, требуемых для исполнения и индивидуальной оценки такого исполнения определенным или предполагаемым кругом пользователей • Понятность • Простота использования • Изучаемость • Привлекательность
  • 18. Определение качества Эффективность — набор атрибутов, относящихся к соотношению между уровнем качества функционирования ПО и объемом используемых ресурсов при установленных условиях • Временная эффективность • Используемость ресурсов
  • 19. Определение качества Функциональность — набор атрибутов характеризующий, соответствие функциональных возможностей ПО набору требуемой пользователем функциональности • Пригодность к применению • Корректность • Способность к взаимодействию • Защищенность
  • 20. Как получается Качество ПО • Качество ПО зависит только от качества его процесса разработки • Качество процесса разработки зависит только от культуры разработки самой проектной команды
  • 21. Определение тестирования Тестирование ПО - процесс исследования программного обеспечения (ПО) с целью получения информации о качестве продукта. (Толковый словарь) Дефект - изъян, порча, повреждение; недостаток, несовершенство.
  • 26. Влияние дефектов С точки зрения управление рисками
  • 27. Влияние дефектов С точки зрения размера проекта (Панкратов В.)
  • 28. Влияние дефектов По степени автоматизации действий
  • 29. Соберем идеи • Тестирование ПО больше, чем просто поиск дефектов!!! • Тестирование – это часть процесса разработки, которое занимает 40-80% всего процесса разработки и стоит 3050% от общей стоимости проекта • Тестирование не только может выявлять дефекты, но и предотвращать их. • Эффективность тестирования сильно влияет на стоимость проекта и сроки его завершения. • Отказ от тестирования – это стратегия пассивного принятия рисков. • Автоматизация тестирования должна приводить к снижению расходов на тестирование.
  • 30. Классификация видов тестирования По объекту тестирования: • Функциональное тестирование • Тестирование производительности – Нагрузочное тестирование – Тестирование стабильности – Стресс-тестирование • • • • • Тестирование удобства использования Тестирование интерфейса пользователя Тестирование безопасности Тестирование локализации Тестирование совместимости
  • 31. По знанию системы: • Тестирование белого ящика – Соответствие кода соглашениям по наименованию и по кодированию – Корректная обработка ошибок – Выделение памяти – Покрытие кода: все ли операторы были выполнены хотя бы один раз – Проверка всех путей управления модуля • Тестирование черного ящика • Тестирование серого ящика По степени автоматизации: • Ручное тестирование • Автоматизированное тестирование • Полуавтоматизированное тестирование
  • 32. По степени автоматизации: • Ручное тестирование • Автоматизированное тестирование • Полуавтоматизированное тестирование По степени изолированности системы: • Модульное тестирование • Интеграционное тестирование • Системное тестирование
  • 33. По степени позитивности сценариев: • Позитивное тестирование • Негативное тестирование По степени подготовленности к тестированию: • Тестирование по документации (формальное тестирование) • Тестирование как есть (интуитивное тестирование)
  • 34. По времени проведения тестирования: • Альфа-тестирование – – – – Тестирование при приемке Тестирование новой функциональности Регрессионное тестирование Тестирование при сдаче • Бета-тестирование • Приемочное тестирование
  • 35. Логика Хоара • Контрактная модель программирования • Используется для доказательства частичной и полной корректности компьютерных программ • Тройка Хоара {pred} statement {post}, где pred, post – утверждения (assertions), pred – предусловие, post постусловие, statement – оператор языка программирования Пример: {x+1 == 43} y=x+1; {y == 43 ^ x == 42} • Логика Хоара определяет аксиомы и правила вывода для императивного языка программирования (http://ru.wikipedia.org/wiki/Логика_Хоара)
  • 36. Правила Логики Хоара Аксиома пустого оператора {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}
  • 37. От формальной системы к автоматическому тестированию • Все последовательности операторов протестировать невозможно • Часто тестирование – это многократно повторяющиеся рутинные действия • Человек преимущественно необходим только на этапе оценки результатов, выданных ПО, на их соответствие требованиям заказчика. • Часто проверку результатов на соответствие требованиям заказчика также можно автоматизировать.
  • 39. Модульное (юнит) тестирование • С помощью правила композиции и/или правила вывода объединяем несколько операторов в один общий блок. Проверка предусловия и постусловия для блока операторов равносильна проверке пост- и предусловий каждого из операторов в этом блоке. Пример: {x + 1 ==43 } y = x + 1; {y == 43} {y == 43} z = y; {z == 43} По правилу композиции {x + 1 == 43} y = x + 1; z = y; {z == 43}
  • 40. • Какие границы блоков удобнее выбирать для целей тестирования? – Методы (см. Контрактная модель программирования) {pred} void f(object arg1)… {post} – Классы (как контейнер методов) • Часто при разработке кода делаются неявные предположения о состоянии программы (Asserts) Исследования: На каждые 5-6 строк делается как минимум одно неявное предположение о состоянии программы Вывод: Рекомендация по рефакторингу – методы должны быть короткими (5-7 строк)
  • 41. Следствия • Пишутся на том же языке, что и тестируемая процедура или класс • Юнит-тесты должны быть простыми!!! Плюсы • Стимулируют рефакторинг • Поощряют написание слабосвязанного кода • Упрощают регрессионное тестирование • Юнит-тесты = документация Ограничения • Не проверяют взаимодействие компонентов • Не дают 100% гарантии • Сложно покрывать тестами уже написанное приложение
  • 42. Интеграционное тестирование с точки зрения автоматизации • Есть несколько методов, каждый из которых покрыт тестами • Эти методы используются для реализации функции верхнего уровня • Покрытие тестами этой функции и есть интеграционное тестирование Замечание: Покрытие тестами только верхнеуровневой функции не принесет много пользы, т.к. не проведено модульное тестирование самой функции, а значит нет возможности локализовать ошибку
  • 43. Критерий остановки • На один метод как правило пишется несколько тестов Когда пора остановиться? Варианты: • По времени – очень плохой критерий • Вычислять коэффициент покрытия кода – не всегда есть под рукой инструменты для вычисления покрытия кода, нет 100% гарантии • Test Driven Development
  • 45. Разминка Загадано слово. Можно задавать вопросы только с ответами да/нет. Угадайте за минимальное количество вопросов.
  • 46. Критерий “хорошего” теста • Существует обоснованная вероятность выявления тестом ошибки • Набор тестов не должен быть избыточным • Тест должен быть наилучшим в своей категории • Не должен быть слишком простым и слишком сложным
  • 48. 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); } }
  • 49. junit.framework.Assert • assertEquals • assertFalse • assertNotNull • assertNull • assertNotSame • assertSame • assertTrue
  • 50. Классы эквивалентности Если при выполнении двух тестов ожидается один и тот же результат, то они считаются эквивалентными. Группа тестов представляет собой класс эквивалентности, если:
  • 51. Классы эквивалентности • Все тесты предназначены для выявления одной и той же ошибки • Если один из тестов выявит ошибку, то остальные скорее всего тоже это сделают • Если один из тестов не выявит ошибки, то остальные скорее всего тоже этого не сделают
  • 52. Классы экивалентности • Тесты включают значения одних и тех же входных данных • Для их проведения выполняются одни и те же операции • В результате тестов формируются значения одних и тех же выходных данных • Либо не один из тестов не вызывает обработку ошибок в программе, либо всеми тестами вызывается одна и та же обработка ошибок
  • 53. Пример классов эквивалентности Решение квадратного уравнения в вещественных числах Result SquareRoot(double a, double b, double c); • Уравнение, имеющее решение в виде двух корней кратности 1 – (1, -1, -2) • Уравнение, имеющее решение в виде одного корня кратности 2 – (1, 2, 1) • Уравнение, не имеющее решений – (1, 0, 1) • Коэффициент a = 0
  • 55. Способы выявления классов эквивалентности • Заведомо неверные или недопустимые данные Пример: a = 0 с предыдущего слайда
  • 56. • Диапазоны числовых значений I. Для диапазона значений есть три недопустимых класса экивалентности: – Числа меньше диапазона – Числа больше диапазона – Нечисловые данные Замечание: Иногда некоторые из этих классов могут отсутствовать, например, нет ограничения сверху. Лучше явно убедиться, что этого ограничения нет, взяв очень большое число. II. Поддиапазоны, например, 1-5, 9, 10, 12, 14, 16 – этажность зданий
  • 57. • Фиксированные перечни значений – Все значения данного перечня – Любое значение, не входящее в перечень Например, улицы г. Омска Идеи для поиска классов эквивалентности – Аббревиатуры – Сокращения – Ошибки при написании – Старые названия
  • 58. • Списки меню, выбора Любой элемент меню может представлять отдельный класс эквивалентности • Переменные, значения которых должны быть равными Значения, которые являются приемлемыми, но не принимаются в данном месте программы, образуют отдельные эквивалентности Пример: дата 13-07-2011, 07-13-2011, 13.07.2011, 13/07/2011 числа с плавающей точкой 12,43 12.43
  • 59. • Значения, зависящие от времени Пример: запрос серверу, когда – Ничего не обрабатывается – Идет обработка другого запроса – Сразу после завершения обработки другого запроса • Группы переменных, результат которых ограничивается определенным набором или диапазоном значений Пример: квадратное уравнение
  • 60. • Действия, на которые программа отвечает эквивалентными событиями Пример, обработка ошибок • Различные варианты окружения Пример, объем оперативный памяти: – Проектный – Недостаточный – Больше, чем проектный
  • 61. Граничные условия • Для каждого класса эквивалентности нужно провести минимальное число тестов Следовательно: Лучшие тесты – те, которые лежат на границах классов эквивалентности Пример, для квадратного уравнения лучше брать не 0, а число, чуть меньше “эпсилон”
  • 63. Stubs Зависимость – это объект системы, с котором взаимодействует тестируемый код и над которым нет контроля у разработчика тестов. Примеры: – Объекты операционной системы – Объекты, разработка которых еще не была завершена/начата – Сторонние библиотеки Заглушка – контролируемая замена зависимости в разрабатываемой системе
  • 64. Когда применяются заглушки • Создать имитацию загрузки или ограниченности ресурсов • Создать имитацию сбоя в системе • Выполнить тестирование, когда зависимость еще не реализована • Гарантировать отсутствие влияния зависимости на результаты тестирования • Отладка тестов для фасада
  • 65. Идеи по реализации заглушек • Заглушка имитирует поведение реального объекта – применяем паттерн Прокси • Код должен, использующий базовый интерфейс для Заглушек и реальных объектов, должен удовлетворять принципу подстановки Лисков • Тестируемые классы должны либо конфигурироваться интерфейсами, либо использовать фабрики
  • 66. Mocks Тестирование основанное на состояниях (традиционный подход) Недостатки: – Требует знания о внутреннем состоянии объекта –возможно нарушение инкапсуляции – Нарушает принципы ООП
  • 67. Тестирование основанное на поведении – сосредоточено на том, какие методы вызываются, в какой последовательности, какие результаты выдают Поведенческое тестирование – тестирование того, как объект взаимодействует с другими объектами, то есть посылает выходные данные и принимает входные от других объектов.
  • 68. Mock-объект – прокси-объект, который определяет прошел ли тестируемый объект тест или нет Различие между Stub и Mock: • Stub подменяет реальный объект с целью имитации реального функционала • Mock подменяет реальный объект с целью оценки правильности взаимодействия тестируемого объекта с подменяемым.
  • 69. Подходы к реализации mock • Proxy (easymock, jmock, moq, rhino.mocks) • Подгрузка класса mock объекта вместо реального класса (jmockit, powermock, DI контейнеры)
  • 70. Библиотека EasyMock IFoo mock = EasyMock.createMock(IFoo.class); EasyMock.expect(mock.doSomething(“argument”)).andReturn(t rue); EasyMock.replay(mock); bool result = test.perform(); EasyMock.verify(mock);
  • 72. Параметры метода • • • • • • • 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);
  • 73. Пример теста 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); }
  • 74. 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); } }
  • 75. Библиотека 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);
  • 76. 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);
  • 77. 7. Возврат разных значений на каждый вызов функции var mock = new Mock<IFoo>(); var calls = 0; mock.Setup(foo => foo.GetCountThing()) .Returns(() => calls) .Callback(() => calls++); Console.WriteLine(mock.Object.GetCountThing());
  • 78. 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");
  • 79. 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");
  • 80. 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));
  • 81. mock.Setup(foo => foo.Execute("ping")) .Callback(() => Console.WriteLine("Before returns")) .Returns(true) .Callback(() => Console.WriteLine("After returns"));
  • 82. Проверки 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());
  • 83. 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));
  • 84. Пример: восстановление пароля – шаг 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); }
  • 85. Пример: восстановление пароля – шаг 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); }
  • 86. Пример: восстановление пароля – шаг 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); }
  • 87. Пример: восстановление пароля – шаг 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"); }
  • 88. Пример: заглушка для еще не написанного объекта Interface IUserStorage { bool Save(User user); bool Connect(string userName); }
  • 89. Пример: заглушка для еще не написанного объекта 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); }
  • 92. Пример: отладка тестов через mock-объекты Пример 03.007.02-2011.02 Мок-объекты использованы для отладки самих тестов
  • 94. Идеи для применения mock • Тестирование сложности алгоритмов • Графический интерфейс
  • 95. Пример: тестирование пользовательского интерфейса Puppeteer, Вальтер Антон (http://blogr.avalter.net/2009/06/puppeteer.html) • АОП или использование aссessors • Требует написания кода для обработки элементарных типов пользовательского интерфейса
  • 96. [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; } }
  • 97. public partial class Form1 : Form { // ............ [PuppetChild("TextBox")] [ReflectedPuppetProperty("Text","Text",typeof(SingleStringParamCreator))] private System.Windows.Forms.TextBox textBox1; // ............ }
  • 98. 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", "name@mail.com")); action.PreConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "")); action.PostConditions.Add(new AssertEqual(new GetProperty("EMail", "Text"), "name@mail.com")); 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"), "name@mail.com")); 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] Иванов Иван name@mail.com")); puppeteer.AddAction(action);
  • 99. puppeteer.Run(new Dictionary<string, string>()); textBox1.Text = puppeteer.Result; PuppetHolder.Clear();