-Поиск по дневнику

Поиск сообщений в rss_forum_sources_ru

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 29.07.2007
Записей:
Комментариев:
Написано: 80




Форум на Исходниках.RU


Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://forum.sources.ru.
Данный дневник сформирован из открытого RSS-источника по адресу http://forum.sources.ru/yandex.php, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Gag and Entertaining Acivity Online

Четверг, 03 Сентября 2020 г. 00:49 + в цитатник
larryTeess: Looking for Singapore live casino games, SolarbetSg is the right sportsbook for you.
Reliable Online Casino in Singapore

https://forum.sources.ru/index.php?showtopic=419520&view=findpost&p=3838163


Метки:  

TDD vs не TDD

Четверг, 03 Сентября 2020 г. 00:16 + в цитатник
D_KEY:
Цитата korvin @
Так я ж бомблю, что его почти не пишут, этот самый декларативный код, предпочитая обмазаться тестами и говнякать =)

Так и не начнут же :)
По крайней мере не раньше, чем меритократические тенденции возобладают в РФ

Цитата
Цитата D_KEY @
А хорошо получалось или было все нестабильно?

Всё было плохо.

Ну значит или те, кто нахваливают TDD врут, или у тех, кого ты видил, было что-то не так сделано. Ну и вообще основная проблема-то может быть вообще в кадрах :D

Цитата
Если у тебя новые требование (новая формула, скажем, умножать нужно не на два, а на три), то естественно нужно написать новую функцию и использовать там, где нужно, а не трогать старую. Ты что, open-close принцип забыл?

Я просто не могу смапить твой синтетический пример на реальный код :)

Цитата

А что такое «оптимизация декларативного кода»?

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

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838157


Метки:  

Производительность Си в сравнении с Rust

Среда, 02 Сентября 2020 г. 22:43 + в цитатник
Sunless: Добрый вечер!
Почему Си с компилятором GCC уступает в производительности Rust? Объясните доходчиво, пожалуйста. Источник тут https://benchmarksgame-team.pages.debian.ne...stest/rust.html
Спасибо.

https://forum.sources.ru/index.php?showtopic=419518&view=findpost&p=3838153


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 22:30 + в цитатник
korvin:
Цитата D_KEY @
а в реальном декларативном коде не вознкает потребности в рефакторинге?

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

Добавлено
Цитата D_KEY @
А хорошо получалось или было все нестабильно?

Всё было плохо.

Цитата D_KEY @
А, то есть мы полностью переписываем код каждый раз?

Зачем каждый раз? Если ты про то, чтобы переиспользовать эту функцию в новой фиче, то если она подходит, можно и переиспользовать, но тогда две фичи будут от неё зависеть и менять её нельзя. Да и зачем? Если у тебя новые требование (новая формула, скажем, умножать нужно не на два, а на три), то естественно нужно написать новую функцию и использовать там, где нужно, а не трогать старую. Ты что, open-close принцип забыл?

Цитата D_KEY @
То, что если он недекларативен ради оптимизации, то тогда тесты имеет смысл писать?

Ну да, если это нечитаемое байтоковыряние, конечно, надо.

Цитата D_KEY @
А что, декларативный код не оптимизируют?

А что такое «оптимизация декларативного кода»?

Добавлено
К слову о моках и в чём с ними проблема.

