Вы немного не правильно восприняли мой комментарий. Я знаю как работает Spectre и знаю ограничения на его применимость. Я скорее о том, что «забить» не получится — всем придется как минимум пообновлять браузеры. Т.е. почти у всех сейчас установлен дырявый хром, в котором эта уязвимость есть в эксплуатируемом виде. А фикс, по планам, выйдет 23-го января. Вопрос не в величине дырки, вопрос в распространенности. Т.е. да, куча народу прочитала статью. Сколько из них пошло и отключило у себя SharedArrayBuffer?
«Еденичные уязвимые приложения» и прочите «гаджеты» — это, прежде всего, браузеры. Spectre позволяет читать память браузера из Javascript. Авторы атаки предоставили POC для Chrome. И именно из-за этого вся движуха со срочными фиксами для браузеров, включением Site Isolation и отключением SharedArrayBuffer — для использования атаки достаточно просто заманить пользователя на сайт. Т.е. это не какая-то теоретическая атака, в которой
всё очень хрупко, что и позволяет, приняв рюмку коньяка, забить.
… а вполне конкретная дырка, как минимум в Chrome.
Службы MagicCardService и SlackResponseService выполняют разные функции и поэтому отделены друг от друга.
Это применение SRP, а не ISP. ISP — это когда один класс предоставляет разным клиентам разные интерфейсы.
LSP к "не возвращает null, не содержит ненужных классов или аннотаций" никакого отношения не имеет. Для проявления LSP должна быть хоть какая-то иерархия классов с разным поведением. Его просто нельзя показать на одном SlackResponseService/Impl.
Т.е. статья о So..D, а не о SOLID, с явным перекосом в сторону S.
Нет, я вполне доволен и Тостером и его нишей. Мне просто интересно, почему для общий для SO и Тостера проблем — нытье старожилов, желание некоторых пользователей привлечь внимание к вопросам, указаний пользователей на проблемы с модерацией — разными платформами принимаются противоположные решения. Т.е. мне, пользователю SO, а не тостера, совершенно все равно, взлетят ли у вас платные конкурсы, или весь топ будет забит простыми вопросами за полбакса :) Я пытаюсь понять, что именно побудило вас выбрать вариант «делить вопросы по категориям» вместо «донести до community, что простые вопросы — наше все».
Т.е. да, «старожилы хотят», но я не представляю механизма для эффективного разделения трех уровней «начинающих» — intern, junior, middle — на большом потоке вопросов. Поделитесь подробностями реализации?
Скорее всего вы вкладываете в слово «пользуюсь» разный смысл по отношению к enSO и к Тостеру. На тостере вы активно задаете вопросы / даете ответы. А на SO вы попадаете из гугла, и в профиль логинились последний раз 10 месяцев назад :)
Т.е. вы получили странный результат опроса, но не стали выяснять в чем причина. Точно так же, получили в результатах в качестве плюсов SO «Более сложные вопросы» и «Лучшая модерация» — и тоже не стали выяснять причину.
На SO старожилы тоже ныли по поводу нехватки «более сложных вопросов» и засилья новичков. И на русском, и на английском. Вы сделали из подобного нытья вывод, что вопросы надо (как-то?) делить по категориям сложности. Т.е. вводить какие-то изменения, которые потребуют усилий для реализации и поддержания, затронут всех, но которые принесут выгоду только нескольким «старожилам». На том же ruSO для решения проблемы хватило поста на мете. На enSO — хватило поста в блоге Jeff Atwood.
Как для не-пользователя тостера, можете пояснить, что имелось ввиду под
Можно просматривать все вопросы
А на SO нельзя просматривать все запросы?
Вы попросили пользователей Тостера сравнить SO и Тостер. Естественно, вы получили в преимуществах тостера «Более приятный интерфейс» и «Русский язык» — т.к. опрашивали тех, кто уже сделал выбор в пользу тостера, и тех, кто попадает из гугла на enSO, а не ruSO.
Проведите точно такой же опрос среди пользователей SO — и получите противоположные результаты.
Ну так и я о том же. Стандартная защита от SQL-инъекций — параметризированные запросы (через PDO в случае с PHP). В статье об обходе параметризации — ни слова. Все остальное — это не защитные средства, а «защитные средства». А в названии статьи у вас кавычек почему-то нет.
Неважно о чем сама статья. В конце статьи есть заключение. В нем написано «Тщательно проверять входящие данные». Совершенно дикий совет. Будь там написано «используйте параметризированный SQL» — статья была бы хорошей. Правда, очень короткой, и ссылку на WAF в нее не получичилось бы вставить :)
А так — это не современная статья по защите от инъекций, а просто набор хитрых способов обхода «защитных костылей».
Да, QA может подсказать. Но другие разработчкими справляются с этим намного лучше и быстрее. Т.е. гораздо эффективнее ввести peer code review (через те же пулл реквесты) и получить заодно повышение code ownership, чем надеятся что QA смогут что-то в коде увидеть, и тем более заранее написать кейсы на юнит-тесты (это вообще нереально в более-менее нетривиальном приложении).
Юнит-тесты (если они именно юнит, а не интеграционные) не пишутся по тесткейсам от QA. Юнит-тесты покрывают небольшие куски кода — отдельные методы, отдельные классы, отдельные вызовы в коде.
«SomeService при вызове SaveSomething, при условии что зависимость ISomeRepo вернет минимум 5 строк, в вызове GetSomeItems() заполнит поле SomeField у сохраняемого объекта значением SomeValue» — вот что проверяет юнит тест. Это просто проверка на наличие какого-то условия или какого-то вызова в коде.
QA обычно ничего не знаю о классах и об отдельных методах. Поэтому QA не может полноценно ревьювить и дополнять юнит-тесты. И дело не только в знании конкретного ЯП или фреймворка. Дело в том, что количество юнит тестов должно соответствовать количеству проверок и прочих методов принятия решений в коде. Собственно, в этом и состоит работа разработчика — переложить требования с человеческого (в виде User Story, документации, чего угодно) на язык if-ов и while-ов.
Современные языки программирования хорошо приспособлены для описания бизнес-логики. Они позволяют делать это гораздо компактнее русского или английского языков. Поэтому полноценное описание функционала (спецификация), если она действительно описывает весь функционал, должна несколько раз превышать по объему код приложения. А т.к. нет способов поддерживать и рефакторить текст спецификации с той же легкостью, что и код приложения — то написание такой «полноценной» спецификации должно занимать намного больше времени, чем написание кода. Именно поэтому все спецификации обычно далеки от полноты, и попытки «сгенерировать код по спеке» обречены на провал.
То же самое с тесткейсами для юнит-тестов. Их должно быть столько же, сколько проверок. Более того, написание кейсов для юнит-тестов QA, заранее, подразумевает что QA настолько хорошо представляет себе структуру приложения, что может точно сказать в каком методе, где именно и как именно будет написан каждый if. Если у вас QA так круты — то разработчики вам не нужны. Ну и объем таких тексткейсов будет точно так же превышать объем кода.
Поэтому да, для юнит-тестов разработчик сам придумывает покрытие. Точно так же, как он сам придумывает, где к коде написать if. И проверяют юнит-тесты именно наличие if-а или наличие вызова. Загораясь красным, когда кто-то лажанет при мерже, или неудачно подрефакторит. Или просто случайно выкосит проверку.
Те тесты, которые (иногда) пишутся по кейсам (или могут быть представлены в виде кейсов), по принципу один кейс — один тест — это или интеграционные или функциональные тесты. Т.е. это или selenium и прочие тыкалки интерфейса, тесты на всю систему в сборе (включая базу), или тесты «на бэкенд в сборе + базу».
Я не делю тесты по полезности для QA — это вообще не имеет смысла. Тесты пишутся (или прогоняются, если они ручные) не ради QA. Они пишутся ради обеспечения качества продукта. За качество надо платить, в основном, временем разработчиков (кодеров и тестировщиков).
Но вот ваша статья не только делит полезность тестов для разработчиков по технологическому признаку. Вы прямо противопоставляете принципиально разные виды тестирования, и выдаете из этого целую статью.
По сравнению с ручным тестированием, автоматизированное имеет как достоинства так и явные недостатки
Точно так же можно написать статью о том, что «SQL по сравнению с JavaScript имеет как достоинства, так и явные недостатки», с кучей очень обоснованных доводов в пользу как SQL, так и JS.
Скорее всего, у автора все в порядке с пониманием темы. Просто статья писалась ради второй части (которой пока нет), в которой смешанные в кучу виды тестирования разделят и разложат по полочкам.
Совершенно непонятно, о каких именно тестах написана статья. В тексте явно упоминается selenium, «вернуть задачу к разработчикам», хрупкость тестов при смене интерфейса, в преимущество ручных тестов вписана «гибкость» на примере тестирования в сафари. Т.е. вроде как речь об автоматизации работы QA.
И тут же, в ту же кучу — тесты до кода, правка тестов самими разработчиками, упоминания юнит тестов, «Тесты — такой же код» — т.е. явно не автоматизация работы QA, а именно юнит-тесты. Ну или в крайнем случае интеграционные. Юнит тесты призваны экономить время разработчиков. QA вообще не должно быть никакого дела до наличия или отсутствия юнит-тестов. Фраза «вернуть задачу к разработчикам при красном юнит тесте» — не имеет смысла — билд просто не должнен доходить до QA при красных юнит/интеграционных тестах.
Юнит-тесты — не альтернатива ручному тестированию. И, тем более, не аналог и не замена автоматизированному тестированию UI, вроде selenium. Это просто другой вид тестирования. А вы вписали в общий список все достоинства и все недостатки разных видов тестирования, даже тех, которые вообще в зону ответственности QA не входит. И перемешали. Не хватает только пунктов «selenium не умеет самостоятельно проводить penetration test-ы» и «юнит-тестами тяжело протестировать документацию» :)
С таким же успехом можно было расписать достоинства и недостатки JavaScript, достоинства .NET/Java, lua-скриптов, powershell, SQL, а потом перемешать это в один список «Блеск и нищета написания кода».
Т.е. вроде как была идея написать интересный противоречивый пост с интригой и открытой концовкой. Но выглядит так, как будто статью писал не лидер backend разработки, а маркетолог, которому выдали брошюру «разные виды тестирования для чайников» :(
Зависит от проекта. Когда-то давно пытались прикручивать самописный эмулятор — работало для простых запросов, но на чем-то сложном начинались проблемы. Т.е. для простых запросов оказалось удобнее использовать репозиторий (как в статье) и мокать его. Для сложных — наткнулись на разницу эмулятора и реальной базы.
На текущем проекте — в базе лежит часть логики (права доступа, хаки для иерархических данных и прочее) — и интеграционные тесты требуют реальной базы. Вынести логику из базы полностью не получится (точнее, получится, но работать будет гораздо медленее). И ORM — не EF :)
У меня интеграционных тестов > 8000. Оцените время выполнения при использовании вашего фреймворка :) Медленность тестов с базой — это ужасно плохо.
TDD и «писать тесты до кода» — разные вещи. Я не приверженец TDD, и не предлагаю вам строить архитектуру только на основании тестов. И вообще (вынуждненно, много легаси кода) предпочитаю интеграционные тесты. Но их можно писать до кода, а можно — после. Одни и те же тесты на один и тот же код могут приносят разный профит в зависимости от момента их написания. И дают разный эффект на мотивацию.
Тесты после кода:
[время на написание кода] + [время на ручной протык разработчиком и фикс] + [время на написание тестов]
Недостатки:
Разработчик пишет сразу большие куски функционала, которые нужно покрывать несколькими тестами (как у вас в статье). Из-за этого вы получаете меньше тестов, с дырками в покрытии (уберется необходимость скидки — удалят тест — не будет покрыт кейс выборки без скидки)
Разработчик воспринимает код после протыка и фикса как «готовый» — и подсознательно считает тесты ненужными, или считает их «дополнительной работой», а не неотъемлимой частью кода. Которая поможет в будущем кому-то (не ему) вносить изменения.
Тесты до кода:
[время на написание теста] + [время на написание кода]
Тот же код, те же тесты — но нет необходимости в активном ручном протыке. И нет ощущения, что вы делате «дополнительную» работу за других. Тесты начинают помогать разработчику вот прямо сейчас, а не когда-нибудь потом. Это прямой стимул, который заодно создает сайдэффект «код не сломается в будущем». Win-Win.
Внедрение тестов на проекте — это проблема психологии, а не техническая (как писать и запускать) и не менеджерская (выделить время). Нужно сделать так, чтобы разработчики чувствовали себя неуютно при попытке нафигачить код без тестов. Им должно быть физически неудобно это делать. «Лень запускать UI и проверять руками, проще тест написать» — вот эффект, который нужно получить.
Попробуйте писать свои интеграционные тесты до кода. Почувствуете разницу.
15 минут на 1000 тестов — это ужасно долго. У меня на проекте 12800 тестов, из них — 9700 серверных, из которых больше 8000 — интеграционные на базе (так сложилось). Время прогона — 20 минут на CI, примерно 15 минут — на дев-машине.
Если бы мы не вложились в CI (билд сервера с SSD + много локальных хаков в тестовом фреймворке) — мы бы получили почти 3 часа на прогон тестов. Вы готовы ждать 2-3 часа перед каждым пушем? А потом еще 3 часа на прогонку на билд-сервере? Ок, у нас на проекте мы смогли вставить хаки и сократить время выполнения. Но я не уверен, сможете ли вы сделать то же самое в своем коде.
Fear-driven development? Бить по рукам, лишать премии и прочие кнуты может позволить себе только галера, на которой студентов держат за счет того, что они не знают другой жизни и боятся поменять работу. На продуктовой разработке это просто убьет мотивацию и принесет больше вреда, чем пользы.
Если у вас разработчиков приходится лишать премии за нарушение принятого процесса — значит они не понимают, зачем конкретные практики в вашем процессе приняты. И битьем по рукам вы только усугубите ситуацию — спрячете проблему, загоните ее внутрь — но не решите.
Есть более гуманные способы — например снизить потери от «красных» коммитов активным бранчеванием (поломает дев свою ветку — всех остальных это не затронет). Процесс должен помогать разработчикам творить — создавать продукт. А не держать их в узде.
Насчет материализации — я имел ввиду именно факт дополнительного создания еще одного набора (отслеживаемых?) объектов Products, из которых уже потом Linq to Objects делает Select, а не собственно выполнения запроса. Суть в том, что при переписывании готового кода поменялся механизм выполнения запроса, возможно не в лучшую сторону, никто (по легенде поста) это не заметил, и все это подперто одним (!) тестом.
Настоящая проблема с примером из первой части в том, что вы быстро набросали полностью рабочий вариант «самым простым способом». Наверняка даже протестировали его вручную. Он готов. И все телодвижения, которые вы делаете после этого, не добавляют продукту, в котором этот код написан, никакой ценности. Если хочется написать покрытый тестами код — то стоит писать тесты до кода.
Тесты после кода, особенно если под них приходится править свеженаписанный рабочий и уже протестированный (запущенный пару раз) код — это пустая трата времени.
Вы с большей вероятностью добавите багов, чем почините. Видно даже на вашем примере — вы используете `IEnumerable` в репозитории, что вызывает выполнение запроса и материализацию продуктов прямо в момент вызова `GetFeaturedProducts`, а не позже, как это кажется по коду (и как происходило в оригинальном примере).
Попробуйте расписать свой же пример, но через написание двух тестов до кода — «Необходимо отобразить простой список рекомендуемых товаров» и «если список просматривает привилегированный пользователь, то цена всех товаров должна быть снижена на 5 процентов» — это покажет тесты с лучшей стороны.
Интеграционные тесты на базе — не панацея. У них есть один огромный недостаток — они медленные. Т.е. они кажутся хорошей идеей, пока их меньше 10000 штук. Потом они начинают занимать час даже на приличном железе, и вам придется вкладываться в инфраструктуру для билдов. К тому же разработчики перестанут запускать тесты локально и начнут пушить со словами «мне повезет».
… а вполне конкретная дырка, как минимум в Chrome.
Это применение SRP, а не ISP. ISP — это когда один класс предоставляет разным клиентам разные интерфейсы.
LSP к "не возвращает null, не содержит ненужных классов или аннотаций" никакого отношения не имеет. Для проявления LSP должна быть хоть какая-то иерархия классов с разным поведением. Его просто нельзя показать на одном SlackResponseService/Impl.
Т.е. статья о So..D, а не о SOLID, с явным перекосом в сторону S.
Т.е. да, «старожилы хотят», но я не представляю механизма для эффективного разделения трех уровней «начинающих» — intern, junior, middle — на большом потоке вопросов. Поделитесь подробностями реализации?
На SO старожилы тоже ныли по поводу нехватки «более сложных вопросов» и засилья новичков. И на русском, и на английском. Вы сделали из подобного нытья вывод, что вопросы надо (как-то?) делить по категориям сложности. Т.е. вводить какие-то изменения, которые потребуют усилий для реализации и поддержания, затронут всех, но которые принесут выгоду только нескольким «старожилам». На том же ruSO для решения проблемы хватило поста на мете. На enSO — хватило поста в блоге Jeff Atwood.
А на SO нельзя просматривать все запросы?
Вы попросили пользователей Тостера сравнить SO и Тостер. Естественно, вы получили в преимуществах тостера «Более приятный интерфейс» и «Русский язык» — т.к. опрашивали тех, кто уже сделал выбор в пользу тостера, и тех, кто попадает из гугла на enSO, а не ruSO.
Проведите точно такой же опрос среди пользователей SO — и получите противоположные результаты.
А так — это не современная статья по защите от инъекций, а просто набор хитрых способов обхода «защитных костылей».
«SomeService при вызове SaveSomething, при условии что зависимость ISomeRepo вернет минимум 5 строк, в вызове GetSomeItems() заполнит поле SomeField у сохраняемого объекта значением SomeValue» — вот что проверяет юнит тест. Это просто проверка на наличие какого-то условия или какого-то вызова в коде.
QA обычно ничего не знаю о классах и об отдельных методах. Поэтому QA не может полноценно ревьювить и дополнять юнит-тесты. И дело не только в знании конкретного ЯП или фреймворка. Дело в том, что количество юнит тестов должно соответствовать количеству проверок и прочих методов принятия решений в коде. Собственно, в этом и состоит работа разработчика — переложить требования с человеческого (в виде User Story, документации, чего угодно) на язык if-ов и while-ов.
Современные языки программирования хорошо приспособлены для описания бизнес-логики. Они позволяют делать это гораздо компактнее русского или английского языков. Поэтому полноценное описание функционала (спецификация), если она действительно описывает весь функционал, должна несколько раз превышать по объему код приложения. А т.к. нет способов поддерживать и рефакторить текст спецификации с той же легкостью, что и код приложения — то написание такой «полноценной» спецификации должно занимать намного больше времени, чем написание кода. Именно поэтому все спецификации обычно далеки от полноты, и попытки «сгенерировать код по спеке» обречены на провал.
То же самое с тесткейсами для юнит-тестов. Их должно быть столько же, сколько проверок. Более того, написание кейсов для юнит-тестов QA, заранее, подразумевает что QA настолько хорошо представляет себе структуру приложения, что может точно сказать в каком методе, где именно и как именно будет написан каждый if. Если у вас QA так круты — то разработчики вам не нужны. Ну и объем таких тексткейсов будет точно так же превышать объем кода.
Поэтому да, для юнит-тестов разработчик сам придумывает покрытие. Точно так же, как он сам придумывает, где к коде написать if. И проверяют юнит-тесты именно наличие if-а или наличие вызова. Загораясь красным, когда кто-то лажанет при мерже, или неудачно подрефакторит. Или просто случайно выкосит проверку.
Те тесты, которые (иногда) пишутся по кейсам (или могут быть представлены в виде кейсов), по принципу один кейс — один тест — это или интеграционные или функциональные тесты. Т.е. это или selenium и прочие тыкалки интерфейса, тесты на всю систему в сборе (включая базу), или тесты «на бэкенд в сборе + базу».
Но вот ваша статья не только делит полезность тестов для разработчиков по технологическому признаку. Вы прямо противопоставляете принципиально разные виды тестирования, и выдаете из этого целую статью.
Точно так же можно написать статью о том, что «SQL по сравнению с JavaScript имеет как достоинства, так и явные недостатки», с кучей очень обоснованных доводов в пользу как SQL, так и JS.
И тут же, в ту же кучу — тесты до кода, правка тестов самими разработчиками, упоминания юнит тестов, «Тесты — такой же код» — т.е. явно не автоматизация работы QA, а именно юнит-тесты. Ну или в крайнем случае интеграционные. Юнит тесты призваны экономить время разработчиков. QA вообще не должно быть никакого дела до наличия или отсутствия юнит-тестов. Фраза «вернуть задачу к разработчикам при красном юнит тесте» — не имеет смысла — билд просто не должнен доходить до QA при красных юнит/интеграционных тестах.
Юнит-тесты — не альтернатива ручному тестированию. И, тем более, не аналог и не замена автоматизированному тестированию UI, вроде selenium. Это просто другой вид тестирования. А вы вписали в общий список все достоинства и все недостатки разных видов тестирования, даже тех, которые вообще в зону ответственности QA не входит. И перемешали. Не хватает только пунктов «selenium не умеет самостоятельно проводить penetration test-ы» и «юнит-тестами тяжело протестировать документацию» :)
С таким же успехом можно было расписать достоинства и недостатки JavaScript, достоинства .NET/Java, lua-скриптов, powershell, SQL, а потом перемешать это в один список «Блеск и нищета написания кода».
Т.е. вроде как была идея написать интересный противоречивый пост с интригой и открытой концовкой. Но выглядит так, как будто статью писал не лидер backend разработки, а маркетолог, которому выдали брошюру «разные виды тестирования для чайников» :(
На текущем проекте — в базе лежит часть логики (права доступа, хаки для иерархических данных и прочее) — и интеграционные тесты требуют реальной базы. Вынести логику из базы полностью не получится (точнее, получится, но работать будет гораздо медленее). И ORM — не EF :)
TDD и «писать тесты до кода» — разные вещи. Я не приверженец TDD, и не предлагаю вам строить архитектуру только на основании тестов. И вообще (вынуждненно, много легаси кода) предпочитаю интеграционные тесты. Но их можно писать до кода, а можно — после. Одни и те же тесты на один и тот же код могут приносят разный профит в зависимости от момента их написания. И дают разный эффект на мотивацию.
Тесты после кода:
[время на написание кода] + [время на ручной протык разработчиком и фикс] + [время на написание тестов]
Недостатки:
Тесты до кода:
[время на написание теста] + [время на написание кода]
Тот же код, те же тесты — но нет необходимости в активном ручном протыке. И нет ощущения, что вы делате «дополнительную» работу за других. Тесты начинают помогать разработчику вот прямо сейчас, а не когда-нибудь потом. Это прямой стимул, который заодно создает сайдэффект «код не сломается в будущем». Win-Win.
Внедрение тестов на проекте — это проблема психологии, а не техническая (как писать и запускать) и не менеджерская (выделить время). Нужно сделать так, чтобы разработчики чувствовали себя неуютно при попытке нафигачить код без тестов. Им должно быть физически неудобно это делать. «Лень запускать UI и проверять руками, проще тест написать» — вот эффект, который нужно получить.
Попробуйте писать свои интеграционные тесты до кода. Почувствуете разницу.
Если бы мы не вложились в CI (билд сервера с SSD + много локальных хаков в тестовом фреймворке) — мы бы получили почти 3 часа на прогон тестов. Вы готовы ждать 2-3 часа перед каждым пушем? А потом еще 3 часа на прогонку на билд-сервере? Ок, у нас на проекте мы смогли вставить хаки и сократить время выполнения. Но я не уверен, сможете ли вы сделать то же самое в своем коде.
Fear-driven development? Бить по рукам, лишать премии и прочие кнуты может позволить себе только галера, на которой студентов держат за счет того, что они не знают другой жизни и боятся поменять работу. На продуктовой разработке это просто убьет мотивацию и принесет больше вреда, чем пользы.
Если у вас разработчиков приходится лишать премии за нарушение принятого процесса — значит они не понимают, зачем конкретные практики в вашем процессе приняты. И битьем по рукам вы только усугубите ситуацию — спрячете проблему, загоните ее внутрь — но не решите.
Есть более гуманные способы — например снизить потери от «красных» коммитов активным бранчеванием (поломает дев свою ветку — всех остальных это не затронет). Процесс должен помогать разработчикам творить — создавать продукт. А не держать их в узде.
Тесты после кода, особенно если под них приходится править свеженаписанный рабочий и уже протестированный (запущенный пару раз) код — это пустая трата времени.
Вы с большей вероятностью добавите багов, чем почините. Видно даже на вашем примере — вы используете `IEnumerable` в репозитории, что вызывает выполнение запроса и материализацию продуктов прямо в момент вызова `GetFeaturedProducts`, а не позже, как это кажется по коду (и как происходило в оригинальном примере).
Попробуйте расписать свой же пример, но через написание двух тестов до кода — «Необходимо отобразить простой список рекомендуемых товаров» и «если список просматривает привилегированный пользователь, то цена всех товаров должна быть снижена на 5 процентов» — это покажет тесты с лучшей стороны.
Интеграционные тесты на базе — не панацея. У них есть один огромный недостаток — они медленные. Т.е. они кажутся хорошей идеей, пока их меньше 10000 штук. Потом они начинают занимать час даже на приличном железе, и вам придется вкладываться в инфраструктуру для билдов. К тому же разработчики перестанут запускать тесты локально и начнут пушить со словами «мне повезет».