Зачем нужны unit тесты, если есть интеграционные?

6yrop

Зачем нужны unit тесты, если есть интеграционные тесты?

Kira

я как нуб долго пытался это понять, а потом мне потребовалось отладить OAuth авторизацию. И озарение снизошло на меня...

freezer

Ну, смотри. Есть у тебя N подсистем (или компонентов), работающих вместе рамках целой системы. У каждой подсистемы есть M_i тест-кейсов (i=1..N). Чтобы покрыть всю систему интеграционными тестами, тебе их надо написать M_1*M_2*...*M_N штук - и это без учёта как раз ошибок взаимодействия подсистем в каких-то особых случаях. Т.е. это заведомо не реально, а юнит-тестов требуется намного меньше - M_1+M_2+...+M_N.

6yrop

юнит-тестов требуется намного меньше
и что с того?

6yrop

Цель то какая, писать меньше тестов? Давайте вообще их не писать.

Dasar

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

6yrop

гарантированно проверить заданные сценарии работы
юнита или системы?

Dasar

Цель то какая, писать меньше тестов? Давайте вообще их не писать.
цель: при сравнимых затратах увеличить кол-во проверяемых вариантов

Dasar

юнита или системы?
юнита в рамках системы

6yrop

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

четко разделить ответственность (между людьми и компонентами),

Человек обычно пишет несколько юнитов. Тесты на кусок, который пишет человек, это уже интеграционные тесты.

6yrop

У каждой подсистемы есть M_i тест-кейсов (i=1..N). Чтобы покрыть всю систему интеграционными тестами, тебе их надо написать M_1*M_2*...*M_N штук - и это без учёта как раз ошибок взаимодействия подсистем в каких-то особых случаях.
Кстати, неправильный подсчет, один интеграционный тест может выполнить сразу по K_i тест-кейсов подсистем. Т.е. подсистемы как бы друг друга потестят в рамках одного интеграционного тесткейса.

Dasar

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

6yrop

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

6yrop

цель: при сравнимых затратах увеличить кол-во проверяемых вариантов
что есть варианты?
и кому от их количества лучше?

freezer

Все эти методологии - большое зло, если ими злоупотребляют =)
Просто грамотная архитектура подразумевает такую декомпозицию системы на модули, при которой каждый модуль имеет самостоятельную ценность и работоспособность в отсутствии какого либо окружения (или при сильно упрощённом окружении). ИМХО, совсем не обязательно всё покрывать юнит-тестами, или тем более начинать с них разработку как в TDD: большинство юнит-тестов вообще получаются "мёртвые", т.е. пишутся один раз и потом не ломаются, или их поломка является следствием не бага, а изменения семантики. Но очень удобно, когда можно отлаживать отдельный модуль, не поднимая всю громоздкую систему, а юнит-тестирование побуждает делать именно такие модули.

freezer

Кстати, неправильный подсчет, один интеграционный тест может выполнить сразу по K_i тест-кейсов подсистем. Т.е. подсистемы как бы друг друга потестят в рамках одного интеграционного тесткейса.
Ну, если у тебя интеграционные тесты эквивалентны работе программы NUnit, которая по очереди вызывает какие-то частные тесты модулей, тогда да :D

6yrop

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

freezer

Если в процессе работы программисту удобно поднимать часть системы вместо всей системы, тогда и надо ставить именно эту цель — удобство разработки. Зачем ставить косвенную цель — юнит-тестирование — которая лишь побуждает?
Обычно отладка и интеграционное тестирование - это самые финальные этапы разработки. Когда до них доходит дело, что-то переделывать в архитектуре уже поздно. А все эти TDD побуждают думать об этом на раннем этапе, когда всей системы ещё нет.
А вообще, разработчики (как и все люди) - существа довольно противоречивые, и не всегда дисциплинированные. Иногда нужен особый искусственный стимул, чтобы они не делали сами себе хуже =) В программировании на C# роль этих стимулов играют, например, ключевые слова const, readonly, private, sealed и т.п.

6yrop

Ну, если у тебя интеграционные тесты эквивалентны работе программы NUnit, которая по очереди вызывает какие-то частные тесты модулей, тогда да
Надо ли писать юнит тест для Unit1:
 