Допустим, есть у нас такой сервис:

    public final class Transfer {
    public static final class Request {
    public final Account.ID source;
    public final Account.ID destination;
    public final Money amount;
    public Request(Account.ID source, Account.ID destination, Money amount) {
    this.source = source;
    this.destination = destination;
    this.amount = amount;
    }
    }
    public static final class InsufficientFunds extends RuntimeException {}
    private final Accounts accounts;
    private final Compliance compliance;
    private final Transactions transactions;
    private final Notifier notifier;
    public Transfer(Accounts accounts, Compliance compliance, Transactions transactions, Notifier notifier) {
    this.accounts = accounts;
    this.compliance = compliance;
    this.transactions = transactions;
    this.notifier = notifier;
    }
    public void submit(Request r) {
    final var source = accounts.load(r.source);
    final var destination = accounts.load(r.destination);
    validate(source, destination, r.amount);
    final var transaction = Transaction.fresh(r.source, r.destination, r.amount);
    transactions.store(transaction);
    notifyUsers(source, destination, transaction.id);
    }
    private void validate(Account source, Account destination, Money amount) {
    checkCompliance(source, destination, amount);
    checkBalance(source, amount);
    }
    private void checkCompliance(Account source, Account destination, Money amount) {
    if (source.hasSameOwnerAs(destination)) {
    return;
    }
    compliance.validateTransfer(source.owner, destination.owner, amount);
    }
    private void checkBalance(Account source, Money amount) {
    if (source.canWithdraw(amount)) {
    return;
    }
    throw new InsufficientFunds();
    }
    private void notifyUsers(Account source, Account destination, Transaction.ID transaction) {
    notifier.notify(source.owner, transaction, "withdraw");
    notifier.notify(destination.owner, transaction, "top up");
    }
    }


у него четыре внешние зависимости, вот одна из них:
    public interface Accounts {
    Account load(Account.ID id);
    // more methods
    // ...
    }

три другие примерно такие же: интерфейсы с разными методами, я описал только те, что используются в сервисе Transfer.

теперь для юнит-тестов мы мокаем эти интерфейсы, как обычно это делают, что-то вроде
    final var accounts = Mockito.mock(Accounts);
    ...
    final var sourceAccount = // new account
    ...
    when(accounts.load(sourceAccount.id)).thenReturn(sourceAccount);
    ...
    subject.submit(new Transfer.Request(sourceAccount.id, ...));
    ...
    // assertions on mocked Transactions DB and Notifier?

и тут возникают вопросы:
– откуда мы знаем, что submit вообще вызовет accounts.load?
– откуда мы знаем, что submit вызовет accounts.load с параметром sourceAccount.id?
– откуда мы знаем, что submit не вызовет других методов accounts?
Этого нет в публичном интерфейсе (здесь я имею ввиду публичные методы и конструкторы) класса Transfer, нет в его «контракте». Фактически это — деталь реализации.

Т.е. наличие параметра Accounts в публичном конструкторе — это часть контракта, публичная внешняя зависимость, а как именно используется экземпляр Accounts — это деталь реализации и «знание» этой детали в тесте — прямое нарушение инкапсуляции.

Теперь рассмотрим альтернативу:
    public final class Transfer {
    public static final class Request {
    public final Money amount;
    public final Lazy source;
    public final Lazy destination;
    public final Lazy checkCompliance;
    public Request(Money amount, Lazy source, Lazy destination, Lazy checkCompliance) {
    this.amount = amount;
    this.source = source;
    this.destination = destination;
    this.checkCompliance = checkCompliance;
    }
    }
    public static final class Response {
    public final Transaction transaction;
    public final Notification[] notifications;
    private Response(Transaction transaction, Notification... notifications) {
    this.transaction = transaction;
    this.notifications = notifications;
    }
    public static final class Notification {
    public final User.ID user;
    public final Transaction.ID transaction;
    public final String message;
    public Notification(User.ID user, Transaction.ID transaction, String message) {
    this.user = user;
    this.transaction = transaction;
    this.message = message;
    }
    }
    }
    public static final class InsufficientFunds extends RuntimeException {}
    public Response submit(Request r) {
    validate(r);
    return transaction(r);
    }
    private void validate(Request r) {
    checkCompliance(r);
    checkBalance(r);
    }
    private void checkCompliance(Request r) {
    if (r.source.val().hasSameOwnerAs(r.destination.val())) {
    return;
    }
    r.checkCompliance.val();
    }
    private void checkBalance(Request r) {
    if (r.source.val().canWithdraw(r.amount)) {
    return;
    }
    throw new InsufficientFunds();
    }
    private Response transaction(Request r) {
    final var transaction = Transaction.fresh(r.source.val().id, r.destination.val().id, r.amount);
    return new Response(
    transaction,
    new Response.Notification(r.source.val().owner, transaction.id, "withdraw"),
    new Response.Notification(r.destination.val().owner, transaction.id, "top up")
    );
    }
    }

Ни одной внешней зависимости с полным сохранением функциональности.

Примерный тест:
    final var sourceAccount = // new account
    ...
    final var response = subject.submit(new Transfer.Request(
    money,
    () -> sourceAccount,
    () -> destinationAccount,
    () -> { /* e.g. do nothing in this particular test case */ }
    ));
    // assertions on response

И никаких моков нафиг не надо.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838152


Метки:  

Как удалить папку $WINDOWS.old ($WINDOWS.`BT)

Среда, 02 Сентября 2020 г. 22:08 + в цитатник
Oleg2004: Akina
Попробовал из командной строки
Пишет нет такого файла
Capture7.JPG (, : 3)

https://forum.sources.ru/index.php?showtopic=419503&view=findpost&p=3838151


Метки:  

Как удалить папку $WINDOWS.old ($WINDOWS.`BT)

Среда, 02 Сентября 2020 г. 20:36 + в цитатник
Oleg2004:
Цитата Qraizer @
Можно попробовать приложить ум к символическим ссылкам. Подсчёт занимаемого объёма учитывает контент по ссылкам, и это в неком смысле правильно, тогда как при перемещении на новое место будут перемещены ссылки, а не сами объекты, и это тоже в неком смысле правильно.

В принципе такой подход возможен наверно...но все операции над файлами папки, реакции Винды на действия с ними - не позволяют принять эту версию как однозначно возможную. При переносе(удалении) понятия "ссылка" или ссылка на это понятие не встречалась вообще.
Ну и названия в 303 символа это вообще абсурд... <_<
Еще одно обстоятельство которое подвергает меня в ступор
Capture333666.JPG (, : 2)
Обратите внимание на текст ошибки...
По сути текст говорит о том, что я не могу записать данный файл на внешний G:
Требуют снять защиту от записи...у кого снять защиту для записи? У переносимого файла? У диска?
Это как это как??? :wall:
Попробовал удалять не через TOTAL COMMANDER а через проводник.
Проводник выкинул мне Ошибка 0x0070780
Capture6.JPG (, : 1)

https://forum.sources.ru/index.php?showtopic=419503&view=findpost&p=3838143


Метки:  

Проектирование Планировщика

Среда, 02 Сентября 2020 г. 20:23 + в цитатник
JoeUser: Всем спасибо за участие! Вопрос закрываю.

https://forum.sources.ru/index.php?showtopic=419511&view=findpost&p=3838139


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 18:25 + в цитатник
Wound:
Цитата Fester @
Логгинг в этом плане идеальный пример, т.к. логгером можно отслеживать процесс. Согласись, далеко не все функии умещаются в одну строку. И логгинг бывает разного уровня (debug, info, warn, error, fatal итд).

Так и что с ним не так то? :-?

Цитата Fester @
Прикол в том, что 3-й класс делает систему неоправданно сложной.

С чего вдруг сложной? В чем заключается сложность? Я не понимаю.

Цитата Fester @
Весь прикол заключает в том, что если пользоваться терминологией автора этой статьи (т.е. UT не имеет мок-объектов, а то, что имеет мок-объекты - это интергационные тесты), то не существует систем, которые тестируются юнит-тестами

Ни автор, ни я не писали того, что выделенно жирным в твоей цитате.

Цитата Fester @
Юнит-тестами можно протестировать только базовые компоненты, а продуктивный (aka полезный) код тестируется исключительно интеграционными тестами.

