Познал дзен написания автотестов в c#. Тесты я пишу уже довольно давно и помногу, но во основном функциональные/интеграционные, закрывающие функционал проекта в целом. При этом зависел я обычно только от объектов инфраструктуры: баз данных, брокеров сообщений и т.д. Модульные тесты тоже писал, но только на места с неочевидной сложной логикой, которая не помещается в голове.
Перенесемся в мир кровавого энтерпрайза. Представим ситуацию, когда наш сервис ходит по сети более чем в 10 других микросервисов. Куда ходят эти 10 микросервисов чтобы собрать информацию - представить страшно.
Поднимать все это добро каждый раз, когда приспичит проверить бизнес логику - не очень удобно даже в светлую эпоху контейнеризации. Тут на помощь нам приходят моки: обносим источник данных интерфейсом, а дальше в тестах в тестируемый класс с бизнес логикой подсовываем фейковую реализацию интерфейса.
До недавнего времени я пилил эту реализацию сам, но тут проникся двумя инструментами - NSubstitute и Autofixture. Первый позволяет создавать фейковые реализации, второй - инициализировать инстансы классов для возвратов с заполненными полями.
У NSubstitute понравилась возможность легко задавать конкретные кейсы из пар запрос - ответ, очень удобно и никакой логики внутри фейка самому писать (и потом поддерживать) не надо.
Autofixture мне не казалось чем-то нужным, до тех пор, пока мне не пришлось тестировать проброс информации из глубинных слоев наверх, с возвращаемой моделью (в сумме с вложенными классами) в пару тысяч строк. Говоришь: мне нужен объект, поля id, name, userid должны иметь заданные значения. Остальные - заполнятся по усмотрению библиотеки чем-то не-дефолтным. Раз - и объект для теста готов, без бесконечной лапши с инициализацией полей руками.
#csharp
#tests
Перенесемся в мир кровавого энтерпрайза. Представим ситуацию, когда наш сервис ходит по сети более чем в 10 других микросервисов. Куда ходят эти 10 микросервисов чтобы собрать информацию - представить страшно.
Поднимать все это добро каждый раз, когда приспичит проверить бизнес логику - не очень удобно даже в светлую эпоху контейнеризации. Тут на помощь нам приходят моки: обносим источник данных интерфейсом, а дальше в тестах в тестируемый класс с бизнес логикой подсовываем фейковую реализацию интерфейса.
До недавнего времени я пилил эту реализацию сам, но тут проникся двумя инструментами - NSubstitute и Autofixture. Первый позволяет создавать фейковые реализации, второй - инициализировать инстансы классов для возвратов с заполненными полями.
У NSubstitute понравилась возможность легко задавать конкретные кейсы из пар запрос - ответ, очень удобно и никакой логики внутри фейка самому писать (и потом поддерживать) не надо.
Autofixture мне не казалось чем-то нужным, до тех пор, пока мне не пришлось тестировать проброс информации из глубинных слоев наверх, с возвращаемой моделью (в сумме с вложенными классами) в пару тысяч строк. Говоришь: мне нужен объект, поля id, name, userid должны иметь заданные значения. Остальные - заполнятся по усмотрению библиотеки чем-то не-дефолтным. Раз - и объект для теста готов, без бесконечной лапши с инициализацией полей руками.
#csharp
#tests
Продолжая тему модульных тестов в c#. Вляпался в занятную ситуацию с Autofixture. Строки и числа Autofixture заполняет случайными значениями, меняющимися от запуска тестов к запуску. А вот тот момент, что значения булевых полей меняются по другим законам я как-то упустил.
Удаляю я неиспользуемое поле в одном из классов, экземпляры которых я создаю с помощью Autofixture - и тут у меня перестает проходить несколько тестов, при том покрывающих вообще случайные места в проекте. А переименование поля (неиспользуемого) такого эффекта не оказывает.
Первое на что я подумал - что-то где-то закешировалось у меня на компе и тесты заглючили, так иногда бывает. Следующий час прошел в попытках провести экзорцизм над проектом. Не помогло, зато я выяснил что проблема воспроизводится и в пайплайне CI/CD на серверах. Приплыли.
В итоге, оказалось, что генерируемые с помощью Autofixture значения булевых полей не меняются от запуска к запуску тестов, но являются функцией от набора полей в классе. Убрали или добавили поле - значения поехали.
А ошибки полезли из-за того, что я их допустил при написании тестов. Сочетание сгенерированных булевых флагов делало их незаметными, но минус на минус перестал давать плюс и тайное стало явным.
#csharp
#tests
#Autofixture
Удаляю я неиспользуемое поле в одном из классов, экземпляры которых я создаю с помощью Autofixture - и тут у меня перестает проходить несколько тестов, при том покрывающих вообще случайные места в проекте. А переименование поля (неиспользуемого) такого эффекта не оказывает.
Первое на что я подумал - что-то где-то закешировалось у меня на компе и тесты заглючили, так иногда бывает. Следующий час прошел в попытках провести экзорцизм над проектом. Не помогло, зато я выяснил что проблема воспроизводится и в пайплайне CI/CD на серверах. Приплыли.
В итоге, оказалось, что генерируемые с помощью Autofixture значения булевых полей не меняются от запуска к запуску тестов, но являются функцией от набора полей в классе. Убрали или добавили поле - значения поехали.
А ошибки полезли из-за того, что я их допустил при написании тестов. Сочетание сгенерированных булевых флагов делало их незаметными, но минус на минус перестал давать плюс и тайное стало явным.
#csharp
#tests
#Autofixture
🔥3
.NET epeshk blog
pl/dotnet Для PostgreSQL появилась поддержка C# и F# как языков процедур. Внутри используется модифицированная библиотека Npgsql, в которой сетевые вызовы заменены на прямые вызовы функций бд. Это позволяет писать в хранимых процедурах такой же код, как…
Вообще, для пишущих хранимые процедуры на не-SQL, есть отдельный котел в аду.
Но новость очень приятная.
#postgresql
#csharp
Но новость очень приятная.
#postgresql
#csharp
Продолжил читать Рихтера, дошел до делегатов. Делегат - это тип, описывающий метод: входящие и выходящие параметры. Можно например сделать метод, принимающий на вход делегат и вызывающий его внутри. И таким образом по ситуации подменять вызываемый метод. В общем штука банальная, иметь такое мне захотелось ~на третий месяц программирования на c#.
Но вот чего я не знал до текущего момента, это что делегаты могут представлять не только одиночные методы, но и их цепочки. В любой момент можно прикрепить к делегату метод, сделав +=. При вызове делегата будет последовательно вызвана вся цепочка методов. Возвращен будет результат выполнения последнего. Соответственно, открываются дополнительные возможности для формирования конвейеров обработки данных по критериям, задаваемым в рантайме.
Метод из цепочки также можно удалить вызвав -= метод.
#csharp
#Рихтер
#книги
Но вот чего я не знал до текущего момента, это что делегаты могут представлять не только одиночные методы, но и их цепочки. В любой момент можно прикрепить к делегату метод, сделав +=. При вызове делегата будет последовательно вызвана вся цепочка методов. Возвращен будет результат выполнения последнего. Соответственно, открываются дополнительные возможности для формирования конвейеров обработки данных по критериям, задаваемым в рантайме.
Метод из цепочки также можно удалить вызвав -= метод.
#csharp
#Рихтер
#книги
🔥4👎1🤔1
Познакомился с занятным инструментом: Approval тестами. Понятно, зачем нужны юнит тесты: фиксировать работоспособное состояние бизнес логики. Понятно, зачем нужны интеграционные тесты: фиксировать работоспособное состояние нескольких компонентов системы.
А тут появляется ещё один достаточно удобный рубеж обороны от багов. Approval тест фиксирует состояние Api. Если каким-то образом были внесены любые изменения, меняющие контракт - тест будет заваливаться, пока изменения не будут в явном виде внесены в специальный файл и закоммичены.
То есть при коммите мы в явном виде подтверждаем, что намеренно внесли изменения в контракт. А заодно имеем четкую историю того, кто и когда менял контракты и к кому в случае необходимости нужно применять устройство с картинки.
#csharp
А тут появляется ещё один достаточно удобный рубеж обороны от багов. Approval тест фиксирует состояние Api. Если каким-то образом были внесены любые изменения, меняющие контракт - тест будет заваливаться, пока изменения не будут в явном виде внесены в специальный файл и закоммичены.
То есть при коммите мы в явном виде подтверждаем, что намеренно внесли изменения в контракт. А заодно имеем четкую историю того, кто и когда менял контракты и к кому в случае необходимости нужно применять устройство с картинки.
#csharp
👍4🔥2
Небольшое наблюдение. Сейчас идёт седьмой крупный (от шести месяцев полной моей занятости) проект за мою карьеру в IT. Из них на трех у меня была полная свобода в плане написания тестов и возможности тянуть резину двигать сроки релиза.
Что характерно - именно эти три проекта, когда пришло время, просто запустились с минимальным предрелизным безумием. А все, где тестов не было - запускались с нервотрепкой и вычерпыванием бесконечного числа багов. При этом, основательный подход к разработке удлинял время от старта проекта до первого запуска в препрод процентов на 50-60. Вроде бы много.
Но если вспомнить, сколько времени проходило на оставшихся четырех проектах от первого запуска до состояния "работает приемлимо", то получается что на авральную пусконаладку уходило за 30% времени разработки. При том к концу её код обрастал костылями, затыкающими дыры, а я выдыхался до состояния выжатого лимона и терял в производительности на пару тройку месяцев или вообще менял работу.
#csharp
#tests
Что характерно - именно эти три проекта, когда пришло время, просто запустились с минимальным предрелизным безумием. А все, где тестов не было - запускались с нервотрепкой и вычерпыванием бесконечного числа багов. При этом, основательный подход к разработке удлинял время от старта проекта до первого запуска в препрод процентов на 50-60. Вроде бы много.
Но если вспомнить, сколько времени проходило на оставшихся четырех проектах от первого запуска до состояния "работает приемлимо", то получается что на авральную пусконаладку уходило за 30% времени разработки. При том к концу её код обрастал костылями, затыкающими дыры, а я выдыхался до состояния выжатого лимона и терял в производительности на пару тройку месяцев или вообще менял работу.
#csharp
#tests
❤7🔥4👎1😁1
Пожалуй пришло время обновить закреплённый пост. Каналу уже 5 лет, с прошлого закрепа изменилось многое.
Датасаенс, питон и наука были заброшены. В настоящий момент я работаю сеньор C# разработчиком в одном из российских банков.
За прошедшие 5 лет я сменил 4 места работы:
1. Фирма, занимающая АСУ ТП в области учёта ресурсов.
2. Медтех стартап в Сколково, делали системы поддержки принятия врачебных решений.
3. Сеть общепита, делал бэкенд службы доставки.
4. Банк, текущее место работы. Работаю в домене клиентских карточек.
Мой технологический стек:
C#, PostgreSQL. Плотно работал с MongoDB, RabbitMQ, Tarantool, умею строить базовую инфраструктуру: логи (Loki), метрики (Prometheus), девопсятина (gitlab, gitea, github actions, docker).
Поверхностно знаком с Apache Kafka, MS SQL и фронтовыми фреймворками - React.js и AvaloniaUI.
По образованию я инженер-оптик, потому часть базы приходится добирать на ходу. В планах закрыть гештальт по алгоритмам и двигаться в сторону архитектуры.
Далее будет навигация по каналу.
Общие теги:
#csharp@eshu_coding - общий тег для постов про разные аспекты разработки на языке программирования c#
#postgresql@eshu_coding - разные интересные моменты про PostgreSQL.
#devops@eshu_coding - мои эксперименты в девопсятине и инфраструктуре.
#mongodb@eshu_coding - записки про MongoDB.
#tarantool@eshu_coding - заметки про Tarantool.
Pet - проекты:
#палантир@eshu_coding - завершенный проект, которым я занимался весь 2021 год - поисковик по телеграму.
#sphagnum@eshu_coding - попытка написать свой брокер сообщений, пока застопорилась на стадии изучения теории и прототипирования по причине нехватки времени.
Книги:
#рихтер@eshu_coding - заметки и конспекты по основополагающей книге про C# - CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Хоть .NET 4.5 вышел до моего появления в IT, внутренности платформы во основном остались прежними.
Конспекты прослушанных выступлений на конференциях:
#dotnext@eshu_coding - Dotnext 2023
#highload@eshu_coding - Highload++ 2024
Шпаргалки и мои заметки для подготовки к собеседованиям #собес@eshu_coding
Природа и путешествия #природа@eshu_coding #путешествие@eshu_coding
Датасаенс, питон и наука были заброшены. В настоящий момент я работаю сеньор C# разработчиком в одном из российских банков.
За прошедшие 5 лет я сменил 4 места работы:
1. Фирма, занимающая АСУ ТП в области учёта ресурсов.
2. Медтех стартап в Сколково, делали системы поддержки принятия врачебных решений.
3. Сеть общепита, делал бэкенд службы доставки.
4. Банк, текущее место работы. Работаю в домене клиентских карточек.
Мой технологический стек:
C#, PostgreSQL. Плотно работал с MongoDB, RabbitMQ, Tarantool, умею строить базовую инфраструктуру: логи (Loki), метрики (Prometheus), девопсятина (gitlab, gitea, github actions, docker).
Поверхностно знаком с Apache Kafka, MS SQL и фронтовыми фреймворками - React.js и AvaloniaUI.
По образованию я инженер-оптик, потому часть базы приходится добирать на ходу. В планах закрыть гештальт по алгоритмам и двигаться в сторону архитектуры.
Далее будет навигация по каналу.
Общие теги:
#csharp@eshu_coding - общий тег для постов про разные аспекты разработки на языке программирования c#
#postgresql@eshu_coding - разные интересные моменты про PostgreSQL.
#devops@eshu_coding - мои эксперименты в девопсятине и инфраструктуре.
#mongodb@eshu_coding - записки про MongoDB.
#tarantool@eshu_coding - заметки про Tarantool.
Pet - проекты:
#палантир@eshu_coding - завершенный проект, которым я занимался весь 2021 год - поисковик по телеграму.
#sphagnum@eshu_coding - попытка написать свой брокер сообщений, пока застопорилась на стадии изучения теории и прототипирования по причине нехватки времени.
Книги:
#рихтер@eshu_coding - заметки и конспекты по основополагающей книге про C# - CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Хоть .NET 4.5 вышел до моего появления в IT, внутренности платформы во основном остались прежними.
Конспекты прослушанных выступлений на конференциях:
#dotnext@eshu_coding - Dotnext 2023
#highload@eshu_coding - Highload++ 2024
Шпаргалки и мои заметки для подготовки к собеседованиям #собес@eshu_coding
Природа и путешествия #природа@eshu_coding #путешествие@eshu_coding
❤7👍6🔥2👎1