Здравствуйте, mrTwister, Вы писали:
L>>Высококвалифицированный хирург поможет плохому танцору! T>Не понял, поясни мысль. Ты хочешь сказать, что рефакторинг не инвалидирует юнит-тесты?
Рефакторинг в идеале есть изменение структуры кода без изменения функционала. По определению, рефакторинг не должен инвалидировать юнит-тесты, так как они тестируют как раз функционал.
На деле ничечго идеального не бывает, и тесты явно, опосредованно или вообще непреднамеренно тестируют не только функционал, но и видимый интерфейс кода. Равно как и рефакторинг зачастую меняет не только и не столько структуру кода, но и заодно, а и иногда и исключительно, его логику.
И вот как раз в этих случаях инвалидация юнит-тестов — это очень, очень полезный эффект, который позволяет тебе, как разработчику, узнать, что твое улучшение кода заодно ломает интеграцию с системой, которую поддерживает другая команда. Узнать вот прямо здесь и сейчас, а не через два месяца, когда она сорвет следующий релиз цикл.
Случаи, когда юнит-тесты написаны профессиональным копателями от забора до обеда под руководством консультантов по code coverage, мне рассматривать не интересно.
Здравствуйте, landerhigh, Вы писали:
L>Рефакторинг в идеале есть изменение структуры кода без изменения функционала. По определению, рефакторинг не должен инвалидировать юнит-тесты, так как они тестируют как раз функционал.
Нет, рефакторинг — это перераспределение ответственности, в рамках которой удаляются и видоизменяются абстракции (юниты). Удаление и видоизменение юнитов не может не приводить к инвалидации юнит-тестов. Иначе, это не юнит-тесты, а интеграциюнные тесты, которым плевать на архитектуру, структуру кода и распределение ответственности.
L>И вот как раз в этих случаях инвалидация юнит-тестов — это очень, очень полезный эффект, который позволяет тебе, как разработчику, узнать, что твое улучшение кода заодно ломает интеграцию с системой, которую поддерживает другая команда. Узнать вот прямо здесь и сейчас, а не через два месяца, когда она сорвет следующий релиз цикл.
Узнать, что сломана интеграция позволяют интеграционные тесты, по определению. Юнит-тестам на интеграцию наплевать. Юнит-тесты могут только в лучшем случае продублировать мое представление о внешней системе, то есть я сначала в коде фиксирую свое представление о внешней системе, потом его же дублирую в юнит-тестах. Чем помогает это дублирование не понятно, так как если я неправильно представляю интерфейс внешней системы, то я его и в юнит-тесте тоже неправильно продублирую.
Здравствуйте, mrTwister, Вы писали:
T>Узнать, что сломана интеграция позволяют интеграционные тесты, по определению. Юнит-тестам на интеграцию наплевать. Юнит-тесты могут только в лучшем случае продублировать мое представление о внешней системе, то есть я сначала в коде фиксирую свое представление о внешней системе, потом его же дублирую в юнит-тестах. Чем помогает это дублирование не понятно, так как если я неправильно представляю интерфейс внешней системы, то я его и в юнит-тесте тоже неправильно продублирую.
Тем, что обнаружение проблемы на этапе юнит тестирования дешевле, чем на любом другом этапе.
Здравствуйте, landerhigh, Вы писали:
T>>Только интеграционные проблемы юнит-тестами не обнаруживаются, для этого интеграционные тесты нужны
L>Поломка пубилчного API или изменение декларируемого поведения прекрасно обнаруживается.
О каком публичном API идет речь? Если это REST, или GRPC какой-нибудь, то юнит-тесты бесполезны, тут надо только настоящий веб-сервер запускать, а это уже интеграционный тест.
Здравствуйте, mrTwister, Вы писали:
T>О каком публичном API идет речь? Если это REST, или GRPC какой-нибудь, то юнит-тесты бесполезны, тут надо только настоящий веб-сервер запускать, а это уже интеграционный тест.
Что мешает сделать мок в районе отправки/получения данных?
Здравствуйте, steep8, Вы писали:
T>>О каком публичном API идет речь? Если это REST, или GRPC какой-нибудь, то юнит-тесты бесполезны, тут надо только настоящий веб-сервер запускать, а это уже интеграционный тест. S>Что мешает сделать мок в районе отправки/получения данных?
Если инженера волнует качество и эффективность его работы, и хотя бы чуть-чуть заботит поддерживаемость кода — именно так и делают.
Когда кодеру лень писать юнит-тесты, он ищет оправдания.
Здравствуйте, steep8, Вы писали:
T>>О каком публичном API идет речь? Если это REST, или GRPC какой-нибудь, то юнит-тесты бесполезны, тут надо только настоящий веб-сервер запускать, а это уже интеграционный тест.
S>Что мешает сделать мок в районе отправки/получения данных?
И как этот мок поможет обнаружить поломку публичного API?
Здравствуйте, mrTwister, Вы писали:
T>Нет, рефакторинг — это перераспределение ответственности, в рамках которой удаляются и видоизменяются абстракции (юниты). Удаление и видоизменение юнитов не может не приводить к инвалидации юнит-тестов. Иначе, это не юнит-тесты, а интеграциюнные тесты, которым плевать на архитектуру, структуру кода и распределение ответственности.
Так ют должны тестировать не абстракции, а реализации (тело) методов, т.е. интерфейсы по сути. И если тут приходится что-то сильно
менять, значит дизайн не очень чтобы очень.
Здравствуйте, Sharov, Вы писали:
S>Так ют должны тестировать не абстракции, а реализации (тело) методов, т.е. интерфейсы по сути. И если тут приходится что-то сильно S>менять, значит дизайн не очень чтобы очень.
Естественно, дизайн не очень, именно поэтому его и рефакторят. Если бы с дизайном было бы всё нормально, то рефакторинг и не нужен был бы.
Здравствуйте, mrTwister, Вы писали:
S>>Так ют должны тестировать не абстракции, а реализации (тело) методов, т.е. интерфейсы по сути. И если тут приходится что-то сильно S>>менять, значит дизайн не очень чтобы очень. T>Естественно, дизайн не очень, именно поэтому его и рефакторят. Если бы с дизайном было бы всё нормально, то рефакторинг и не нужен был бы.
От дизайна объем рефакторинга и поломанных ют и зависит.
Здравствуйте, mrTwister, Вы писали:
T>>>О каком публичном API идет речь? Если это REST, или GRPC какой-нибудь, то юнит-тесты бесполезны, тут надо только настоящий веб-сервер запускать, а это уже интеграционный тест. S>>Что мешает сделать мок в районе отправки/получения данных? T>И как этот мок поможет обнаружить поломку публичного API?
Не очень понятно что конкретно ты хочешь обнаружить. Отпрпавка/получение это транспорт, и частью API как правило не является. Можно же протестировать, что некий REST-запрос правильно конвертируется в некий DTO. Зачем для этого работающий веб-сервер не очень ясно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Sharov, Вы писали:
T>>Естественно, дизайн не очень, именно поэтому его и рефакторят. Если бы с дизайном было бы всё нормально, то рефакторинг и не нужен был бы. S>От дизайна объем рефакторинга и поломанных ют и зависит.
Ну то есть если рефакторинг не нужен, то юнит-тесты рефакторингу не помешают. Спасибо, Кэп!
Здравствуйте, mrTwister, Вы писали:
T>И как этот мок поможет обнаружить поломку публичного API?
Для тех, у кого публичный API — это просто описание контракта в схеме — никак.
У некоторых старообрядцев "публичный API" включает в себя также и декларируемое или подразумеваемое поведение. И вот тут — очень даже "как".
Например, отрефакторил ты модуль в целях оптимизации. Заменил std::map на std::unordered_map.
Функциональность не изменилась, но записи в ответе на запрос больше не упорядочены по алфавиту.
Сломался юнит-тест, который полагался на определенный порядок записей в ответе.
Здравствуйте, ·, Вы писали:
·>Не очень понятно что конкретно ты хочешь обнаружить. Отпрпавка/получение это транспорт, и частью API как правило не является.
Ну вот мне было выше обещано, что с помощью юнит-тестов можно быстро обнаруживать слом публичного API внешней системы. Я пытаюсь понять, как именно это сделать.
·>Можно же протестировать, что некий REST-запрос правильно конвертируется в некий DTO. Зачем для этого работающий веб-сервер не очень ясно.
Не очень понятно, как без web-сервера можно обработать http запрос. Иначе, мы будем тестировать не то, как REST запрос конвертируется в DTO, а, например, парсинг JSON. Только зачем нам надо это тестировать (учитывая, что это делается третьесторонней библиотекой как правило), и как это поможет быстро обнаружить слом публичного API внешней системы
Здравствуйте, mrTwister, Вы писали:
T>·>Не очень понятно что конкретно ты хочешь обнаружить. Отпрпавка/получение это транспорт, и частью API как правило не является. T>Ну вот мне было выше обещано, что с помощью юнит-тестов можно быстро обнаруживать слом публичного API внешней системы. Я пытаюсь понять, как именно это сделать.
"внешней системы"? Этого вроде не было. Внешняя система тестируется conformance-тестами и к твоему коду отношения не имеет.
T>·>Можно же протестировать, что некий REST-запрос правильно конвертируется в некий DTO. Зачем для этого работающий веб-сервер не очень ясно. T>Не очень понятно, как без web-сервера можно обработать http запрос. Иначе, мы будем тестировать не то, как REST запрос конвертируется в DTO, а, например, парсинг JSON. Только зачем нам надо это тестировать (учитывая, что это делается третьесторонней библиотекой как правило), и как это поможет быстро обнаружить слом публичного API внешней системы
Не очень понятно, зачем тестировать и быстро обнаруживать ошибки в том как web-сервер обрабатывает http-запросы. Этим должны заниматься разработчики веб-сервера. Ну я понимаю, что должен быть небольшой end-to-end интеграционный тест, который проверяет, что твоё приложение правильно запускается, открывает нужные порты, и отвечает на какой-нибудь простой запрос.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, landerhigh, Вы писали:
L>std::unordered_map. L>Сломался юнит-тест, который полагался на определенный порядок записей в ответе.
Реальный случай: юнит-тест сравнивал список, а в логике в кишках использвался hashmap, и при смене версии JVM, порядок стал рандомным. Лечилось выставлением initial seed перед каждым тестом.
Здравствуйте, landerhigh, Вы писали:
L>Например, отрефакторил ты модуль в целях оптимизации. Заменил std::map на std::unordered_map. L>Функциональность не изменилась, но записи в ответе на запрос больше не упорядочены по алфавиту.
Ок, то есть речь идет о тестировании публичного API библиотеки. Но если тест тестирует целую библиотеку через её публичный API, то это не юнит-тест, а интеграционный.
Здравствуйте, Тёмчик, Вы писали:
Тё>Реальный случай: юнит-тест сравнивал список, а в логике в кишках использвался hashmap, и при смене версии JVM, порядок стал рандомным. Лечилось выставлением initial seed перед каждым тестом.
В нашем реальном случае оказалось, что все интеграционные тесты использовали датасет, в котором вызов API возвращал ровно один элемент.
Более того, 99.9% вызовов в продакшене тоже имели дело с только одним элементом.
Но два раза в год (угадайте, когда) "умные" девайсы, работающие на слабой однокристалке, запрашивали все данные.
И вот тут случился "упс".