SlideShare ist ein Scribd-Unternehmen logo
1 von 65
Downloaden Sie, um offline zu lesen
xUnit – философия и основные правила
Александр Ярулин
• Модульный тест: «отделяем зерна от плевел»
• Немного истории
• Определение термина xUnit
• Основные идеи xUnit
• Различные реализации xUnit
• Область применимости xUnit
• Некоторые сценарии нетрадиционного
использования xUnit
О чем будем говорить…
Что такое модульный тест?
• код с определенной структурой, который проверяет
поведение одного класса или функции ( т.е. использует
внутренние интерфейсы приложения)
• написан на том же языке программирования
• пишется как правило самими разработчиками
Тест не модульный, если
• работает с реальной БД
• использует сеть
• работает с файловой системой
• воздействует на тестируемую систему (SUT)
через внешний интерфейс (API, GUI, сеть и
т.д.)
Для чего модульные тесты?
• повышение качества продукта
• предотвращение ошибок и их быстрое выявление
• изолированная проверка работоспособности внутренних модулей
для быстрой локализации дефектов
• понимание системы
• тесты как спецификация системы (напр. при TDD)
• тесты как документация
• снижение рисков
• быстрое выявление побочных эффектов изменений в коде
• безопасная работа с унаследованным кодом, который покрыт
модульными тестами
Каким должен быть идеальный unit-тест ?
• Самодостаточным (self-checking)
• Независимым (independent)
• Понятным (clear)
• Повторяемым (repeatable)
• Устойчивым (robust)
• Простым (simple)
• Легко запускаемым (easy running)
• Эффективным (efficient)
Вопросы…вопросы…
• как писать unit-тесты ?
• как упорядочивать unit-тесты ?
• как запускать unit-тесты ?
• как получать отчеты?
Немного истории
SetTestCase>>#testAdd
empty add: 5.
self should: [empty includes: 5]
@Test public void simpleAdd() {
int n1 = 3
int n2 = 2
expected = 6
assertTrue(expected == n1 + n2);
}
История от Мартина Фаулера 
Кент Бек, SmallTalk и SUnit
CppUnit и портирование на другие языки
JUnit (Кент Бек, Эрих Гамма)
Даем определение
xUnit – семейство инфраструктур автоматизации
тестирования (Testing Automation Framework),
реализующих общие принципы и предназначенных
для реализации созданных вручную тестов (Scripted
Test).
Синонимы термина Scripted Test:
• Hand-Written Test
• Hand-Scripted Test
• Programatic Test
• Automated Unit Test
Допустим «дуализм»
• xUnit как парадигма
• xUnit как семейство
фреймворков автоматизации
«Парадигма» - совокупность фундаментальных научных установок,
представлений и терминов, принимаемая и разделяемая научным
сообществом и объединяющая большинство его членов. (Wikipedia)
«Общие принципы»
• Тест – это тестовый метод (Test Method), реализующий 4-
х фазный тест (Four Phase Test)
• Объединение тестовых методов в классы (Tescase Class)
в коде
• Использование утверждений (Assertions) для проверки
поведения системы
• Объединение тестов в тестовые наборы (Test Suite) на
этапе выполнения
• Обнаружение (Test Discovery) или явное перечисление
(Test Enumeration) тестов
• Различные варианты запуска тестов (Test Running)
• Отчеты о результатах тестирования (Testing Report)
Применимость xUnit-фреймворков
• Модульные тесты (unit tests)
Небольшие, понятные и быстрые тесты с простой тестовой конфигурацией
• Интеграционные тесты (integration tests)
• ряд преимуществ может быть потерян
• эффективное использование также возможно
• самостоятельное или вместе Data Driven Testing (DDT)
4-х фазный тест (Four Phase Test)
• Настройка тестовой конфигурации (Setup)
• Действие с SUT (Exercise)
• Проверка корректности результата (Verify)
• Очистка (Teardown)
Цель: хранение тестовой логики
Реализация: метод класса , процедура или функция с тестовой логикой,
реализующая 4-фазный тест
Основные типы:
• тест ожидаемой успешности/не успешности (Simple Success Test)
• тесты на ожидаемые исключения (Expected Exception Test)
• тесты создания объектов / тесты конструкторов (Constructor Test)
Тестовый метод (Test Method)
• Нужен для проверки очевидных успешных сценариев
• Реализует классические 4 фазы
• Возможные исключения в тестовом методе не перехватываются
Простой тест успешности
(Simple Success Test)
class WindowTestCase(unittest.TestCase):
def test_default_dimension(self):
window = Window()
self.assertEqual(window.size(), (800, 600),
'incorrect default dimension')
• Проверка правильности обработки ошибок в SUT
• Только те исключения, которые приложение генерирует самостоятельно
Тест на ожидаемое исключение
class WindowTestCase(unittest.TestCase):
def test_size_exception(self):
window = Window(width=-100, height=100)
self.assertRaises(InputParamException, “bla”)
• Для локализации дефектов при создании объекта
• Проверка правильности создания объекта
• Проверяются все поля ( инициализируемые и неинициализируемые)
• Может быть сделан на основе теста успешности или теста на ожидаемое
исключение
Тест конструктора
class WindowTestCase(unittest.TestCase):
def test_window_ctor(self):
w = Window(width=100, height=200)
self.assertEqual(w.width, 100, ”incorrect width”)
self.assertEqual(w.height, 200, “incorrect height”)
self.assertNull(w.childs, “childs is not null”)
• класс, предназначенный для группировки одного или более тестовых методов
• создание объекта класса (Testcase object) для каждого тестового метода на
этапе выполнения
• объединение объектов класса в тестовые наборы (Test Suite) для запуска
специальной программой (Test Runner)
Класс теста (Testcase Class)
• То, во что превращается каждый тестовый метод на этапе выполнения
• У каждого объекта есть метод run для запуска теста
• У всех тестов единый интерфейс для программы запуска тестов
• Тесты изолированы друг от друга
Исключения
• NUnit
Объект теста (Testcase Object)
«…Я думаю, что самой большой ошибкой при написании Nunit был
отказ от создания нового экземпляра класса тестовой конфигурации
для каждого тестового метода …» Джеймс Ньюкирк , автор NUnit
• «Композитный тест», который содержит
коллекцию отдельных объектов тестов
(Testcase Object)
• У каждого объекта набора тестов (Test Suite
Object) есть метод run для запуска теста
• Для программы запуска тестов все равны
• Наборы наборов, наборы наборов наборов ….
Паттерн «Компоновщик» – позволяет
клиентам обращаться к отдельным объектам
и к группам объектов одинаково
Объект набора тестов (Test Suite Object)
Test Suite и TestCase в unittest
import unittest
class WidgetTestCase(unittest.TestCase):
def test_default_size(self):
#...
def test_resize(self):
#...
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_size'))
suite.addTest(WidgetTestCase('test_resize'))
suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
suite1 = module1.TheTestSuite()
suite2 = module2.TheTestSuite()
alltests = unittest.TestSuite([suite1, suite2])
• У каждой xUnit-реализации есть приложение для запуска тестов (Test Runner)
• Консольные
• GUI-шные
• Встраиваемые в IDE
• Должен уметь
• Обнаруживать и запускать тесты (Test Discovery)
• Обнаружение классов тестов
• Обнаружение тестовых методов
• Выводить информацию о результатах прогона (Test Report)
• Можно написать свой Test Runner
«Запускальщик» тестов (Test Runner)
Пример автотеста ( Python, unittest )
import random
import unittest
class TestRandom(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
python –m unittest discover –s ./tests/ -p “test*.py”
1. самостоятельный запуск
2. запуск средствами unittest (фактически аналогично п.1)
3. запуск определенного набора тестов
4. запуск единичного теста (тестового метода)
5. Test discovery
python –m unittest test.TestRandom.test_choice
python –m unittest test.TestRandom
python –m unittest test
./test.py
Некоторые варианты запуска
4-х фазный тест
Цели:
• подготовка тестового окружения, необходимого для проведения теста
Примеры:
• переменные окружения
• инициализация базы данных
• создание нужных файлов
• открытие сетевых соединений
• создание и инициализация объектов классов
• и так далее …
Настройка (Setup)
• Новая тестовая конфигурация (Fresh Fixture)
• Встроенная (In-line Setup)
• Делегированная (Delegated Setup)
• Метод создания (Creation Method)
• Неявная (Implicit setup)
• Общая тестовая конфигурация (Shared Fixture)
• Предварительная (Prebuild Fixture )
• «Ленивая» настройка (Lazy Setup)
• Конфигурация набора (Suite Fixture Setup)
• Цепочки тестов (Chained Tests)
Шаблоны настройки конфигурации
Встроенная настройка (In-line Setup)
Шаблоны настройки конфигурации
• Подходит для очень простых тестов
• Подходит на начальном этапе
• Часто является предметом рефакторинга
class InlineDemo(unittest.TestCase):
def test_one(self):
#inline setup
self.sut = Sut()
sut.setParam(1)
#exercise the sut
def test_two(self):
#inline setup
self.sut = Sut()
sut.setParam(2)
#exercise the sut
Делегированная настройка (Delegated Setup)
Шаблоны настройки конфигурации
• Избавление от дублирования похожего тестового кода
• Сохраняется понятность / читабельность теста
class DelegatedDemo(unittest.TestCase):
def test_one(self):
self.sut = create_the_sut()
#exercise the sut in test_one-way
def test_two(self):
self.sut = create_the_sut()
#exercise the sut in test_two-way
Неявная настройка (Implicit Setup)
Шаблоны настройки конфигурации
• setUp вызывается самим фреймворком перед запуском каждого теста
• Использовать для создания одинаковых данных
• Как правило сопровождается неявной очисткой (Implicit Teardown)
• Антипаттерн – сваливать в кучу общие и частные данные
class ImplicitDemo(unittest.TestCase):
def setUp(self):
self.common = CreateSmthCommon()
def test_one(self):
special = CreateSmthSpecial(self.common)
Предварительная конфигурация (Prebuilt Fixture)
Шаблоны настройки конфигурации
• Создается до запуска тестов
• Позволяет сокращать время прогона
• Сложно управлять с ростом конфигурации
• Риск неявного взаимовлияния тестов через данные
class PrebuiltDemo(unittest.TestCase):
def test_the_sut(self):
sut = findSUTInPrebuiltFixture()
#exercise with the sut
«Ленивая» настройка (Lazy Setup)
Шаблоны настройки конфигурации
• Создается первым же тестом, которому она нужна
• Экономия времени
• Непонятно, после какого теста надо чистить
• Использовать, когда очистка не обязательна
class LazySetupDemo(unittest.TestCase):
def setUp(self):
if self.sut:
return
self.sut = create_the_sut()
def test_the_sut(self):
#exercise with the SUT
Конфигурация набора (Suite Fixture Setup)
Шаблоны настройки конфигурации
• Конфигурация, общая для всех тестов класса
• Выигрыш во времени
• Риск появления взаимодействующих тестов (Interacting Tests)
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = new_connection()
#some test methods here
@classmethod
def tearDownClass(self):
cls._connection.destroy()
Цепочки тестов (Chained Tests)
Шаблоны настройки конфигурации
• Важен порядок тестов
• Тесты используют «остатки» предыдущих и экономят время
• Риск - меняем один тест, падают остальные
class Chain(unittest.TestCase):
def test_1(self):
obj = get_from_db()
#do something with obj
obj.store_into_db()
def test_2(self):
obj = get_from_db()
#use obj while testing
Действие (Exercise)
Цели:
• воздействие на тестируемый объект
Примеры:
• вызов тестируемых функций
• запуск тестируемых утилит ( ? )
• тестовое создание экземпляров объектов
• вызов api-методов ( ? )
• и так далее …
Проверка результатов (Verify)
Стратегии:
• Проверка состояния объекта (State Verification)
• Проверка поведения (Behavior Verification)
Методы с утверждениями :
• Специальное утверждение (Custom Assertion)
• Дельта-утверждение (Delta Assertion)
• Сторожевое утверждение (Guard Assertion)
• Утверждение незаконченного теста (Unfinished Test Assertion)
Проверка состояния (State Verification)
важно конечное состояние SUT, а
не то, как в него попали
def test_state(self):
expected = CatalogItem()
catalog.addItem(expected)
actual = catalog.get(0)
self.asserEqual(catalog.size(),1,”…”)
self.assertEqual(expected, actual)
Проверка поведения (Behavior Verification)
• DOC – Dependent On Component
• Нужен способ проверки
• Тестовые двойники (Test Double)
def test_behavior(self):
#setup
spy = DOCSpy()
sut = Sut(doc=spy)
#exercise
sut.do_smth_what_needs_DOC()
#verify
self.asserEqual(spy.numOfCalls,10,”…”)
#teardown doesn’t matter
Специальное утверждение (Custom Assertion)
def test_assert(self):
...
self.assertEqual(expected.field1,
actual.field1)
self.assertEqual(expected.field2,
actual.field2)
self.assertEqual(expected.field3,
actual.field3)
...
• cоздаем собственный assertion
• прячем в него повторяющиеся
проверки
• упрощаем код теста
def test_custom_assert(self):
...
assertEqualCustom(expected, actual)
...
Дельта утверждение
• Фиксируем состояние конфигурации
до теста
• Делаем проверки, отталкиваясь от
зафиксированного состояния
def test_conditional_logic(self):
objcount = fixture.get_objects_count()
# setup , … , teardown
assertEqual(objcount, fixture.get_objects_count())
Сторожевое утверждение (Guard Assertion)
• Для избавления от условной логики «if then
else fail»
• Это обычный assertion, но он не относится
напрямую к цели теста
• Используется как правило между setup и
exercise
def test_conditional_logic(self):
if(fixture.catalog):
#do some test
else:
self.fail()
def test_guard(self):
self.assertIsNotNone(fixture.catalog)
#do some test
Утверждение незаконченного теста
• «TODO» для автотестов
• Не доделанный тест должен фейлиться
class MyTestCase(unittest.TestCase):
def test_unfinished(self):
self.fail(“Why I Live???")
Утверждения(Assertions) в unittest
Method Checks that New in
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b 2.7
assertIsNot(a, b) a is not b 2.7
assertIsNone(x) x is None 2.7
assertIsNotNone(x) x is not None 2.7
assertIn(a, b) a in b 2.7
assertNotIn(a, b) a not in b 2.7
assertIsInstance(a, b) isinstance(a, b) 2.7
assertNotIsInstance(a, b) not isinstance(a, b) 2.7
Очистка (Teardown)
Цели:
• исключение возможности неявного влияния
тестов друг на друга и повышение их
повторяемости
• рациональное использование ресурсов системы
Примеры:
• закрытие файловых дескрипторов
• освобождение явно выделенной памяти
• закрытие сетевых соединений
• удаление «следов» в БД, файловой системе
• и так далее …
Шаблоны очистки
• Очистка со сборкой мусора (Garbage-Collected Teardown)
• Автоматическая очистка (Automated Teardown)
• Встроенная очистка (Inline Teardown)
• Неявная очистка (Implicit Teardown)
Изоляция проверяемой системы
Тестовые двойники (Test Double)
• предоставляет такой же интерфейс,
как настоящий компонент
• с фиксированным или настраиваемым
поведением
• позволяет покрыть больше кода
• позволяет бороться с медленными
тестами (Slow Test)
Основные типы
• Тестовая заглушка (Test Stub)
• Тестовый агент (Test Spy)
• Подставной объект (Mock Object)
Для чего?
Тестовая заглушка (Test Stub)
• возможность опосредованного ввода для
SUT
• помогает заставить SUT вести себя так, как
нам надо (покрывать нужные ветки кода)
Тестовый агент (Test Spy)
• опосредованный вывод - записывает
вызовы SUT
• используется с шаблоном «Проверка
поведения»
Подставной объект (Mock Object)
• настраивается значениями для передачи в
SUT, а также ожиданиями ответов от SUT
• cравнивает ответы от SUT с помощью
assertions
• в самом тесте утверждения не дублируются
• используется для проверки поведения SUT
• «строгий» и «нестрогий» подставной объект
и порядок вызовов от SUT
Пример xUnit для не unit-тестов
• тесты на модели (model)
• тесты на представления (view)
• тесты с реальным веб-сервером
• даже тесты на GUI
Пример теста на Django
class PollViewTests(TestCase):
def test_index_view_with_no_polls(self):
""" If no polls exist, an appropriate message should be displayed. """
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_poll_list'], [])
def test_index_view_with_a_past_poll(self):
""" Polls with a pub_date in the past should be displayed on index page. """
create_poll(question="Past poll.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual( response.context['latest_poll_list'], ['<Poll: Past
poll.>'] )
Еще один не-unit тест…
import unittest
class GoogleTestCase(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def testPageTitle(self):
self.browser.get('http://www.google.com')
self.assertIn('Google', self.browser.title)
def teardown(self):
self.browser.quit
if __name__ == '__main__':
unittest.main(verbosity=2)
Отчеты о тестировании и CI
• TAP (Test Anything Protocol) – отчеты
• JUnit – отчеты
• Произвольные форматы и конвертации
1..48
ok 1 Description # Directive
# Diagnostic
....
ok 47 Description
ok 48 Description
<testsuite tests="3">
<testcase classname="foo" name="ASuccessfulTest"/>
<testcase classname="foo" name="AnotherSuccessfulTest"/>
<testcase classname="foo" name="AFailingTest">
<failure type="NotEnoughFoo">
details about failure
</failure>
</testcase>
</testsuite>
Признаки плохих тестов (Test Smells)
• непонятный тест (Obscure Test)
• хрупкий тест (Fragile Test)
• условная логика в тесте (Conditional test logic)
• дублирование кода (Test Code Duplication)
• медленные тесты (Slow Tests)
• беспорядочный тест (Erratic test)
Непонятный тест (Obscure Test)
• Сложно понять, что делает тест
• Сложно его поддерживать
Возможные причины Возможные решения
Тест делает много лишнего • Оставить только то, что непосредственно
относится к цели теста.
• Декомпозиция теста
Запутанная логика создания ,
взаимодействия с SUT или проверки
• Разработка теста «от общего к частному»
• Использование вспомогательных методов,
специальных утверждений,
делегированной настройки
Хрупкий тест (Fragile Test)
• Тест «падает» от несвязанных с ним изменений в SUT
• Больше анализа тестов – выше трудоемкость поддержки
Возможные причины Возможные решения
Изменился код, используемый для создания,
проверки или очистки
Использовать методы создания, специальные
утверждения, хелперы
Неожиданные изменения в данных.
Например, действия одного теста «сломали»
данные другого
Минимизация влияния тестов друг на друга.
Например Fresh Fixture.
Зависимость от контекста. Например,
результаты зависят от даты или длины
текущего месяца.
Решается в каждом конкретном случае по-
особому.
Пример (Oracle):
ALTER SYSTEM SET fixed_date = '2011-12-31
23:59:59‘;
ALTER SYSTEM SET fixed_date=NONE.
Условная логика теста (Conditional Test Logic)
• Сложнее отладка самого теста
• Непонятный тест
Возможные причины Возможные решения
«Гибкий тест» – проверяет разное и по-разному в
зависимости от внешних условий
• Изоляция SUT
• Декомпозиция теста
If then else • Сторожевые утверждения
• Специальные утверждения
Сложная очистка • Неявная очистка
• Автоматическая очистка
Дублирование кода (Test Code Duplication)
• Сложность и дороговизна поддержки системы
автотестов
• Дополнительный рефакторинг
Возможные причины Возможные решения
Copy - Paste «Лучше день потерять, зато потом…» (с) м/ф
«Крылья, ноги и хвосты»
Изобретение велосипеда. Например,
параллельная реализация кучи одинаковых в
общем-то хелперов, библиотек и т.д.
• Ревью
• Анализ того, что «велосипед уже есть»
Медленный тест (Slow Test)
• Тест слишком долгий, для того, чтобы разработчик запускал его
после каждого изменения
• Снижает продуктивность команды в целом – «бутылочное горло»
в процессе интеграции
Возможные причины Возможные решения
Использование медленных компонентов.
Например , реальной БД.
• Замена медленных компонентов , на
«быстрых» двойников.
Пример: OCI Stub
Долгий процесс создания данных, много
повторяющихся общих данных
Использование общей тестовой конфигурации
Неоправданные задержки (чрезмерные
задержки, забытые sleep-ы 
• Убрать все ненужные паузы
• Нужные паузы проанализировать на
предмет их избыточности
Беспорядочный тест (Erratic Test)
• Бесконечный анализ бесконечных «миганий»
• НЕРВИРУЕТ!
Возможные причины Возможные решения
Неявное влияние тестов друг на друга
• Через данные (создание очистка)
• Каждый раз новая конфигурация
• Ленивая настройка
• Автоматическая очистка
Конкурентный одновременный запуск Пересмотреть способ запуска
Зависимость от «фазы луны» Настройку «фазы луны» сделать частью
процесса настройки перед запуском тестов
PyTest – швейцарский нож
• Не встроен в python
• Поддержка xUnit-style тестов
• Политика гарантированной обратной совместимости
• Поддерживает стандартное Test Discovery
• Возможность собственной настройки Discovery (через ini-
файл)
• Гибкая настройка тестовых конфигураций (fixtures)
• «Из коробки» может запускать unittest-тесты без их
модификации
• Механизм плагинов существенно расширяющих
функциональность (pytest-xdist, pytest-django, pytest-cov,
pytest-pep8 etc)
PyTest – совсем чуть-чуть наглядности
Простой тест Группировка в классе
Удобный дефолтный отчет
PyTest – «фикстуры»
«фикстуры»
…область «видимости» фикстур…
…параметризация фикстур…
• Существенно расширяют возможности
стандартного xUnit setup-teardown подхода
• Имеют явные имена, по которым могут быть
вызваны из тестовых методов , модулей, классов
или всего проекта.
• Могут быть использованы в других «фикстурах»
• Могут быть параметризованы
• Имеют несколько уровней области видимости:
функция/метод, класс, модуль, сессия
Итоги… 
— Чему мы научились, Палмер?
— Не знаю, сэр.
— Я тоже не знаю…. Научились больше этого не
делать…. И еще бы знать, что мы сделали…
— Это сложно сказать, сэр…
СПАСИБО ЗА ВНИМАНИЕ 

Weitere ähnliche Inhalte

Was ist angesagt?

Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Anton Moiseenko
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.Igor Shkulipa
 
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Anton Moiseenko
 
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)"Опыт создания системы управления сборкой и тестированием" (слайдкаст)
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)SPB SQA Group
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.Igor Shkulipa
 
Использование Mock объектов в модульном тестировании
Использование Mock объектов в модульном тестированииИспользование Mock объектов в модульном тестировании
Использование Mock объектов в модульном тестированииGetDev.NET
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.Igor Shkulipa
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.Igor Shkulipa
 
Java Core. Lecture# 3. Part# 1. Abstract classes.
Java Core. Lecture# 3. Part# 1. Abstract classes.Java Core. Lecture# 3. Part# 1. Abstract classes.
Java Core. Lecture# 3. Part# 1. Abstract classes.Anton Moiseenko
 
Тестирование весна 2014 смешанное занятие 2
Тестирование весна 2014 смешанное занятие 2Тестирование весна 2014 смешанное занятие 2
Тестирование весна 2014 смешанное занятие 2Technopark
 

Was ist angesagt? (12)

Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
 
C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.C++ STL & Qt. Занятие 05.
C++ STL & Qt. Занятие 05.
 
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.
 
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)"Опыт создания системы управления сборкой и тестированием" (слайдкаст)
"Опыт создания системы управления сборкой и тестированием" (слайдкаст)
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
Unit тесты java
Unit тесты javaUnit тесты java
Unit тесты java
 
Использование Mock объектов в модульном тестировании
Использование Mock объектов в модульном тестированииИспользование Mock объектов в модульном тестировании
Использование Mock объектов в модульном тестировании
 
Java: вчера, сегодня, завтра
Java: вчера, сегодня, завтраJava: вчера, сегодня, завтра
Java: вчера, сегодня, завтра
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
 
Java Core. Lecture# 3. Part# 1. Abstract classes.
Java Core. Lecture# 3. Part# 1. Abstract classes.Java Core. Lecture# 3. Part# 1. Abstract classes.
Java Core. Lecture# 3. Part# 1. Abstract classes.
 
Тестирование весна 2014 смешанное занятие 2
Тестирование весна 2014 смешанное занятие 2Тестирование весна 2014 смешанное занятие 2
Тестирование весна 2014 смешанное занятие 2
 

Ähnlich wie Александр Ярулин - Автоматизация тестирования с xUnit

Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgIT61
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in netAlex Tumanoff
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAndrey Rebrov
 
Unit testing
Unit testingUnit testing
Unit testingISsoft
 
Тестирование ПО
Тестирование ПОТестирование ПО
Тестирование ПОseleznev_stas
 
Jubula – TDD UI QA Automation Tool
Jubula – TDD UI QA Automation ToolJubula – TDD UI QA Automation Tool
Jubula – TDD UI QA Automation ToolCOMAQA.BY
 
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with SeleniumOSLL
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Dmitry Buzdin
 
Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...SQALab
 
Froglogic Squish
Froglogic Squish Froglogic Squish
Froglogic Squish SQALab
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsAnton Vidishchev
 
Организация тестового набора при автоматизированном функциональном тестировании
Организация тестового набора при автоматизированном функциональном тестированииОрганизация тестового набора при автоматизированном функциональном тестировании
Организация тестового набора при автоматизированном функциональном тестированииSQALab
 
Do you know what you are testing?
Do you know what you are testing?Do you know what you are testing?
Do you know what you are testing?Mikalai Alimenkou
 
А вы знаете что тестируют ваши тесты?
А вы знаете что тестируют ваши тесты?А вы знаете что тестируют ваши тесты?
А вы знаете что тестируют ваши тесты?SQALab
 
Формирование команды автотестирования
Формирование команды автотестированияФормирование команды автотестирования
Формирование команды автотестированияOlga Rusakova
 
Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...
 Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par... Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...
Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...it-people
 
Тестирирование с xUnit
Тестирирование с xUnitТестирирование с xUnit
Тестирирование с xUnitAlexander Goida
 

Ähnlich wie Александр Ярулин - Автоматизация тестирования с xUnit (20)

Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in net
 
Unit tests
Unit testsUnit tests
Unit tests
 
Automation Functional Testing in Agile Projects
Automation Functional Testing in Agile ProjectsAutomation Functional Testing in Agile Projects
Automation Functional Testing in Agile Projects
 
Unit testing
Unit testingUnit testing
Unit testing
 
Тестирование ПО
Тестирование ПОТестирование ПО
Тестирование ПО
 
Jubula – TDD UI QA Automation Tool
Jubula – TDD UI QA Automation ToolJubula – TDD UI QA Automation Tool
Jubula – TDD UI QA Automation Tool
 
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with Selenium
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?
 
План тестирования
План тестированияПлан тестирования
План тестирования
 
Test levels
Test levelsTest levels
Test levels
 
Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...Система управления автоматическими тестами на примере использования Visual St...
Система управления автоматическими тестами на примере использования Visual St...
 
Froglogic Squish
Froglogic Squish Froglogic Squish
Froglogic Squish
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET Applications
 
Организация тестового набора при автоматизированном функциональном тестировании
Организация тестового набора при автоматизированном функциональном тестированииОрганизация тестового набора при автоматизированном функциональном тестировании
Организация тестового набора при автоматизированном функциональном тестировании
 
Do you know what you are testing?
Do you know what you are testing?Do you know what you are testing?
Do you know what you are testing?
 
А вы знаете что тестируют ваши тесты?
А вы знаете что тестируют ваши тесты?А вы знаете что тестируют ваши тесты?
А вы знаете что тестируют ваши тесты?
 
Формирование команды автотестирования
Формирование команды автотестированияФормирование команды автотестирования
Формирование команды автотестирования
 
Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...
 Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par... Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...
Создаем команду автотестирования в нетипичных условиях, Василий Никишин, Par...
 
Тестирирование с xUnit
Тестирирование с xUnitТестирирование с xUnit
Тестирирование с xUnit
 

Mehr von Yandex

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksYandex
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Yandex
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаYandex
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаYandex
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Yandex
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Yandex
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Yandex
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Yandex
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Yandex
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Yandex
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Yandex
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровYandex
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Yandex
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Yandex
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Yandex
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Yandex
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Yandex
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Yandex
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Yandex
 

Mehr von Yandex (20)

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 

Александр Ярулин - Автоматизация тестирования с xUnit

  • 1. xUnit – философия и основные правила Александр Ярулин
  • 2. • Модульный тест: «отделяем зерна от плевел» • Немного истории • Определение термина xUnit • Основные идеи xUnit • Различные реализации xUnit • Область применимости xUnit • Некоторые сценарии нетрадиционного использования xUnit О чем будем говорить…
  • 3. Что такое модульный тест? • код с определенной структурой, который проверяет поведение одного класса или функции ( т.е. использует внутренние интерфейсы приложения) • написан на том же языке программирования • пишется как правило самими разработчиками
  • 4. Тест не модульный, если • работает с реальной БД • использует сеть • работает с файловой системой • воздействует на тестируемую систему (SUT) через внешний интерфейс (API, GUI, сеть и т.д.)
  • 5. Для чего модульные тесты? • повышение качества продукта • предотвращение ошибок и их быстрое выявление • изолированная проверка работоспособности внутренних модулей для быстрой локализации дефектов • понимание системы • тесты как спецификация системы (напр. при TDD) • тесты как документация • снижение рисков • быстрое выявление побочных эффектов изменений в коде • безопасная работа с унаследованным кодом, который покрыт модульными тестами
  • 6. Каким должен быть идеальный unit-тест ? • Самодостаточным (self-checking) • Независимым (independent) • Понятным (clear) • Повторяемым (repeatable) • Устойчивым (robust) • Простым (simple) • Легко запускаемым (easy running) • Эффективным (efficient)
  • 7. Вопросы…вопросы… • как писать unit-тесты ? • как упорядочивать unit-тесты ? • как запускать unit-тесты ? • как получать отчеты?
  • 8. Немного истории SetTestCase>>#testAdd empty add: 5. self should: [empty includes: 5] @Test public void simpleAdd() { int n1 = 3 int n2 = 2 expected = 6 assertTrue(expected == n1 + n2); } История от Мартина Фаулера  Кент Бек, SmallTalk и SUnit CppUnit и портирование на другие языки JUnit (Кент Бек, Эрих Гамма)
  • 9. Даем определение xUnit – семейство инфраструктур автоматизации тестирования (Testing Automation Framework), реализующих общие принципы и предназначенных для реализации созданных вручную тестов (Scripted Test). Синонимы термина Scripted Test: • Hand-Written Test • Hand-Scripted Test • Programatic Test • Automated Unit Test
  • 10. Допустим «дуализм» • xUnit как парадигма • xUnit как семейство фреймворков автоматизации «Парадигма» - совокупность фундаментальных научных установок, представлений и терминов, принимаемая и разделяемая научным сообществом и объединяющая большинство его членов. (Wikipedia)
  • 11. «Общие принципы» • Тест – это тестовый метод (Test Method), реализующий 4- х фазный тест (Four Phase Test) • Объединение тестовых методов в классы (Tescase Class) в коде • Использование утверждений (Assertions) для проверки поведения системы • Объединение тестов в тестовые наборы (Test Suite) на этапе выполнения • Обнаружение (Test Discovery) или явное перечисление (Test Enumeration) тестов • Различные варианты запуска тестов (Test Running) • Отчеты о результатах тестирования (Testing Report)
  • 12. Применимость xUnit-фреймворков • Модульные тесты (unit tests) Небольшие, понятные и быстрые тесты с простой тестовой конфигурацией • Интеграционные тесты (integration tests) • ряд преимуществ может быть потерян • эффективное использование также возможно • самостоятельное или вместе Data Driven Testing (DDT)
  • 13. 4-х фазный тест (Four Phase Test) • Настройка тестовой конфигурации (Setup) • Действие с SUT (Exercise) • Проверка корректности результата (Verify) • Очистка (Teardown)
  • 14. Цель: хранение тестовой логики Реализация: метод класса , процедура или функция с тестовой логикой, реализующая 4-фазный тест Основные типы: • тест ожидаемой успешности/не успешности (Simple Success Test) • тесты на ожидаемые исключения (Expected Exception Test) • тесты создания объектов / тесты конструкторов (Constructor Test) Тестовый метод (Test Method)
  • 15. • Нужен для проверки очевидных успешных сценариев • Реализует классические 4 фазы • Возможные исключения в тестовом методе не перехватываются Простой тест успешности (Simple Success Test) class WindowTestCase(unittest.TestCase): def test_default_dimension(self): window = Window() self.assertEqual(window.size(), (800, 600), 'incorrect default dimension')
  • 16. • Проверка правильности обработки ошибок в SUT • Только те исключения, которые приложение генерирует самостоятельно Тест на ожидаемое исключение class WindowTestCase(unittest.TestCase): def test_size_exception(self): window = Window(width=-100, height=100) self.assertRaises(InputParamException, “bla”)
  • 17. • Для локализации дефектов при создании объекта • Проверка правильности создания объекта • Проверяются все поля ( инициализируемые и неинициализируемые) • Может быть сделан на основе теста успешности или теста на ожидаемое исключение Тест конструктора class WindowTestCase(unittest.TestCase): def test_window_ctor(self): w = Window(width=100, height=200) self.assertEqual(w.width, 100, ”incorrect width”) self.assertEqual(w.height, 200, “incorrect height”) self.assertNull(w.childs, “childs is not null”)
  • 18. • класс, предназначенный для группировки одного или более тестовых методов • создание объекта класса (Testcase object) для каждого тестового метода на этапе выполнения • объединение объектов класса в тестовые наборы (Test Suite) для запуска специальной программой (Test Runner) Класс теста (Testcase Class)
  • 19. • То, во что превращается каждый тестовый метод на этапе выполнения • У каждого объекта есть метод run для запуска теста • У всех тестов единый интерфейс для программы запуска тестов • Тесты изолированы друг от друга Исключения • NUnit Объект теста (Testcase Object) «…Я думаю, что самой большой ошибкой при написании Nunit был отказ от создания нового экземпляра класса тестовой конфигурации для каждого тестового метода …» Джеймс Ньюкирк , автор NUnit
  • 20. • «Композитный тест», который содержит коллекцию отдельных объектов тестов (Testcase Object) • У каждого объекта набора тестов (Test Suite Object) есть метод run для запуска теста • Для программы запуска тестов все равны • Наборы наборов, наборы наборов наборов …. Паттерн «Компоновщик» – позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково Объект набора тестов (Test Suite Object)
  • 21. Test Suite и TestCase в unittest import unittest class WidgetTestCase(unittest.TestCase): def test_default_size(self): #... def test_resize(self): #... suite = unittest.TestSuite() suite.addTest(WidgetTestCase('test_default_size')) suite.addTest(WidgetTestCase('test_resize')) suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase) suite1 = module1.TheTestSuite() suite2 = module2.TheTestSuite() alltests = unittest.TestSuite([suite1, suite2])
  • 22. • У каждой xUnit-реализации есть приложение для запуска тестов (Test Runner) • Консольные • GUI-шные • Встраиваемые в IDE • Должен уметь • Обнаруживать и запускать тесты (Test Discovery) • Обнаружение классов тестов • Обнаружение тестовых методов • Выводить информацию о результатах прогона (Test Report) • Можно написать свой Test Runner «Запускальщик» тестов (Test Runner)
  • 23. Пример автотеста ( Python, unittest ) import random import unittest class TestRandom(unittest.TestCase): def setUp(self): self.seq = range(10) def test_choice(self): element = random.choice(self.seq) self.assertTrue(element in self.seq) if __name__ == '__main__': unittest.main()
  • 24. python –m unittest discover –s ./tests/ -p “test*.py” 1. самостоятельный запуск 2. запуск средствами unittest (фактически аналогично п.1) 3. запуск определенного набора тестов 4. запуск единичного теста (тестового метода) 5. Test discovery python –m unittest test.TestRandom.test_choice python –m unittest test.TestRandom python –m unittest test ./test.py Некоторые варианты запуска
  • 26. Цели: • подготовка тестового окружения, необходимого для проведения теста Примеры: • переменные окружения • инициализация базы данных • создание нужных файлов • открытие сетевых соединений • создание и инициализация объектов классов • и так далее … Настройка (Setup)
  • 27. • Новая тестовая конфигурация (Fresh Fixture) • Встроенная (In-line Setup) • Делегированная (Delegated Setup) • Метод создания (Creation Method) • Неявная (Implicit setup) • Общая тестовая конфигурация (Shared Fixture) • Предварительная (Prebuild Fixture ) • «Ленивая» настройка (Lazy Setup) • Конфигурация набора (Suite Fixture Setup) • Цепочки тестов (Chained Tests) Шаблоны настройки конфигурации
  • 28. Встроенная настройка (In-line Setup) Шаблоны настройки конфигурации • Подходит для очень простых тестов • Подходит на начальном этапе • Часто является предметом рефакторинга class InlineDemo(unittest.TestCase): def test_one(self): #inline setup self.sut = Sut() sut.setParam(1) #exercise the sut def test_two(self): #inline setup self.sut = Sut() sut.setParam(2) #exercise the sut
  • 29. Делегированная настройка (Delegated Setup) Шаблоны настройки конфигурации • Избавление от дублирования похожего тестового кода • Сохраняется понятность / читабельность теста class DelegatedDemo(unittest.TestCase): def test_one(self): self.sut = create_the_sut() #exercise the sut in test_one-way def test_two(self): self.sut = create_the_sut() #exercise the sut in test_two-way
  • 30. Неявная настройка (Implicit Setup) Шаблоны настройки конфигурации • setUp вызывается самим фреймворком перед запуском каждого теста • Использовать для создания одинаковых данных • Как правило сопровождается неявной очисткой (Implicit Teardown) • Антипаттерн – сваливать в кучу общие и частные данные class ImplicitDemo(unittest.TestCase): def setUp(self): self.common = CreateSmthCommon() def test_one(self): special = CreateSmthSpecial(self.common)
  • 31. Предварительная конфигурация (Prebuilt Fixture) Шаблоны настройки конфигурации • Создается до запуска тестов • Позволяет сокращать время прогона • Сложно управлять с ростом конфигурации • Риск неявного взаимовлияния тестов через данные class PrebuiltDemo(unittest.TestCase): def test_the_sut(self): sut = findSUTInPrebuiltFixture() #exercise with the sut
  • 32. «Ленивая» настройка (Lazy Setup) Шаблоны настройки конфигурации • Создается первым же тестом, которому она нужна • Экономия времени • Непонятно, после какого теста надо чистить • Использовать, когда очистка не обязательна class LazySetupDemo(unittest.TestCase): def setUp(self): if self.sut: return self.sut = create_the_sut() def test_the_sut(self): #exercise with the SUT
  • 33. Конфигурация набора (Suite Fixture Setup) Шаблоны настройки конфигурации • Конфигурация, общая для всех тестов класса • Выигрыш во времени • Риск появления взаимодействующих тестов (Interacting Tests) class Test(unittest.TestCase): @classmethod def setUpClass(cls): cls._connection = new_connection() #some test methods here @classmethod def tearDownClass(self): cls._connection.destroy()
  • 34. Цепочки тестов (Chained Tests) Шаблоны настройки конфигурации • Важен порядок тестов • Тесты используют «остатки» предыдущих и экономят время • Риск - меняем один тест, падают остальные class Chain(unittest.TestCase): def test_1(self): obj = get_from_db() #do something with obj obj.store_into_db() def test_2(self): obj = get_from_db() #use obj while testing
  • 35. Действие (Exercise) Цели: • воздействие на тестируемый объект Примеры: • вызов тестируемых функций • запуск тестируемых утилит ( ? ) • тестовое создание экземпляров объектов • вызов api-методов ( ? ) • и так далее …
  • 36. Проверка результатов (Verify) Стратегии: • Проверка состояния объекта (State Verification) • Проверка поведения (Behavior Verification) Методы с утверждениями : • Специальное утверждение (Custom Assertion) • Дельта-утверждение (Delta Assertion) • Сторожевое утверждение (Guard Assertion) • Утверждение незаконченного теста (Unfinished Test Assertion)
  • 37. Проверка состояния (State Verification) важно конечное состояние SUT, а не то, как в него попали def test_state(self): expected = CatalogItem() catalog.addItem(expected) actual = catalog.get(0) self.asserEqual(catalog.size(),1,”…”) self.assertEqual(expected, actual)
  • 38. Проверка поведения (Behavior Verification) • DOC – Dependent On Component • Нужен способ проверки • Тестовые двойники (Test Double) def test_behavior(self): #setup spy = DOCSpy() sut = Sut(doc=spy) #exercise sut.do_smth_what_needs_DOC() #verify self.asserEqual(spy.numOfCalls,10,”…”) #teardown doesn’t matter
  • 39. Специальное утверждение (Custom Assertion) def test_assert(self): ... self.assertEqual(expected.field1, actual.field1) self.assertEqual(expected.field2, actual.field2) self.assertEqual(expected.field3, actual.field3) ... • cоздаем собственный assertion • прячем в него повторяющиеся проверки • упрощаем код теста def test_custom_assert(self): ... assertEqualCustom(expected, actual) ...
  • 40. Дельта утверждение • Фиксируем состояние конфигурации до теста • Делаем проверки, отталкиваясь от зафиксированного состояния def test_conditional_logic(self): objcount = fixture.get_objects_count() # setup , … , teardown assertEqual(objcount, fixture.get_objects_count())
  • 41. Сторожевое утверждение (Guard Assertion) • Для избавления от условной логики «if then else fail» • Это обычный assertion, но он не относится напрямую к цели теста • Используется как правило между setup и exercise def test_conditional_logic(self): if(fixture.catalog): #do some test else: self.fail() def test_guard(self): self.assertIsNotNone(fixture.catalog) #do some test
  • 42. Утверждение незаконченного теста • «TODO» для автотестов • Не доделанный тест должен фейлиться class MyTestCase(unittest.TestCase): def test_unfinished(self): self.fail(“Why I Live???")
  • 43. Утверждения(Assertions) в unittest Method Checks that New in assertEqual(a, b) a == b assertNotEqual(a, b) a != b assertTrue(x) bool(x) is True assertFalse(x) bool(x) is False assertIs(a, b) a is b 2.7 assertIsNot(a, b) a is not b 2.7 assertIsNone(x) x is None 2.7 assertIsNotNone(x) x is not None 2.7 assertIn(a, b) a in b 2.7 assertNotIn(a, b) a not in b 2.7 assertIsInstance(a, b) isinstance(a, b) 2.7 assertNotIsInstance(a, b) not isinstance(a, b) 2.7
  • 44. Очистка (Teardown) Цели: • исключение возможности неявного влияния тестов друг на друга и повышение их повторяемости • рациональное использование ресурсов системы Примеры: • закрытие файловых дескрипторов • освобождение явно выделенной памяти • закрытие сетевых соединений • удаление «следов» в БД, файловой системе • и так далее …
  • 45. Шаблоны очистки • Очистка со сборкой мусора (Garbage-Collected Teardown) • Автоматическая очистка (Automated Teardown) • Встроенная очистка (Inline Teardown) • Неявная очистка (Implicit Teardown)
  • 46. Изоляция проверяемой системы Тестовые двойники (Test Double) • предоставляет такой же интерфейс, как настоящий компонент • с фиксированным или настраиваемым поведением • позволяет покрыть больше кода • позволяет бороться с медленными тестами (Slow Test) Основные типы • Тестовая заглушка (Test Stub) • Тестовый агент (Test Spy) • Подставной объект (Mock Object) Для чего?
  • 47. Тестовая заглушка (Test Stub) • возможность опосредованного ввода для SUT • помогает заставить SUT вести себя так, как нам надо (покрывать нужные ветки кода)
  • 48. Тестовый агент (Test Spy) • опосредованный вывод - записывает вызовы SUT • используется с шаблоном «Проверка поведения»
  • 49. Подставной объект (Mock Object) • настраивается значениями для передачи в SUT, а также ожиданиями ответов от SUT • cравнивает ответы от SUT с помощью assertions • в самом тесте утверждения не дублируются • используется для проверки поведения SUT • «строгий» и «нестрогий» подставной объект и порядок вызовов от SUT
  • 50. Пример xUnit для не unit-тестов • тесты на модели (model) • тесты на представления (view) • тесты с реальным веб-сервером • даже тесты на GUI
  • 51. Пример теста на Django class PollViewTests(TestCase): def test_index_view_with_no_polls(self): """ If no polls exist, an appropriate message should be displayed. """ response = self.client.get(reverse('polls:index')) self.assertEqual(response.status_code, 200) self.assertContains(response, "No polls are available.") self.assertQuerysetEqual(response.context['latest_poll_list'], []) def test_index_view_with_a_past_poll(self): """ Polls with a pub_date in the past should be displayed on index page. """ create_poll(question="Past poll.", days=-30) response = self.client.get(reverse('polls:index')) self.assertQuerysetEqual( response.context['latest_poll_list'], ['<Poll: Past poll.>'] )
  • 52. Еще один не-unit тест… import unittest class GoogleTestCase(unittest.TestCase): def setUp(self): self.browser = webdriver.Firefox() def testPageTitle(self): self.browser.get('http://www.google.com') self.assertIn('Google', self.browser.title) def teardown(self): self.browser.quit if __name__ == '__main__': unittest.main(verbosity=2)
  • 53. Отчеты о тестировании и CI • TAP (Test Anything Protocol) – отчеты • JUnit – отчеты • Произвольные форматы и конвертации 1..48 ok 1 Description # Directive # Diagnostic .... ok 47 Description ok 48 Description <testsuite tests="3"> <testcase classname="foo" name="ASuccessfulTest"/> <testcase classname="foo" name="AnotherSuccessfulTest"/> <testcase classname="foo" name="AFailingTest"> <failure type="NotEnoughFoo"> details about failure </failure> </testcase> </testsuite>
  • 54. Признаки плохих тестов (Test Smells) • непонятный тест (Obscure Test) • хрупкий тест (Fragile Test) • условная логика в тесте (Conditional test logic) • дублирование кода (Test Code Duplication) • медленные тесты (Slow Tests) • беспорядочный тест (Erratic test)
  • 55. Непонятный тест (Obscure Test) • Сложно понять, что делает тест • Сложно его поддерживать Возможные причины Возможные решения Тест делает много лишнего • Оставить только то, что непосредственно относится к цели теста. • Декомпозиция теста Запутанная логика создания , взаимодействия с SUT или проверки • Разработка теста «от общего к частному» • Использование вспомогательных методов, специальных утверждений, делегированной настройки
  • 56. Хрупкий тест (Fragile Test) • Тест «падает» от несвязанных с ним изменений в SUT • Больше анализа тестов – выше трудоемкость поддержки Возможные причины Возможные решения Изменился код, используемый для создания, проверки или очистки Использовать методы создания, специальные утверждения, хелперы Неожиданные изменения в данных. Например, действия одного теста «сломали» данные другого Минимизация влияния тестов друг на друга. Например Fresh Fixture. Зависимость от контекста. Например, результаты зависят от даты или длины текущего месяца. Решается в каждом конкретном случае по- особому. Пример (Oracle): ALTER SYSTEM SET fixed_date = '2011-12-31 23:59:59‘; ALTER SYSTEM SET fixed_date=NONE.
  • 57. Условная логика теста (Conditional Test Logic) • Сложнее отладка самого теста • Непонятный тест Возможные причины Возможные решения «Гибкий тест» – проверяет разное и по-разному в зависимости от внешних условий • Изоляция SUT • Декомпозиция теста If then else • Сторожевые утверждения • Специальные утверждения Сложная очистка • Неявная очистка • Автоматическая очистка
  • 58. Дублирование кода (Test Code Duplication) • Сложность и дороговизна поддержки системы автотестов • Дополнительный рефакторинг Возможные причины Возможные решения Copy - Paste «Лучше день потерять, зато потом…» (с) м/ф «Крылья, ноги и хвосты» Изобретение велосипеда. Например, параллельная реализация кучи одинаковых в общем-то хелперов, библиотек и т.д. • Ревью • Анализ того, что «велосипед уже есть»
  • 59. Медленный тест (Slow Test) • Тест слишком долгий, для того, чтобы разработчик запускал его после каждого изменения • Снижает продуктивность команды в целом – «бутылочное горло» в процессе интеграции Возможные причины Возможные решения Использование медленных компонентов. Например , реальной БД. • Замена медленных компонентов , на «быстрых» двойников. Пример: OCI Stub Долгий процесс создания данных, много повторяющихся общих данных Использование общей тестовой конфигурации Неоправданные задержки (чрезмерные задержки, забытые sleep-ы  • Убрать все ненужные паузы • Нужные паузы проанализировать на предмет их избыточности
  • 60. Беспорядочный тест (Erratic Test) • Бесконечный анализ бесконечных «миганий» • НЕРВИРУЕТ! Возможные причины Возможные решения Неявное влияние тестов друг на друга • Через данные (создание очистка) • Каждый раз новая конфигурация • Ленивая настройка • Автоматическая очистка Конкурентный одновременный запуск Пересмотреть способ запуска Зависимость от «фазы луны» Настройку «фазы луны» сделать частью процесса настройки перед запуском тестов
  • 61. PyTest – швейцарский нож • Не встроен в python • Поддержка xUnit-style тестов • Политика гарантированной обратной совместимости • Поддерживает стандартное Test Discovery • Возможность собственной настройки Discovery (через ini- файл) • Гибкая настройка тестовых конфигураций (fixtures) • «Из коробки» может запускать unittest-тесты без их модификации • Механизм плагинов существенно расширяющих функциональность (pytest-xdist, pytest-django, pytest-cov, pytest-pep8 etc)
  • 62. PyTest – совсем чуть-чуть наглядности Простой тест Группировка в классе Удобный дефолтный отчет
  • 63. PyTest – «фикстуры» «фикстуры» …область «видимости» фикстур… …параметризация фикстур… • Существенно расширяют возможности стандартного xUnit setup-teardown подхода • Имеют явные имена, по которым могут быть вызваны из тестовых методов , модулей, классов или всего проекта. • Могут быть использованы в других «фикстурах» • Могут быть параметризованы • Имеют несколько уровней области видимости: функция/метод, класс, модуль, сессия
  • 64. Итоги…  — Чему мы научились, Палмер? — Не знаю, сэр. — Я тоже не знаю…. Научились больше этого не делать…. И еще бы знать, что мы сделали… — Это сложно сказать, сэр…