public class Unit2
{
public string M1(string request)
{
var unit1 = new Unit1();
... unit1.M1(false);
...
... unit1.M1(true);
...
}
}

public class Unit1
{
public xxx M1(bool b)
{
...
}
}

freezer

В каких-то случаях надо, в каких-то - нет.
Когда это может быть нужно: Unit1 у тебя делится между разными проектами, а Unit2 - нет. То есть, там будет уже класс Unit3, для которого тебе придётся написать свой тест, покрывающий тест-кейсы Unit1, но уже по-другому. Во общем, получается опаснейшее дело - дублирование кода (в данном случае - тестов).

6yrop

Когда это может быть нужно: Unit1 у тебя делится между разными проектами,
вау :D , писать или не писать unit-тест зависит от того используется ли юнит в разных проектах или нет. А это же со временем меняется, сегодня в одном, завтра в разных проектах, или сегодня в разных, завтра в одном.

yroslavasako

Поэтому лучше писать всегда. Это же очевидно.

freezer

В этом и сложность (и прелесть) работы архитектора, что нужно уметь такие вещи предугадывать. Чем лучше это удаётся - тем меньше потом геморроя.

6yrop

Поэтому лучше писать всегда. Это же очевидно.
Делать ненужную работу это очевидно? :confused:

6yrop

А вообще, разработчики (как и все люди) - существа довольно противоречивые, и не всегда дисциплинированные. Иногда нужен особый искусственный стимул, чтобы они не делали сами себе хуже =) В программировании на C# роль этих стимулов играют, например, ключевые слова const, readonly, private, sealed и т.п.
Эти ключевые слова очень даже естественны, а не искусственны. Они помогают работать в условиях жесткой ограниченности человеческой головы. А вот ставить косвенные цели это неестественно, да. Вот пример. Реализуя реальные цели, помечаем метод как private. А если ставим косвенную цель — юнит тестирование, то не можем поставить private, поскольку метод надо вызвать из теста.

6yrop

В этом и сложность (и прелесть) работы архитектора, что нужно уметь такие вещи предугадывать.
Качество предсказаний мерили? Или это ненаучно?

forenius

Если окружающие системы не твои ?

6yrop

Если окружающие системы не твои ?
тестирование группы систем это интеграционное тестирование. В чем вопрос?

freezer

Качество предсказаний мерили? Или это ненаучно?
К сожалению, в этом деле пока что мало от науки, и много от ремесла. Иногда меряют точность оценки разработчиком или ПМ-ом сложности задачек.

Maurog

Зачем нужны unit тесты, если есть интеграционные тесты?
у нас в компании используются след виды тестов:
1) юнит тесты
2) функциональные тесты
3) интеграционные тесты
4) load\stress тесты
1) пишутся только для тех юнитов (классов\функций), назначений которых в целом ясно и их интерфейс вряд ли будет сильно меняться в будущем. пример: функции для нормализации double, класс Decimal и тд так же мы их используем для покрытия особо важных частей продукта (к примеру, ядро торговой системы, вычисление маржевых требований и тд)
2) здесь основная идея сделать фейковые внешние компоненты, так что наш тестируемый компонент будет работать с фейковыми, расположенными в том же процессе. взаимодействие с базой тоже можно абстрагировать.
3) здесь уже все удаленные (remote) компоненты также участвуют в тестировании, сюда же добавляется third-party программы и mysql
4) здесь участвуют воображаемые клиенты, администраторы, поставщики ликвидности (эмуляторы банков), сценарии с падением компонент, рестартом mysql и тд. тестов как таковых нет, просто идет активная работа всей системы. собранная статистика (кол-во ордеров, сделок, кол-во ошибок в логах и тд) в виде графиков высылается на емейлы для анализа вручную. на графиках отображены и пред результаты, так что можно следить за динамикой
coverage statistics выше всего после прохождения интеграционных тестов пункт 3) и они же выполняются дольше всего (конкретно в нашем случае)
в целом идея такая: использовать все виды тестов, т.к. они решают разные задачи

katrin2201

Зачем нужны интеграционные тесты, если есть системные?
Оставить комментарий
Имя или ник:
Комментарий: