Современная технология разработки ПО направлена на решения проблемм сложности, а не на построение отдельных алгоритмов (для этого 5 лет ходят в ВУЗ).
Ни какой пацан, не зная проекта изнутри, ни когда не сможет сказать «что будет», если «зафигарить здесь полочку». Вспомните книги гуру — практикующих консультатов. Все их расказы начинаются с того, что они приходят на умирающий проект и пару дней разбираются с причинами — почему 10 человеколет еще не начали приносить прибыль. Гуру — знает об ограничениях своего восприятия, «пацан» — нет.
Идеи «пацанов» это не более чем одна из тысячи интерестных идей в мозговом штурме, которая должна еще пройти 5 фильтров и 5 трансформаций, чтобы стать возможно полезной.
Что здесь правда?
— 300 строк кода? Для меня и 25 много
— статики с изменяющимся состоянием? Попробуйте к такому проекту добавить логику о которой не предполагал автор (кода) — например еще один экземпляр SQL-фасада.
— Патерны. Согласен. Патерн не должен использоваться там, где нет необходимости в его конкретной фишки. И от патерна стоит избавиться там, где негатив от него превышает позитив.
— IoC. Согласен.
— Code first. В больших проектах, где к базе обращается 3-4 клиента разрабатываемых в разное время, разными группами. Когда у вас в компании 2 десятка баз синхронизируются друг с другом. Когда у вас есть таблицы с 1.5*10^9 строк. Удачи.
Как я и говорил автор не прав и ни неправ одновременно. У меня у самого есть воззрения достойные халевара, но я же не говорю что сообщество «не доросло до моего уровня, чтобы понять их глубину и проницательность».
К сожелению, не дождался ответа на свой вопрос, поэтому продолжаю свою мысль. Подход совмещения контрактов с юнит тестами напоминает вариант построения тестов на тестируемом классе. То есть, некоторый класс A содержит не только полезный функционал, но и тесты проверяющие его. Недостаток такого подхода очевиден — слишком много кода в классе.
Перед переходом на TDD, я пользовался контрактам. Тогда они были достаточно архаичными — System.Debug.Assert. Доходило до смешного — рядом с двумя строчками полезного кода распологался десяток Assert-ов. Два три экрана кода, при удалении «мусора» превращались в пол экрана.
Я потому и спрашивал. Может контракты и правда жизнеспособны? Разбиваем 100500 тестов на группы. Называем каждую из них «контрактом». Награждаем ими конкретные классы (хоть десять контрактов на один класс). В тестах запускаем проверку Типа на соответствие всем его контрактам. Как частный случай проверки, может сработать.
А существуют способы ассоциировать ContractClassForAttribute с набором тестов (стандартные)? Грубо, если класс награжден контрактом, то для него среда тестирования автоматически вызовет 1,2,3… тесты. Ну или с минимальными усилиями хотябы — пишим тест с телом одну строку? типа ContractClassForAttribute.Assert(()=>new AAA()).
Я имел ввиду пустые строки отделяющие логические блоки кода. Здесь я бы поставил перед while, последним внешним if и return.
«kf<0? h>=0: h>0» не уверен :), но помоему он определяет в какую сторону идти в зависимости от направления отсортированности масива-параметра. Вобщем, без поллитра…
Может я и не прав, и вы код не уплотняли. Возможно, дело вкуса. Возможно, виноваты имена переменных. Но читать очень тяжело. Как результат — закрались сомнения :).
Так уже. Вы же целеноправленно строки сокращаете :):
1. «thin return» на одной строке
2. Несколько переменных объявлено вместе
3. «kf<0? h>=0: h>0» — конфета
4. А где пробелы между логическими блоками? Я бы поставил минимум в трех местах.
Такие тривиальные вещи идеально «разгрызаются» через TDD. Задача не использует внешних ресурсов…. Эх, где мои 17 лет (читай 16-22)? Попробуйте и достигните нирваны.
Надо сокращать наборы данных на которых фактически выполняются тесты, например вводом фиктивных параметров в хранимки и WHILE (@a is null or @a=tbl.field)
Я понимаю, что у этой задачи есть множество решений разной степени сложности. Когда я только начинал писать тесты, я пользовался рефлексией — за что мне до сих пор стыдно.
Вопрос в том, какой профит мы хотим от этого получить: пользоваться сингелтоном за его изящество (меня он восхитил в первый раз именно этим) или принять, что это просто глобальная видимость. «Сложность» тестирования, подсистем использующих глобальные сущности, это не самая серьезная из их проблем. Так есть ли смысл ее решать?
И сразу получаем проблему независимости тестов. Определяем TestInitialize и TestCleanup. Получаем проблемму с конфигурирование отдельных тестов. Определяем класс очистки и установки среды через IDisposable с параметрами в конструкторе — получаем сложную систему подготовки среды к тестирования.
И зачем такие финты ушами? Что бы получить доступ из любого места в коде к объекту. То есть — это обычная глобальная видимость. Но нам то хочется еще и временем жизни упровлять. Противоречие.
Решение:
Передаем объект от GetInstance через параметр (конструктора или метода) и забываем о всех проблеммах раз и на всегда. По сути отказываемся от сингелтона.
Именно поэтому, широко известные в узких кругах гуру советуют делать везде, где только можно минимальную реализация и пользоваться рефакторингом для дальнейшего развития. Так и говорят: «Если у кого и получается предсказывать будущее, то ему очень повезло. А я по старинке»
1. Тесты (или тест?) после кода
2. Тесты не как не повлияли на построение архитектуры, она целиком была сделана на бумаге. Driving-а (да и Design-а тоже) из аббревиатуры TDD нет
3. Нет и намека о ритме
4. Второй описанный (возможно, другие не были описанные) — точно не UnitTest. Или это небыл тест? Тогда sorry.
С использованием автотестирования — да. Но не TDD.
Но основной тезис «Тест – это не дополнение к коду, но его важная часть» классный.
У меня на Moq не получилось переопределить виртуальный метод у класса. Rhino справился. Может конечно я не знаю как. А так, использование Moq немного удобнее. ИМХО, конечно
Современная технология разработки ПО направлена на решения проблемм сложности, а не на построение отдельных алгоритмов (для этого 5 лет ходят в ВУЗ).
Ни какой пацан, не зная проекта изнутри, ни когда не сможет сказать «что будет», если «зафигарить здесь полочку». Вспомните книги гуру — практикующих консультатов. Все их расказы начинаются с того, что они приходят на умирающий проект и пару дней разбираются с причинами — почему 10 человеколет еще не начали приносить прибыль. Гуру — знает об ограничениях своего восприятия, «пацан» — нет.
Идеи «пацанов» это не более чем одна из тысячи интерестных идей в мозговом штурме, которая должна еще пройти 5 фильтров и 5 трансформаций, чтобы стать возможно полезной.
Что здесь правда?
— 300 строк кода? Для меня и 25 много
— статики с изменяющимся состоянием? Попробуйте к такому проекту добавить логику о которой не предполагал автор (кода) — например еще один экземпляр SQL-фасада.
— Патерны. Согласен. Патерн не должен использоваться там, где нет необходимости в его конкретной фишки. И от патерна стоит избавиться там, где негатив от него превышает позитив.
— IoC. Согласен.
— Code first. В больших проектах, где к базе обращается 3-4 клиента разрабатываемых в разное время, разными группами. Когда у вас в компании 2 десятка баз синхронизируются друг с другом. Когда у вас есть таблицы с 1.5*10^9 строк. Удачи.
Как я и говорил автор не прав и ни неправ одновременно. У меня у самого есть воззрения достойные халевара, но я же не говорю что сообщество «не доросло до моего уровня, чтобы понять их глубину и проницательность».
Перед переходом на TDD, я пользовался контрактам. Тогда они были достаточно архаичными — System.Debug.Assert. Доходило до смешного — рядом с двумя строчками полезного кода распологался десяток Assert-ов. Два три экрана кода, при удалении «мусора» превращались в пол экрана.
Я потому и спрашивал. Может контракты и правда жизнеспособны? Разбиваем 100500 тестов на группы. Называем каждую из них «контрактом». Награждаем ими конкретные классы (хоть десять контрактов на один класс). В тестах запускаем проверку Типа на соответствие всем его контрактам. Как частный случай проверки, может сработать.
«kf<0? h>=0: h>0» не уверен :), но помоему он определяет в какую сторону идти в зависимости от направления отсортированности масива-параметра. Вобщем, без поллитра…
Может я и не прав, и вы код не уплотняли. Возможно, дело вкуса. Возможно, виноваты имена переменных. Но читать очень тяжело. Как результат — закрались сомнения :).
1. «thin return» на одной строке
2. Несколько переменных объявлено вместе
3. «kf<0? h>=0: h>0» — конфета
4. А где пробелы между логическими блоками? Я бы поставил минимум в трех местах.
Вопрос в том, какой профит мы хотим от этого получить: пользоваться сингелтоном за его изящество (меня он восхитил в первый раз именно этим) или принять, что это просто глобальная видимость. «Сложность» тестирования, подсистем использующих глобальные сущности, это не самая серьезная из их проблем. Так есть ли смысл ее решать?
И зачем такие финты ушами? Что бы получить доступ из любого места в коде к объекту. То есть — это обычная глобальная видимость. Но нам то хочется еще и временем жизни упровлять. Противоречие.
Решение:
Передаем объект от GetInstance через параметр (конструктора или метода) и забываем о всех проблеммах раз и на всегда. По сути отказываемся от сингелтона.
1. Тесты (или тест?) после кода
2. Тесты не как не повлияли на построение архитектуры, она целиком была сделана на бумаге. Driving-а (да и Design-а тоже) из аббревиатуры TDD нет
3. Нет и намека о ритме
4. Второй описанный (возможно, другие не были описанные) — точно не UnitTest. Или это небыл тест? Тогда sorry.
С использованием автотестирования — да. Но не TDD.
Но основной тезис «Тест – это не дополнение к коду, но его важная часть» классный.