Зачем нужны unit тесты, если есть интеграционные?
я как нуб долго пытался это понять, а потом мне потребовалось отладить OAuth авторизацию. И озарение снизошло на меня...
Ну, смотри. Есть у тебя N подсистем (или компонентов), работающих вместе рамках целой системы. У каждой подсистемы есть M_i тест-кейсов (i=1..N). Чтобы покрыть всю систему интеграционными тестами, тебе их надо написать M_1*M_2*...*M_N штук - и это без учёта как раз ошибок взаимодействия подсистем в каких-то особых случаях. Т.е. это заведомо не реально, а юнит-тестов требуется намного меньше - M_1+M_2+...+M_N.
юнит-тестов требуется намного меньшеи что с того?
Цель то какая, писать меньше тестов? Давайте вообще их не писать.
точно локализовать причину ошибку,
четко разделить ответственность (между людьми и компонентами),
гарантированно проверить заданные сценарии работы
гарантированно проверить заданные сценарии работыюнита или системы?
Цель то какая, писать меньше тестов? Давайте вообще их не писать.цель: при сравнимых затратах увеличить кол-во проверяемых вариантов
юнита или системы?юнита в рамках системы
увеличить скорость поиска ошибки,да, пока единственное, что ясно. Но ценность этого не велика при нормальном коде.
точно локализовать причину ошибку,
четко разделить ответственность (между людьми и компонентами),
Человек обычно пишет несколько юнитов. Тесты на кусок, который пишет человек, это уже интеграционные тесты.
У каждой подсистемы есть M_i тест-кейсов (i=1..N). Чтобы покрыть всю систему интеграционными тестами, тебе их надо написать M_1*M_2*...*M_N штук - и это без учёта как раз ошибок взаимодействия подсистем в каких-то особых случаях.Кстати, неправильный подсчет, один интеграционный тест может выполнить сразу по K_i тест-кейсов подсистем. Т.е. подсистемы как бы друг друга потестят в рамках одного интеграционного тесткейса.
Тесты на кусок, который пишет человек, это уже интеграционные тестынекачественное определение. по нему любой тест на кусок кода больше одной строки уже является интеграционным.
если тесты пишутся на правильность работы стыка в жестко-заданном окружении, то это юнит-тесты.
если тесты пишутся на правильность взаимодействия (часто в слабо-заданном окружении), то это интеграционные тесты
некачественное определение.я к тому и веду, в методологии через тестирование нет четких определений, поэтому хорошая почва для спекуляций и мракобесия
цель: при сравнимых затратах увеличить кол-во проверяемых вариантовчто есть варианты?
и кому от их количества лучше?
Просто грамотная архитектура подразумевает такую декомпозицию системы на модули, при которой каждый модуль имеет самостоятельную ценность и работоспособность в отсутствии какого либо окружения (или при сильно упрощённом окружении). ИМХО, совсем не обязательно всё покрывать юнит-тестами, или тем более начинать с них разработку как в TDD: большинство юнит-тестов вообще получаются "мёртвые", т.е. пишутся один раз и потом не ломаются, или их поломка является следствием не бага, а изменения семантики. Но очень удобно, когда можно отлаживать отдельный модуль, не поднимая всю громоздкую систему, а юнит-тестирование побуждает делать именно такие модули.
Кстати, неправильный подсчет, один интеграционный тест может выполнить сразу по K_i тест-кейсов подсистем. Т.е. подсистемы как бы друг друга потестят в рамках одного интеграционного тесткейса.Ну, если у тебя интеграционные тесты эквивалентны работе программы NUnit, которая по очереди вызывает какие-то частные тесты модулей, тогда да
Но очень удобно, когда можно отлаживать отдельный модуль, не поднимая всю громоздкую систему, а юнит-тестирование побуждает делать именно такие модули.Если в процессе работы программисту удобно поднимать часть системы вместо всей системы, тогда и надо ставить именно эту цель — удобство разработки. Зачем ставить косвенную цель — юнит-тестирование — которая лишь побуждает?
Если в процессе работы программисту удобно поднимать часть системы вместо всей системы, тогда и надо ставить именно эту цель — удобство разработки. Зачем ставить косвенную цель — юнит-тестирование — которая лишь побуждает?Обычно отладка и интеграционное тестирование - это самые финальные этапы разработки. Когда до них доходит дело, что-то переделывать в архитектуре уже поздно. А все эти TDD побуждают думать об этом на раннем этапе, когда всей системы ещё нет.
А вообще, разработчики (как и все люди) - существа довольно противоречивые, и не всегда дисциплинированные. Иногда нужен особый искусственный стимул, чтобы они не делали сами себе хуже =) В программировании на C# роль этих стимулов играют, например, ключевые слова const, readonly, private, sealed и т.п.
Ну, если у тебя интеграционные тесты эквивалентны работе программы 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)
{
...
}
}
Когда это может быть нужно: Unit1 у тебя делится между разными проектами, а Unit2 - нет. То есть, там будет уже класс Unit3, для которого тебе придётся написать свой тест, покрывающий тест-кейсы Unit1, но уже по-другому. Во общем, получается опаснейшее дело - дублирование кода (в данном случае - тестов).
Когда это может быть нужно: Unit1 у тебя делится между разными проектами,вау , писать или не писать unit-тест зависит от того используется ли юнит в разных проектах или нет. А это же со временем меняется, сегодня в одном, завтра в разных проектах, или сегодня в разных, завтра в одном.
Поэтому лучше писать всегда. Это же очевидно.
В этом и сложность (и прелесть) работы архитектора, что нужно уметь такие вещи предугадывать. Чем лучше это удаётся - тем меньше потом геморроя.
Поэтому лучше писать всегда. Это же очевидно.Делать ненужную работу это очевидно?
А вообще, разработчики (как и все люди) - существа довольно противоречивые, и не всегда дисциплинированные. Иногда нужен особый искусственный стимул, чтобы они не делали сами себе хуже =) В программировании на C# роль этих стимулов играют, например, ключевые слова const, readonly, private, sealed и т.п.Эти ключевые слова очень даже естественны, а не искусственны. Они помогают работать в условиях жесткой ограниченности человеческой головы. А вот ставить косвенные цели это неестественно, да. Вот пример. Реализуя реальные цели, помечаем метод как private. А если ставим косвенную цель — юнит тестирование, то не можем поставить private, поскольку метод надо вызвать из теста.
В этом и сложность (и прелесть) работы архитектора, что нужно уметь такие вещи предугадывать.Качество предсказаний мерили? Или это ненаучно?
Если окружающие системы не твои ?
Если окружающие системы не твои ?тестирование группы систем это интеграционное тестирование. В чем вопрос?
Качество предсказаний мерили? Или это ненаучно?К сожалению, в этом деле пока что мало от науки, и много от ремесла. Иногда меряют точность оценки разработчиком или ПМ-ом сложности задачек.
Зачем нужны unit тесты, если есть интеграционные тесты?у нас в компании используются след виды тестов:
1) юнит тесты
2) функциональные тесты
3) интеграционные тесты
4) load\stress тесты
1) пишутся только для тех юнитов (классов\функций), назначений которых в целом ясно и их интерфейс вряд ли будет сильно меняться в будущем. пример: функции для нормализации double, класс Decimal и тд так же мы их используем для покрытия особо важных частей продукта (к примеру, ядро торговой системы, вычисление маржевых требований и тд)
2) здесь основная идея сделать фейковые внешние компоненты, так что наш тестируемый компонент будет работать с фейковыми, расположенными в том же процессе. взаимодействие с базой тоже можно абстрагировать.
3) здесь уже все удаленные (remote) компоненты также участвуют в тестировании, сюда же добавляется third-party программы и mysql
4) здесь участвуют воображаемые клиенты, администраторы, поставщики ликвидности (эмуляторы банков), сценарии с падением компонент, рестартом mysql и тд. тестов как таковых нет, просто идет активная работа всей системы. собранная статистика (кол-во ордеров, сделок, кол-во ошибок в логах и тд) в виде графиков высылается на емейлы для анализа вручную. на графиках отображены и пред результаты, так что можно следить за динамикой
coverage statistics выше всего после прохождения интеграционных тестов пункт 3) и они же выполняются дольше всего (конкретно в нашем случае)
в целом идея такая: использовать все виды тестов, т.к. они решают разные задачи
Зачем нужны интеграционные тесты, если есть системные?
Оставить комментарий
6yrop
Зачем нужны unit тесты, если есть интеграционные тесты?