Если у тебя функция и жнец и жрец и на дуде игрец, тогда это явно говорит о плохом дизайне в твоем приложении и о жестких зависимостях, от которых нужно избавляться.

Цитата Fester @
Например, у нас есть модуль, который контролирует передачу RFID чипов. Каждый евент от RFID-антенны сохраняется в БД и передается от 0 до n раз на 5 других подсистем. И вся информация о правильном поведении идет из вне Ну и каких "юнит-тестах" (в понимании автора статьи) тут можно говорить?

Юнит тестами тестируют конкретные функции/методы, ты же привел какой то юзер кейс, который должен тестироваться интеграционными тестами.
Тестируемая функция в ЮТ не должна не от чего зависеть, она должна быть автономной. Т.е. если у тебя в каком то 1 методе ошибка. То в юнит тестах - должен быть сфейлен ровно 1 UT из 1000 запущенных, даже если в программе у тебя куча мест, которые используют эту функцию/метод.
Если же у тебя сфейлилось 50 юнит тестов, из за того, что в ровно 1 методе у тебя ошибка, значит с твоими юнит тестами что то не то, и их ценность стремится к нулю.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838133


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 18:16 + в цитатник
Fester:
Цитата Wound @
Но у тебя в ТЗ оговорено что класс должен и логировать и вычислять сумму.

Логгинг в этом плане идеальный пример, т.к. логгером можно отслеживать процесс. Согласись, далеко не все функии умещаются в одну строку. И логгинг бывает разного уровня (debug, info, warn, error, fatal итд).

Цитата Wound @
Соответственно первый класс для вычисления суммы, второй для логирования, а третий агрегирует в себе эти два.

Прикол в том, что 3-й класс делает систему неоправданно сложной.

Цитата Wound @
Вот автор и описывает - что такой подход ведет к запутанности, сильной зависимости, и соответственно к подводным камням и ошибкам.

Весь прикол заключает в том, что если пользоваться терминологией автора этой статьи (т.е. UT не имеет мок-объектов, а то, что имеет мок-объекты - это интергационные тесты), то не существует систем, которые тестируются юнит-тестами :) Юнит-тестами можно протестировать только базовые компоненты, а продуктивный (aka полезный) код тестируется исключительно интеграционными тестами.
Например, у нас есть модуль, который контролирует передачу RFID чипов. Каждый евент от RFID-антенны сохраняется в БД и передается от 0 до n раз на 5 других подсистем. И вся информация о правильном поведении идет из вне :) Ну и каких "юнит-тестах" (в понимании автора статьи) тут можно говорить?

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838132


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 18:13 + в цитатник
D_KEY:
Цитата korvin @
Зачем ты начал рефакторить то, что и так ясно отражает суть?
Про оптимизацию я уже писал, но ты всё пропустил.

Ну в твоем синтетическом примере может и не полез бы, а в реальном декларативном коде не вознкает потребности в рефакторинге?

Цитата
Видел я как такой стартап использует эти практики. Ничем от херак-херак не отличается.

А хорошо получалось или было все нестабильно?

Цитата
Э нет, делать фичу — это новые требования и новая реализация.

А, то есть мы полностью переписываем код каждый раз? :D

Цитата
Про оптимизации я уже писал.

То, что если он недекларативен ради оптимизации, то тогда тесты имеет смысл писать?
А что, декларативный код не оптимизируют?

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838131


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 18:01 + в цитатник
korvin:
Цитата D_KEY @
Простой пример. Начал рефакторить или оптимизировать, ошибся в чем-то. Сломал.

Зачем ты начал рефакторить то, что и так ясно отражает суть?
Про оптимизацию я уже писал, но ты всё пропустил.

Цитата D_KEY @
Как раз обычно все эти быстрые стартапы часто активно используют эти "новые" хорошие инженерные практики

Видел я как такой стартап использует эти практики. Ничем от херак-херак не отличается.

