Основная идея Test-Driven Development (TDD) — написание тестов перед написанием любого функционального кода, а затем написание только минимально возможного количества кода, необходимого для прохождения тестов. Может показаться странным, что такое развитие происходит, но на самом деле это весьма полезно, поскольку база тестов удваивается как частичная спецификация основного кода.
Однако, учитывая такую простую предпосылку, существует огромное количество терминологии и приемов. В этой статье я соберу наиболее важные термины и модные слова, которые вы можете услышать, и определю их.
Справочник по терминологии
Приемочное тестирование
Тестирование в первую очередь позволяет выполнять функциональные тесты высокого уровня.
Высочайший уровень тестирования подтверждает, что программное обеспечение соответствует требованиям заказчика. Приемочные испытания обычно проводятся в средах, максимально приближенных к производственным. Смотрите функциональное тестирование и тестирование системы .
Утверждение
Утверждения являются утверждениями, которые выполняют фактическую проверку на выходе программного обеспечения. В общем, одной функции assert
достаточно для выражения любой проверки. На практике тестовые библиотеки часто имеют много функций assert для удовлетворения конкретных потребностей (таких как assertFalse
, assertEqual
и другие) для обеспечения лучшего анализа и более assertEqual
вывода.
Тестирование поведения
Методика тестирования, включающая тестирование, дублирует программное обеспечение, утверждая, что оно вызывает правильные методы в правильном порядке. Смотрите макет для примера. Также см. Государственное тестирование .
Поведенческое развитие (BDD)
Подмножество TDD обусловлено необходимостью более четкой связи и надлежащей документации. BDD, пожалуй, самая большая разработка последних лет в TDD.
Его основная идея состоит в том, чтобы заменить запутанную и ориентированную на разработчика терминологию ( тесты , наборы , утверждения и т. Д.) Повсеместным языком , понятным для всех участвующих заинтересованных сторон (включая нетехнических сотрудников и, возможно, клиентов).
Смотрите историю пользователя .
Тестирование черного ящика
Общий принцип в тестировании, когда человек, пишущий тесты, не знает или избегает внутренних компонентов программного обеспечения, вместо этого выбирая для тестирования открытого интерфейса программного обеспечения строго его интерфейс или спецификацию. Смотрите тестирование белого ящика .
Граничное тестирование
Стратегия написания тестов для обнаружения отдельных ошибок и других подобных типов ошибок. Чтобы выполнить граничное тестирование, протестируйте входные данные вокруг некоторых возможных проблемных границ. В случае целых чисел это могут быть 0
, -1
, MIN_INT
, MAX_INT
и другие подобные значения.
фиктивный
Утверждения являются утверждениями, которые выполняют фактическую проверку на выходе программного обеспечения.
Пустышка — это тип тестового двойника, который никогда не используется самим программным обеспечением, а используется только при тестировании для заполнения необходимых параметров.
Не настоящие
Подделки — это тестовые двойники, которые реализуют требуемую функциональность способом, который полезен при тестировании, но который также эффективно исключает его использование в производственной среде. Например, база данных ключ-значение, которая хранит все значения в памяти и теряет их после каждого выполнения, потенциально позволяет выполнять тесты быстрее, но ее тенденция к уничтожению данных не позволяет использовать ее в работе.
зажимное приспособление
Конкретная среда, которая должна быть настроена до запуска теста. Как правило, он состоит из настройки всех тестовых дубликатов и других зависимостей для тестируемого программного обеспечения: таких как вставка предопределенных данных в поддельную базу данных, настройка определенной структуры каталогов в поддельной файловой системе, настройка свойств на зависимости тестируемого программного обеспечения.
Функциональное тестирование
Тестирование на высоком уровне, подтверждающее, что все бизнес-требования продукта выполнены. Функциональное тестирование обычно включает использование пользовательских историй, чтобы сосредоточиться на более высоком уровне требований, чтобы охватить как можно больше сценариев использования. Смотрите приемочные испытания и тестирование системы . Например:
1
2
3
4
|
# In this example we check that the about page of the website is working as expected
open ‘example.com’
clickOn ‘about us’
assertThereIs ‘We are a small Example company’
|
зеленый
Разговор для прохождения набора тестов или иногда конкретного прохождения теста. Смотри красный .
Интеграционное тестирование
Средство тестирования среднего уровня, которое проверяет определенный набор модулей, правильно работающих вместе. Интеграционные тесты похожи на модульные тесты без использования удваивающихся тестов для определенного подмножества зависимостей, по сути, проверяя взаимодействие между программным обеспечением и его зависимостями. Пример:
1
2
3
4
5
6
7
8
|
# In this example we check that the newly registered user,
# who was referred by another user, gets an on-site «friendship» created.
# Here we check the interaction between the form controller,
# database, and a User active record
db = new Fake Db
u1 = db.createUser(name=’john’)
RegistrationForm(db, name=’kate’, referred=’john’).save()
assert(u1.hasFriend(‘kate’))
|
издеваться
Тип двойного теста, созданный для конкретного теста или контрольного примера . Ожидается, что он будет вызван определенное количество раз и даст заранее определенный ответ. В конце теста макет вызывает ошибку, если он не вызывался столько раз, сколько ожидалось. Насмешка со строгими ожиданиями является частью концепции утверждений . Пример:
1
2
3
4
5
6
7
|
# In this example we use a mock database to check that the form
# uses the database to store the new user.
# If the database has not been called at the end of the test,
# the mock itself will raise an assertion error.
db = new Mock Db
db.expect(‘save’).once().with(name=’john’)
RegistrationForm(db, name=’john’).save()
|
Обезьяна-заплат
Способ расширить и изменить поведение существующих объектов и классов на языке программирования. Обезьяны-исправления могут использоваться в качестве альтернативы внедрению зависимостей, и тестирование удваивается путем непосредственного изменения существующих функций, вызываемых тестируемым программным обеспечением (и изменения их обратно после теста).
1
2
3
4
|
# In this example we replace the standard library function
# to prevent the test from using a real filesystem
filesystem.listdir = f (name) ->
assertEqual(MyFileSearch(‘foo’).count(), 1)
|
красный
Разговор для неудачного набора тестов или иногда конкретного неудачного теста. Вижу зеленый .
Рефакторинг
Процесс улучшения реализации деталей кода без изменения его функциональности.
Рефакторинг без тестов — очень хрупкий процесс, так как разработчик, выполняющий рефакторинг, никогда не может быть уверен, что его улучшения не нарушают некоторые части функциональности.
Если код был написан с использованием разработки, основанной на тестировании, разработчик может быть уверен, что его рефакторинг прошел успешно, как только все тесты пройдут, поскольку все необходимые функции кода по-прежнему корректны.
регрессия
Программный дефект, который появляется в определенной функции после некоторого события (обычно это изменение в коде).
Сценарий тестирования
Смотрите функциональное тестирование .
Настроить
Процесс подготовки крепежа . Смотрите демонтаж . Пример:
1
2
3
4
5
6
|
# In this example we prepare a fake database with some fake values
# that we will need across multiple tests
db = new Fake Db
db.createUser(name=’john’)
db.createUser(name=’kate’)
db.createFriendship(‘john’, ‘kate’)
|
Государственное тестирование
Форма модульного тестирования, когда тестовый код предоставляет тест, удваивает и утверждает, что состояние этих двойников было правильно изменено. Смотрите тестирование поведения .
1
2
3
4
5
6
|
# In this example, like in an example on mock objects,
# we will check that the form uses the database to store the new user.
# This time we will check state, instead of behavior
db = new Fake Db
RegistrationForm(db, name=’john’).save()
assertInList(‘john’, db.listUsers())
|
огрызок
Подделки — это тестовые двойники , которые никогда не используются самим программным обеспечением.
Тип двойного теста, который может отвечать на тестируемое программное обеспечение с предварительно определенными ответами. Однако, в отличие от макетов , заглушки обычно не проверяют, правильно ли они были вызваны, а лишь проверяют, может ли программа вызывать свои зависимости.
Тестирование системы
Активность тестирования высокого уровня, когда все программное обеспечение тестируется сверху вниз. Это включает функциональное тестирование , а также проверку других характеристик (таких как производительность и стабильность).
SUT
Аббревиатура для тестируемого программного обеспечения . Используется для отличия тестируемого программного обеспечения от его зависимостей.
Срывать
Процесс очистки приспособления . В языках с мусором эта функциональность в основном обрабатывается автоматически. Смотрите настройку .
Тестовое задание
Наименьшая возможная проверка на правильность. Например, один тест для веб-формы может быть проверкой того, что при получении неверного адреса электронной почты форма предупреждает пользователя и предлагает исправление. Смотрите тестовый пример .
Прецедент
Коллекция тестов, сгруппированных по атрибуту. Например, контрольный пример для веб-формы может представлять собой набор тестов, проверяющих поведение формы на наличие различных допустимых и недействительных входных данных.
01
02
03
04
05
06
07
08
09
10
|
function t1:
assertNoError(
RegistrationForm(name=’john’, password=’horse battery staple correct’).save()
)
function t2:
assertError(MissingPassword, RegistrationForm(name=’john’).save())
function t3:
assertError(StupidPassword, RegistrationForm(name=’john’, password=’password’).save())
|
Тестовое покрытие
Пользовательские истории обычно определяются на человеческих языках, чтобы сосредоточиться на пользовательском опыте.
Любая метрика, которая пытается оценить вероятность важного поведения SUT, еще не охвачена тестами. Наиболее популярные методы включают в себя различные виды покрытия кода : методы, обеспечивающие выполнение всех возможных операторов кода (или функций, или логических ветвей в коде) во время тестирования.
Тестовый цикл
Процесс разработки TDD. Учитывая, что разработка TDD начинается с написания нескольких тестов, ясно, что набор тестов начинается красным . Как только разработчик реализует все недавно протестированные функции, тесты становятся зелеными . Теперь разработчик может безопасно реорганизовать свою реализацию без риска появления новых ошибок, поскольку у него есть набор тестов, на который можно положиться. После завершения рефакторинга разработчик может начать цикл заново, написав больше тестов для получения новых функциональных возможностей. Таким образом, красно-зеленый-рефакторный цикл испытаний .
Test Double
Тестовые дубликаты — это объекты, которые тестовый код создает и передает в SUT для замены реальных зависимостей. Например, модульные тесты должны быть очень быстрыми и тестировать только определенную часть программного обеспечения.
По этим причинам его зависимости, такие как библиотеки взаимодействия с базой данных или файловой системой, обычно заменяются объектами, которые действуют в памяти, а не взаимодействуют с реальной базой данных или файловой системой.
Существует четыре основных категории двойников: манекены , подделки , заглушки и макеты .
Тестирование
Коллекция тестовых случаев, которые тестируют большую часть программного обеспечения. Как вариант, все тестовые случаи для конкретного программного обеспечения.
Тест-Первое Программирование
Тестирование белого ящика позволяет глубже проанализировать возможные проблемы в коде.
Тестирование в первую очередь — это более широкий термин для разработки, основанной на тестировании. В то время как TDD способствует тесной связи между написанием тестов (обычно модульных ) и написанием кода, программирование в первую очередь позволяет выполнять функциональные тесты высокого уровня. Однако различие в общем использовании редко отмечается, и два термина обычно используются взаимозаменяемо.
Модульное тестирование
Методика тестирования самого низкого уровня, состоящая из тестовых случаев для наименьших возможных единиц кода. Одиночный модульный тест обычно проверяет только определенное маленькое поведение, а случай модульного теста обычно охватывает все функциональные возможности конкретной отдельной функции или класса.
История пользователя
Единое описание определенной группы людей, желающих выполнить определенную задачу, используя SUT для достижения конкретной цели. Пользовательские истории обычно определяются на человеческих языках, используя простые, ориентированные на пользователя термины, чтобы избежать рассмотрения деталей реализации и вместо этого сосредоточиться на пользовательском опыте. Например:
1
|
As a user, I want to be able to find my friends on this website by my address book, instead of looking for them one by one, because that will save me a lot of time.
|
Тестирование белого ящика
Тестирование «белого ящика» — это методика тестирования, когда человек, выполняющий тестирование, знает или может прочитать о внутренностях SUT. В отличие от более распространенного тестирования «черного ящика», тестирование « белого ящика» позволяет глубже анализировать возможные проблемы в коде.
Например, конкретное граничное значение может не выглядеть как основанное исключительно на спецификации программного обеспечения, но это может быть очевидно из его реализации.
Кроме того, любые методики охвата тестированием обычно по определению являются частью тестирования белого ящика.