Цитата D_KEY @
Программисты такие, знаешь ли. Код правят. Делали фичу, рефакторили, оптимизировали - выбирай на свой вкус.

Э нет, делать фичу — это новые требования и новая реализация. Рефакторят говнокод, а этот код чист, декларативен и понятен, идеален, его не нужно рефакторить =)
Про оптимизации я уже писал.
Кроме того, во многих сервисных проектах (особенно в этих ваших стартапах) проблемы производительности возникают обычно не в коде и не с первых годов жизни проекта.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838130


Метки:  

Как удалить папку $WINDOWS.old ($WINDOWS.`BT)

Среда, 02 Сентября 2020 г. 17:14 + в цитатник
Qraizer:
Цитата Oleg2004 @
А вот такие, как "удалил с диска 37 гигов, а свободного места стало 1 гигов" - во, такие чудеся сплошь и рядом... :wall:
И это не фокусы, а реальность...ума не приложу, как это может быть...
Можно попробовать приложить ум к символическим ссылкам. Подсчёт занимаемого объёма учитывает контент по ссылкам, и это в неком смысле правильно, тогда как при перемещении на новое место будут перемещены ссылки, а не сами объекты, и это тоже в неком смысле правильно. Например, там могут быть профили юзеров под \Users, папки с дотНетом, драйвер-паки итп, что может успешно разделяться под разными ОСями. Но это вряд ли, слишком велика разница между 7-ой и 10-ой, чтобы ограничиться лишь 1Гб.
Скорее на томе включены какие-нибудь теневые копии или истории файлов, а они с лёгкостью слопают 49Гб из удаляемых 50-и, если винда посчитает их обычными пользовательскими.
Не исключено, что в процесс вклинилась любимая яблочниками яблочная фича, не так давно не очень вдумчиво перенесённая в виду, под названием временная шкала. Она хранит историю всех действий за последний месяц и позволяет вернуться назад. Понятия не имею, сколько ресурсов требует. По идее немного, т.к. использует облако и учётку MS.

https://forum.sources.ru/index.php?showtopic=419503&view=findpost&p=3838128


Метки:  

Проектирование Планировщика

Среда, 02 Сентября 2020 г. 16:43 + в цитатник
Qraizer:
Цитата JoeUser @
Мне эту всю лабуду вручную править в планировщике? Свят-свят.
Возможно ты удивишься, но это всё делается планировщиком. Настраивается один раз и работает потом само.

https://forum.sources.ru/index.php?showtopic=419511&view=findpost&p=3838127


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 16:19 + в цитатник
Wound:
Цитата D_KEY @
Я может плаваю в теории, но в интеграционных тестах вместо моков уже должны быть реальные объекты, разве нет?

Ну вот автор пишет что нет. Плюс есть мнение, и это не только у этого автора я читал, что в интеграционных тестах - моками имитируются все ситуации, которые могут быть. Реальный объект, не реальный объект, серверная атака, имитация ошибки, имитация с отключенным соединением и т.д. и т.п.

Цитата D_KEY @
А так все верно, да. Просто я бы предложил перед интеграционными тестами, делать еще ЮТ с моками, чтобы некоторые ошибки отлавливать раньше запуска интеграционных тестов.

Ну вот а автор пишет, что такой подход лишен смысла напрочь. Потому что твой код с тестами разрастается, и в итоге ничего не покрывает и толку от них 0, типа все сведется к тому, что ты будешь моки тестировать, а не свой функционал.

Цитата D_KEY @
Вот если вместо "говорит о том, что модули сильно взаимосвязаны" написать "может говорить о том, что модули сильно взаимосвязаны", то я соглашусь

Выдрал специально для тебя:
Цитата

What is a code smell?
“A code smell is a surface indication that usually corresponds to a deeper problem in the system.” ~ Martin Fowler
A code smell does not mean that something is definitely wrong, or that something must be fixed right away. It is a rule of thumb that should alert you to a possible opportunity to improve something.
This text and its title in no way imply that all mocking is bad, or that you should never mock anything.
Additionally, different types of code need different levels (and different kinds) of mocks. Some code exists primarily to facilitate I/O, in which case, there is little to do other than test I/O, and reducing mocks might mean your unit test coverage would be close to 0.
If there is no logic in your code (just pipes and pure compositions), 0% unit test coverage might be acceptable, assuming your integration or functional test coverage is close to 100%. However, if there is logic (conditional expressions, assignments to variables, explicit function calls to units, etc…), you probably do need unit test coverage, and there may be opportunities to simplify your code and reduce mocking requirements.
---
What is tight coupling?
The need to mock in order to achieve unit isolation for the purpose of unit tests is caused by coupling between units. Tight coupling makes code more rigid and brittle: more likely to break when changes are required. In general, less coupling is desirable for its own sake because it makes code easier to extend and maintain. The fact that it also makes testing easier by eliminating the need for mocks is just icing on the cake.
From this we can deduce that if we’re mocking something, there may be an opportunity to make our code more flexible by reducing the coupling between units. Once that’s done, you won’t need the mocks anymore.
Coupling is the degree to which a unit of code (module, function, class, etc…) depends upon other units of code. Tight coupling, or a high degree of coupling, refers to how likely a unit is to break when changes are made to its dependencies. In other words, the tighter the coupling, the harder it is to maintain or extend the application. Loose coupling reduces the complexity of fixing bugs and adapting the application to new use-cases.
---
What does composition have to do with mocking?
Everything. The essence of all software development is the process of breaking a large problem down into smaller, independent pieces (decomposition) and composing the solutions together to form an application that solves the large problem (composition).
Mocking is required when our decomposition strategy has failed.
Mocking is required when the units used to break the large problem down into smaller parts depend on each other. Put another way, mocking is required when our supposed atomic units of composition are not really atomic, and our decomposition strategy has failed to decompose the larger problem into smaller, independent problems.
When decomposition succeeds, it’s possible to use a generic composition utility to compose the pieces back together. Examples:
---
When you use generic composition utilities, each element of the composition can be unit tested in isolation without mocking the others.
The compositions themselves will be declarative, so they’ll contain zero unit-testable logic (presumably the composition utility is a third party library with its own unit tests).
Under those circumstances, there’s nothing meaningful to unit test. You need integration tests, instead.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838124


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 15:44 + в цитатник
D_KEY:
Цитата Wound @
Если мы пишем так как в статье, значит нам уже не надо писать дополнительно ЮТ. Мы с них начинаем писать. Пишем тест, потом функционал. А уж потом дополнительно пишем интеграционные тесты, где с помощью моков эмулируем различные сценарии.

Я может плаваю в теории, но в интеграционных тестах вместо моков уже должны быть реальные объекты, разве нет?
А так все верно, да. Просто я бы предложил перед интеграционными тестами, делать еще ЮТ с моками, чтобы некоторые ошибки отлавливать раньше запуска интеграционных тестов.

Цитата
Ну и автор не говорит что нельзя моки юзать в ЮТ и все тут, он как бы намекает, что если в ЮТ используются Моки то это уже говорит о том, что модули сильно взаимосвязаны, и можно переписать куда лучше, чтоб избавится от моков.

Вот если вместо "говорит о том, что модули сильно взаимосвязаны" написать "может говорить о том, что модули сильно взаимосвязаны", то я соглашусь :)

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838123


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 15:26 + в цитатник
Wound:
Цитата Fester @
Принцип единственной ответственности не запрещает DI и не запрещает общаться с другими компонентами.

Конечно. Но у тебя в ТЗ оговорено что класс должен и логировать и вычислять сумму. Соответственно первый класс для вычисления суммы, второй для логирования, а третий агрегирует в себе эти два.
В чем конкретно проблема то? Как ты напишешь эту задачу? И в чем будет профит от твоего решения, я не пойму?
Ты хочешь ввести в свой метод внешние зависимости и потом тестировать это с помощью UT?
В итоге ты получаешь более зависимый тест, который может грохнуться из за того же логера, получаешь дополнительную кладезь ошибок, тебе придется передавать этот логер в ЮТ. Т.е. у тебя функция вычисляет сумму двух чисел, и помимо этого делает еще что то, что делать не должна.
Вот автор и описывает - что такой подход ведет к запутанности, сильной зависимости, и соответственно к подводным камням и ошибкам.

Цитата Fester @
Ну т.е. все сводится к тому какой тест можно назвать юнит-тестом, а какой уже интеграционный. Вопрос не в сути, а в терминологии. При этом ради сохранения чистоты терминологии автор готов пойти на усложнение кода и, соответственно, добавление ошибок.

Нет, ты все не так понял. Я тебе советую перечитать статью, на всякий случай продублирую ее еще раз: https://medium.com/javascript-scene/mocking...ll-944a70c90a6a

Цитата Fester @
И не просто так придется вводить интерфейс. Т.к. у тебя будет
Calculator : ICalculator
CalculatorWithLogger : ICalculator
CalculatorWithDatabase : ICalculator
CalculatorWithLoggarAndDatabase : ICalculator
что, как ты понимаешь, легко может привести к ошибке.

Для исключения ошибки тебе придется вводить еще один интерфейс:
Calculator : ICalculatorUnit
CalculatorWithLogger : ICalculator
CalculatorWithDatabase : ICalculator
CalculatorWithLoggarAndDatabase : ICalculator

Ты не понял о каком интерфейсе я говорил.

ICalculator - это интерфейс для реализации калькуляторов, зачем его вообще трогать?

У тебя будет интерфейс, который призван объединить вычисление с IO, какой нить:
ICalculatorWithIO или что то подобное. Не суть важно.
В принципе, вместо интерфейса ICalculator, можно взять абстрактный класс например и наследовать свои калькуляторы от него, если тебя смущает именно интерфейс, но можно и интерфейс, просто этот интерфейс(ICalculator) будет внутренним, если можно так выразиться. А ICalculatorWithIO - внешним, если исходить из того, что по ТЗ наружу должен торчать интерфейс который считает и логирует.


Цитата Fester @
которая конвертирует температуру по Кельвину в температуру по Цельсию

Так я не понимаю, какие проблемы? По аналогии напиши, в чем прикол то? Сложность в переименовании интерфейсов и классов возникла?

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838122


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 14:31 + в цитатник
Fester:
Цитата Wound @
Конечно, и что в этом плохого? Есть такой принцип: Принцип единственной ответственности буква S, из абрревиатуры SOLID, вот мы как раз ему и последовали. В чем косяк то?

Принцип единственной ответственности не запрещает DI и не запрещает общаться с другими компонентами.

Цитата Wound @
Так я выше написал, что этот класс будет тестироваться с помощью интеграционных тестов.

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


Цитата Wound @
Если у тебя будет как ты выше написал CalculatorWithLogger, CalculatorWithDatabase, CalculatorWithLoggarAndDatabase, то тут в любом случае придется вводить интерфейс. Ты уже докапываешься до незначительных деталей ИМХО.

И не просто так придется вводить интерфейс. Т.к. у тебя будет
Calculator : ICalculator
CalculatorWithLogger : ICalculator
CalculatorWithDatabase : ICalculator
CalculatorWithLoggarAndDatabase : ICalculator
что, как ты понимаешь, легко может привести к ошибке.

Для исключения ошибки тебе придется вводить еще один интерфейс:
Calculator : ICalculatorUnit
CalculatorWithLogger : ICalculator
CalculatorWithDatabase : ICalculator
CalculatorWithLoggarAndDatabase : ICalculator


Цитата Wound @
Какая эта функция?

которая конвертирует температуру по Кельвину в температуру по Цельсию

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838121


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 13:57 + в цитатник
Wound:
Цитата Fester @
Кстати, даже в этом коде есть логика, которую можно тестировать
Либо ты должен проверять параметры конструктора и кидать исключение в случае если logger или calculator имеют нулевые значения. Либо ты должен проверять на ноль непосредственно при сложении. Т.е. тут цикломатическая сложность гарантированно больше 1, а значит надо делать тест. Можно конечно назвать этот тест интеграционным, но мне кажется, что это уже дрочерство на терминологию

Так я выше написал, что этот класс будет тестироваться с помощью интеграционных тестов. Ну добавь туда проверку на null, если тебе так нужно, я же пример привел, а не конечное приложение.

Цитата Fester @
Да, вот только функция уровнем выше (которая будет использовать CalculatorWithLogger) ничего не должна знать про существование CalculatorWithLogger, ей известен только ICalculator... Т.е. либо тебе придется вводить еще одну абстракцию, либо ты рискуешь совершить ошибку передав в CalculatorWithLogger в качестве ICalculator другой CalculatorWithLogger.

Если у тебя будет как ты выше написал CalculatorWithLogger, CalculatorWithDatabase, CalculatorWithLoggarAndDatabase, то тут в любом случае придется вводить интерфейс. Ты уже докапываешься до незначительных деталей ИМХО.

Добавлено
Цитата Fester @
Проблема в том, что эта функция должна либо сама создать объект CalculatorWithLogger (для этого ей надо будет как-то получить ILogger и ICalculator), либо функция должна будет получить CalculatorWithLogger в качестве параметра (это насколько я понимаю, противоречит требованию к юнит-тесту)

Какая эта функция? Я тебя не понимаю. Обработчик ГУИ формы? CalculatorWithLogger - это внешнее API, которые ты юзаешь в своем коде, а Calculator - это внутреняя бизнес логика, которая тестируется с помощью ЮТ.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838120


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 13:55 + в цитатник
Fester:
Цитата Wound @
В чем проблема написать такой тест? Ну возьми функции выше, измени названия классов.

Проблема в том, что эта функция должна либо сама создать объект CalculatorWithLogger (для этого ей надо будет как-то получить ILogger и ICalculator), либо функция должна будет получить CalculatorWithLogger в качестве параметра (это насколько я понимаю, противоречит требованию к юнит-тесту)

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838119


Метки:  

TDD vs не TDD

Среда, 02 Сентября 2020 г. 13:52 + в цитатник
Wound:
Цитата Fester @
Замечетельно! Вот только у тебя в системе один логгер и Х классов, которые должны что-то протоколировать. Таким образом твое решение приводит к удвоению количества классов

Конечно, и что в этом плохого? Есть такой принцип: Принцип единственной ответственности буква S, из абрревиатуры SOLID, вот мы как раз ему и последовали. В чем косяк то? :-?

Цитата Fester @
А если пойти еще дальше и к логгеру добавить... ну скажем запись в БД, при этом и запись в БД и логгер опциональны, то у тебя получается такой вот зоопарк: Calculator, Logger, Database, CalculatorWithLogger, CalculatorWithDatabase, CalculatorWithLoggarAndDatabase.

Согласись, решение так себе...

Никакого зоопарка не будет. Будет один интерфейс, от которого будут наследоваться все эти CalculatorWithLogger, CalculatorWithDatabase, CalculatorWithLoggarAndDatabase. Это вроде обычный подход, разве нет? :huh:
А Calculator, Logger, Database - это вообще разные классы, реализующие разный функционал. Городить все это в один класс - это будет неверным.

https://forum.sources.ru/index.php?showtopic=419507&view=findpost&p=3838118


Метки:  

Поиск сообщений в rss_forum_sources_ru
Страницы: 2628 ... 2422 2421 [2420] 2419 2418 ..
.. 1 Календарь