TDD и вообще юнит-тесты in the wild

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
77 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
Прошу прощения за запоздалый ответ — был в офлайне несколько дней.

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

Сергей, данная фраза, весь абзац, из которой я ее взял, да и все дальнейшие рассуждения показывают, что вы плохо представляете себе что такое TDD. Просто с точностью "до наоборот". Так что пытаться оспаривать детали здесь нет никакого смысла. Давайте сначала определимся с тем, что такое TDD? Выводы типа "либо я дурак, либо…" предлагаю сразу исключить.




--

Best regards,


Dennis Schetinin


7 января 2015 г., 9:08 пользователь Сергей Глушенко <[hidden email]> написал:
TDD не предполагает какого-либо особого склада ума. Этот подход всего лишь заставляет в каждый момент времени понимать конечную цель своих действий — еще до начала этих самых действий.
 
Возможно в небольших проектах и можно четко представлять себе конечную цель. Заранее продумать всю архитектуру, состав классов и взаимодействие между ними. Но в этом случае проект получится статическим. Его нельзя будет малой кровью модернизировать или где ни будь в середине пути свернуть в сторону. Я год назад начиная свой проект не представлял во что он выльется, имел только смутное представление что я хочу. И теперь я не представляю чем он будет через год. Общая архитектура за это время менялась уже много раз и от базовой архитектуры практически ничего не осталось. Многие связи, и решения как раз возникают в процессе решения задач, а не перед началом работы над задачей. В случае с TTD сначала надо четко себе представить что будет в конце и идти выбранным путем несмотря ни на что. То есть сначала надо очень долго продумывать будущую реализацию. В процессе продумывания можно просто потерять интерес к задаче. Ну или процесс построения будущей архитектуры растянется на непомерно большое время. и не факт что результат будет удачным. Но свернуть то нельзя, потому что изменения тянут за собой глобальные переделки тех же тестов написанных в процессе разработки через TDD.

Ну есть и еще один минус TDD который объеденяет его с тестированием. Глобальное замедление процесса разработки. Посмотрим на реальном примере из моего проекта (полько вчера пробовал).

Есть обект - блок генератора импульсов. Он может параметрироваться. То есть он может быть одновибратором, симметричным генератором, несимметричным генератором. в казачестве параметров в первом и втором случаях  выступает  длительность включенного состояния, в третем случае параметров  два - длительность включенного и длительность выключенного состояния. Длительность может задаваться либо в милисекундах либо в микросекундах. каждый из параметров может быть либо константой, либо читаться со входа.

Для создания скетча (результата работы компилятора) мне необходимо знать какую из функций добавить в скетчь - окончание выдержки в милисекундах или окончание задержки в микросекундах. Соответственно у объекта генератор реализуем метод


isNeededMicrosTimerUtilityFunction



в соответствии с логикой TDD  пишем первый тест (я  свои эксперементы со злости удалил, так что описываю словами)

Создаем Project.
Создаем блок FBDGeneratorBlock.
Добавляем его в проект

 Эта часть подымается родительскому классу что бы в последствии получать блок одним методом

блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 милисекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает false


реализация метода что бы тест стал зеленый

isNeededMicrosTimerUtilityFunction

^self onConstantIsMicros.


кстати реализация метода
onConstantIsMicros
то же обвязывается тестами.

Второй тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 микросекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает true


Второй  тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 микросекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает true


Реализация метода не меняется  поскольку метод
onConstantIsMicros
 уже работает правильно

Третий   тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет вход.
ставим ему параметр время включенного состояния 1000 милисекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает false


Реализация метода не меняется  поскольку метод
onConstantIsMicros
 уже работает правильно

.....

в результате получилось более двадцати тестов на один метод конечный код:

isNeededMicrosTimerUtilityFunction

 
(self isSingle or: [self isSinhroMulty])
 ifTrue
: [^self onConstantIsMicros].
 
^self onConstantIsMicros or: [self offConstantIsMicros]

С той работой с которой я обычно справляюсь за час я провозился день и то до конца не сделал. Ближе к шести вечера (а работаю я с восьми до восьми) я разозлился снес к чертям пакет SUnit вместе со всеми тестами и быстренько все доделал. Я честно пытался понять прелесть TDD но либо я дурак, либо что то в TDD не то. Неприятно считать себя дураком, поэтому я и написал здесь. Может я что то не понимаю, и кто то сможет мне объяснить в чем прелесть использования TDD. По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.




вторник, 6 января 2015 г., 23:00:14 UTC+5 пользователь chaetal написал:

6 января 2015 г., 19:58 пользователь Сергей Глушенко <[hidden email]> написал:

Для того что бы использовать TDD надо обладать очень специфичным складом ума. Думать от обратного надо уметь <…>  Наверное так можно писать когда четко знаеш что у тебя должно получится в конце.В реальной жизни же так почти никогда не бывает. В начале работы обычно не знаеш что получится на выходе и с чем столкнешся. 

Алиса: – Куда мне отсюда идти?
Ч.Кот: — А куда ты хочешь попасть?
Алиса: — А мне все равно, только бы попасть куда-нибудь.
Ч.Кот: — Тогда все равно куда идти. Куда-нибудь ты обязательно попадешь.

Надо обладать специфичным складом ума, чтобы представлять, куда ты (скажем, впервые) направляешься, не имея возможности представить себе все нюансы маршрута?

TDD не предполагает какого-либо особого склада ума. Этот подход всего лишь заставляет в каждый момент времени понимать конечную цель своих действий — еще до начала этих самых действий.


2. Автоматические тесты - зло <…> 1… 2… 3…

Автомобили зло, потому что:

1. На них можно доехать не до любой точки

2. Чаще всего мы хотим прибыть в какое-либо помещение, а на автомобиле туда заехать невозможно

3. Автомобиль требует массу времени: его надо заправлять, заводить, ремонтировать.

Теперь, внимание, вопрос: а какое все это отношение имеет к автоматизации?

ввести тестирование на проекте

Не устану повторять: TDD и тестирование — принципиально разные вещи. Как автоматизация и автомобиль — даже несмотря на то, что у них общий корень "авто".


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Yuriy Mironenko
Но тут возникает очевидный вопрос: уж если есть таблица истинности, то проще считать её реализацией метода, а не его проверкой.
Если я правильно все понимаю, опять же изложенное сводится к проблеме "тестирование против разработки". Ты спрашиваешь: "как тестировать", если реализация почти совпадает с условием теста? TDD на это ответа не даст — не в ее компетенции. TDD занимается вопросом как получить реализацию. Если это тебя интересует, напиши точнее исходное состояние системы и что надо в нее добавить — специфицируй задачу. (Кстати, тест в TDD — это как раз записанная в коде спецификация).

Мне вот теперь тоже захотелось задать вопрос. Я уже много раз повторял в рамках этой дискуссии: давайте не путать TDD и тестирование. Вроде бы никто ни разу не пытался этот тезис оспаривать. Но каждый раз упорно эта тема возвращается. Почему?



--

Best regards,


Dennis Schetinin


7 января 2015 г., 12:55 пользователь Юрий Мироненко <[hidden email]> написал:
Теперь, Денис, вопрос и тебе.

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

Очевидное решение здесь - написать таблицу истинности и по ней всё проверить. В одном тесте, не в двадцати :)

Но тут возникает очевидный вопрос: уж если есть таблица истинности, то проще считать её реализацией метода, а не его проверкой.

7 января 2015 г., 9:23 пользователь Юрий Мироненко <[hidden email]> написал:

Прежде чем продолжить, Сергей, объясните пару моментов.

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

Во-вторых, если я правильно понял, isNeededMicrosTimerUtilityFunction есть логическая функция от четырёх аргументов:
  1. isSingle
  2. isSinhroMulty
  3. onConstantIsMicros
  4. offConstantIsMicros

Поскольку, судя по названиям элементов, там Boolean, всевозможных комбинаций - 16, а вы говорите о 20+ тестах. Откуда берутся дополнительные тесты?

7 января 2015 г., 8:08 пользователь Сергей Глушенко <[hidden email]> написал:

TDD не предполагает какого-либо особого склада ума. Этот подход всего лишь заставляет в каждый момент времени понимать конечную цель своих действий — еще до начала этих самых действий.
 
Возможно в небольших проектах и можно четко представлять себе конечную цель. Заранее продумать всю архитектуру, состав классов и взаимодействие между ними. Но в этом случае проект получится статическим. Его нельзя будет малой кровью модернизировать или где ни будь в середине пути свернуть в сторону. Я год назад начиная свой проект не представлял во что он выльется, имел только смутное представление что я хочу. И теперь я не представляю чем он будет через год. Общая архитектура за это время менялась уже много раз и от базовой архитектуры практически ничего не осталось. Многие связи, и решения как раз возникают в процессе решения задач, а не перед началом работы над задачей. В случае с TTD сначала надо четко себе представить что будет в конце и идти выбранным путем несмотря ни на что. То есть сначала надо очень долго продумывать будущую реализацию. В процессе продумывания можно просто потерять интерес к задаче. Ну или процесс построения будущей архитектуры растянется на непомерно большое время. и не факт что результат будет удачным. Но свернуть то нельзя, потому что изменения тянут за собой глобальные переделки тех же тестов написанных в процессе разработки через TDD.

Ну есть и еще один минус TDD который объеденяет его с тестированием. Глобальное замедление процесса разработки. Посмотрим на реальном примере из моего проекта (полько вчера пробовал).

Есть обект - блок генератора импульсов. Он может параметрироваться. То есть он может быть одновибратором, симметричным генератором, несимметричным генератором. в казачестве параметров в первом и втором случаях  выступает  длительность включенного состояния, в третем случае параметров  два - длительность включенного и длительность выключенного состояния. Длительность может задаваться либо в милисекундах либо в микросекундах. каждый из параметров может быть либо константой, либо читаться со входа.

Для создания скетча (результата работы компилятора) мне необходимо знать какую из функций добавить в скетчь - окончание выдержки в милисекундах или окончание задержки в микросекундах. Соответственно у объекта генератор реализуем метод


isNeededMicrosTimerUtilityFunction



в соответствии с логикой TDD  пишем первый тест (я  свои эксперементы со злости удалил, так что описываю словами)

Создаем Project.
Создаем блок FBDGeneratorBlock.
Добавляем его в проект

 Эта часть подымается родительскому классу что бы в последствии получать блок одним методом

блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 милисекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает false


реализация метода что бы тест стал зеленый

isNeededMicrosTimerUtilityFunction

^self onConstantIsMicros.


кстати реализация метода
onConstantIsMicros
то же обвязывается тестами.

Второй тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 микросекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает true


Второй  тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет константой.
ставим ему параметр время включенного состояния 1000 микросекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает true


Реализация метода не меняется  поскольку метод
onConstantIsMicros
 уже работает правильно

Третий   тест

Создаем блок
блоку говорим что он одновибратор
говорим ему что параметр  время включенного состояния будет вход.
ставим ему параметр время включенного состояния 1000 милисекунд.
проверяем что метод isNeededMicrosTimerUtilityFunction возвращает false


Реализация метода не меняется  поскольку метод
onConstantIsMicros
 уже работает правильно

.....

в результате получилось более двадцати тестов на один метод конечный код:

isNeededMicrosTimerUtilityFunction

 
(self isSingle or: [self isSinhroMulty])
 ifTrue
: [^self onConstantIsMicros].
 
^self onConstantIsMicros or: [self offConstantIsMicros]

С той работой с которой я обычно справляюсь за час я провозился день и то до конца не сделал. Ближе к шести вечера (а работаю я с восьми до восьми) я разозлился снес к чертям пакет SUnit вместе со всеми тестами и быстренько все доделал. Я честно пытался понять прелесть TDD но либо я дурак, либо что то в TDD не то. Неприятно считать себя дураком, поэтому я и написал здесь. Может я что то не понимаю, и кто то сможет мне объяснить в чем прелесть использования TDD. По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.




вторник, 6 января 2015 г., 23:00:14 UTC+5 пользователь chaetal написал:

6 января 2015 г., 19:58 пользователь Сергей Глушенко <[hidden email]> написал:

Для того что бы использовать TDD надо обладать очень специфичным складом ума. Думать от обратного надо уметь <…>  Наверное так можно писать когда четко знаеш что у тебя должно получится в конце.В реальной жизни же так почти никогда не бывает. В начале работы обычно не знаеш что получится на выходе и с чем столкнешся. 

Алиса: – Куда мне отсюда идти?
Ч.Кот: — А куда ты хочешь попасть?
Алиса: — А мне все равно, только бы попасть куда-нибудь.
Ч.Кот: — Тогда все равно куда идти. Куда-нибудь ты обязательно попадешь.

Надо обладать специфичным складом ума, чтобы представлять, куда ты (скажем, впервые) направляешься, не имея возможности представить себе все нюансы маршрута?

TDD не предполагает какого-либо особого склада ума. Этот подход всего лишь заставляет в каждый момент времени понимать конечную цель своих действий — еще до начала этих самых действий.


2. Автоматические тесты - зло <…> 1… 2… 3…

Автомобили зло, потому что:

1. На них можно доехать не до любой точки

2. Чаще всего мы хотим прибыть в какое-либо помещение, а на автомобиле туда заехать невозможно

3. Автомобиль требует массу времени: его надо заправлять, заводить, ремонтировать.

Теперь, внимание, вопрос: а какое все это отношение имеет к автоматизации?

ввести тестирование на проекте

Не устану повторять: TDD и тестирование — принципиально разные вещи. Как автоматизация и автомобиль — даже несмотря на то, что у них общий корень "авто".


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.


--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Сергей Глушенко

7 января 2015 г., 9:08 пользователь Сергей Глушенко <[hidden email]> написал:
По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.

А по результатам моего многолетнего эксперимента TDD либо повышает (при программировании в Smalltalk), либо не влияет в среднесрочной и повышает в долгосрочной перспективе производительность (в C# и Java). 

Первое означает, что даже на 15-минутной задаче я через TDD чаще сделаю быстрее, чем "напрямую", если учитывать все время на обдумывание задачи, ее понимание и проектирование. 

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

Насчет "жесткого ограничения свободы разработчика" — вопрос интересный. Можно обсудить — это может привести нас к взаимопониманию по вопросу что такое TDD. Если возникнет желание, то предлагаю начать с вопроса о том, что вы понимаете под свободой разработчика и как TDD ее ограничивает (желательно с примерами).

--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Yuriy Mironenko
Не могу удержаться от небольшого ёрничанья.
Выдержка из новогодней новости на сайте проекта (курсив мой):

...При  сохранении проекта программа падает. Правильно говорят что торопится нельзя и надо полнее производить проверку программы.

Как бы намекает...

P.S. Конечно, я понимаю, что TDD и "просто тестирование" - вещи разные. Но мне казалось, что критика Сергея относилась не только к TDD, но и к тестам вообще. Хотя бы потому, что в конце повествования он снёс SUnit :)

10 января 2015 г., 14:13 пользователь Dennis Schetinin <[hidden email]> написал:

7 января 2015 г., 9:08 пользователь Сергей Глушенко <[hidden email]> написал:
По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.

А по результатам моего многолетнего эксперимента TDD либо повышает (при программировании в Smalltalk), либо не влияет в среднесрочной и повышает в долгосрочной перспективе производительность (в C# и Java). 

Первое означает, что даже на 15-минутной задаче я через TDD чаще сделаю быстрее, чем "напрямую", если учитывать все время на обдумывание задачи, ее понимание и проектирование. 

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

Насчет "жесткого ограничения свободы разработчика" — вопрос интересный. Можно обсудить — это может привести нас к взаимопониманию по вопросу что такое TDD. Если возникнет желание, то предлагаю начать с вопроса о том, что вы понимаете под свободой разработчика и как TDD ее ограничивает (желательно с примерами).

--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin

13 января 2015 г., 2:54 пользователь Юрий Мироненко <[hidden email]> написал:
P.S. Конечно, я понимаю, что TDD и "просто тестирование" - вещи разные. Но мне казалось, что критика Сергея относилась не только к TDD, но и к тестам вообще. Хотя бы потому, что в конце повествования он снёс SUnit :)

Но это совершенно другая тема, я бы ее обозначил как "Управление тестами". Хотя у Сергея я ее особо не увидел — он до нее попросту не добрался. Но я могу ошибаться: посты были длинными, мог упустить этот мотив.

Это, кстати, одна из тех, которыми я пытаюсь заниматься в свободное время… Если есть интерес, можно открыть соответствующую ветку…


--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
In reply to this post by Yuriy Mironenko
Да это была глупая ошибка)))))  Но если честно очень хотелось выпустить версию до нового года, просто прям горело в одном месте. как раз после неё я и решил провести эксперимент с тестированием и TDD. Неудачный. Хотя если честно, ошибки в существующем функционале у меня очень большая редкость.  В основной массе ошибки возникают в новых блоках  по достаточно ограниченному ряду причин. У менея даже есть небольшой список что надо обязательно сделать при создании нового блока, но все равно время от времени на этом прокалываюсь. Щсновная из причин - не полная реализация метода postCopy.  Где то 80% ошибок идут отдуда. Забываю реализовать либо копирование обекта в переменной , либо реализовать PostCopy у самого нового обекта.  И тут никакое тестирование не поможет. Если я вспомню о необходимости написать тест на копирование переменной, то мне быстрее написать одну строчку на копирование чем тест. И самое главное что это не будет менятся в будущем, поэтому проверять не имеет смысла. Ну и конечно спасибо моим тестерам. Их только зарегестрированных уже почти 400. А реально скачивают новую версию более полутора тысяч раз. Ну и очень помогает в тестировании версии написание видеоуроках. Во время видеоурока показывается весь новый функционал, поэтому и проверяется по полной. Еще по моему не было не одной записи во время которой не нашлось бы несколько ошибок. Так что пока обходимся без автоматического тестирования.
вторник, 13 января 2015 г., 3:54:54 UTC+5 пользователь Assargadon написал:
Не могу удержаться от небольшого ёрничанья.
Выдержка из новогодней новости на сайте проекта (курсив мой):

...При  сохранении проекта программа падает. Правильно говорят что торопится нельзя и надо полнее производить проверку программы.

Как бы намекает...

P.S. Конечно, я понимаю, что TDD и "просто тестирование" - вещи разные. Но мне казалось, что критика Сергея относилась не только к TDD, но и к тестам вообще. Хотя бы потому, что в конце повествования он снёс SUnit :)

10 января 2015 г., 14:13 пользователь Dennis Schetinin <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="b0lImyM4TjwJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">cha...@...> написал:

7 января 2015 г., 9:08 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="b0lImyM4TjwJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.

А по результатам моего многолетнего эксперимента TDD либо повышает (при программировании в Smalltalk), либо не влияет в среднесрочной и повышает в долгосрочной перспективе производительность (в C# и Java). 

Первое означает, что даже на 15-минутной задаче я через TDD чаще сделаю быстрее, чем "напрямую", если учитывать все время на обдумывание задачи, ее понимание и проектирование. 

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

Насчет "жесткого ограничения свободы разработчика" — вопрос интересный. Можно обсудить — это может привести нас к взаимопониманию по вопросу что такое TDD. Если возникнет желание, то предлагаю начать с вопроса о том, что вы понимаете под свободой разработчика и как TDD ее ограничивает (желательно с примерами).

--

Best regards,


Dennis Schetinin

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="b0lImyM4TjwJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
Так и знал, что фраза Юрия спровоцирует очередной цикл разговора на тему "TDD — это не тестирование". Но я обещал не уставать про это писать — буду стараться. Так что очередная порция занудства.

В основной массе ошибки возникают в новых блоках  по достаточно ограниченному ряду причин. У менея даже есть небольшой список что надо обязательно сделать при создании нового блока, но все равно время от времени на этом прокалываюсь. Щсновная из причин - не полная реализация метода postCopy.  Где то 80% ошибок идут отдуда. Забываю реализовать либо копирование обекта в переменной , либо реализовать PostCopy у самого нового обекта.  И тут никакое тестирование не поможет. Если я вспомню о необходимости написать тест на копирование переменной, то мне быстрее написать одну строчку на копирование чем тест.

Сергей абсолютно точно определил исходный источник проблемы: организацию труда. Выполняется некая рутинная операция. К ней есть определенные требования. Эти требования нужно реализовать. Сама реализация — тривиальна. Пролема в том, что эти требования реализовать тупо забывают. TDD тут ни при чем вообще.

TDD может помочь тогда, когда есть конкретная задача и не ясно, как ее реализовать. TDD — это методология разработки!
 
И самое главное что это не будет менятся в будущем, поэтому проверять не имеет смысла.

TDD и тут ни при чем, но "поживем — увидим"?



Но вот что привлекло мое внимание… (Начну издалека) Если задуматься, для чего вообще пишутся программы? Я предлагаю такую мысль: программы пишутся для того, чтобы снять с человека бремя выполнения рутинных операций. Даже если это утверждение не верно в 100% случаев, часто (и на мой взгляд это очень правильно) дело обстоит именно так. Но разработчики часто оказываются первыми, кто про это забывает. Описанный случай — показательный пример. Слова "забываю реализовать" говорят о том, что здесь нужна автоматизация! 

Разумеется, я не имею ввиду, что надо сделать какой-нибудь виззард с кодогенератором или какой-то подобный монстрообразный наворот. Надо просто создать соответствующую инфраструктуру в коде, которая либо будет заставлять реализовывать этот метод, либо (предпочтительнее) реализует его один раз в общем виде. По второму варианту, не зная кода, ничего сказать не могу, кроме того, что здесь как раз может пригодиться рефлексия Smalltalk-а. А по первому варианту напрашивается как раз написать тест (не TDD-шный!), который будет проходить по всем блокам в системе и проверять правильность выполнения операций, которые должны поддерживаться всеми блоками. 






--

Best regards,


Dennis Schetinin


13 января 2015 г., 6:51 пользователь Сергей Глушенко <[hidden email]> написал:
Да это была глупая ошибка)))))  Но если честно очень хотелось выпустить версию до нового года, просто прям горело в одном месте. как раз после неё я и решил провести эксперимент с тестированием и TDD. Неудачный. Хотя если честно, ошибки в существующем функционале у меня очень большая редкость.  В основной массе ошибки возникают в новых блоках  по достаточно ограниченному ряду причин. У менея даже есть небольшой список что надо обязательно сделать при создании нового блока, но все равно время от времени на этом прокалываюсь. Щсновная из причин - не полная реализация метода postCopy.  Где то 80% ошибок идут отдуда. Забываю реализовать либо копирование обекта в переменной , либо реализовать PostCopy у самого нового обекта.  И тут никакое тестирование не поможет. Если я вспомню о необходимости написать тест на копирование переменной, то мне быстрее написать одну строчку на копирование чем тест. И самое главное что это не будет менятся в будущем, поэтому проверять не имеет смысла. Ну и конечно спасибо моим тестерам. Их только зарегестрированных уже почти 400. А реально скачивают новую версию более полутора тысяч раз. Ну и очень помогает в тестировании версии написание видеоуроках. Во время видеоурока показывается весь новый функционал, поэтому и проверяется по полной. Еще по моему не было не одной записи во время которой не нашлось бы несколько ошибок. Так что пока обходимся без автоматического тестирования.
вторник, 13 января 2015 г., 3:54:54 UTC+5 пользователь Assargadon написал:
Не могу удержаться от небольшого ёрничанья.
Выдержка из новогодней новости на сайте проекта (курсив мой):

...При  сохранении проекта программа падает. Правильно говорят что торопится нельзя и надо полнее производить проверку программы.

Как бы намекает...

P.S. Конечно, я понимаю, что TDD и "просто тестирование" - вещи разные. Но мне казалось, что критика Сергея относилась не только к TDD, но и к тестам вообще. Хотя бы потому, что в конце повествования он снёс SUnit :)

10 января 2015 г., 14:13 пользователь Dennis Schetinin <[hidden email]> написал:

7 января 2015 г., 9:08 пользователь Сергей Глушенко <[hidden email]> написал:
По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.

А по результатам моего многолетнего эксперимента TDD либо повышает (при программировании в Smalltalk), либо не влияет в среднесрочной и повышает в долгосрочной перспективе производительность (в C# и Java). 

Первое означает, что даже на 15-минутной задаче я через TDD чаще сделаю быстрее, чем "напрямую", если учитывать все время на обдумывание задачи, ее понимание и проектирование. 

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

Насчет "жесткого ограничения свободы разработчика" — вопрос интересный. Можно обсудить — это может привести нас к взаимопониманию по вопросу что такое TDD. Если возникнет желание, то предлагаю начать с вопроса о том, что вы понимаете под свободой разработчика и как TDD ее ограничивает (желательно с примерами).

--

Best regards,


Dennis Schetinin

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании.
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )
usedDigitalPin - проверить

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

Вот как то так выкручиваюсь пока без тестов.



вторник, 13 января 2015 г., 8:13:10 UTC+5 пользователь chaetal написал:
Так и знал, что фраза Юрия спровоцирует очередной цикл разговора на тему "TDD — это не тестирование". Но я обещал не уставать про это писать — буду стараться. Так что очередная порция занудства.

В основной массе ошибки возникают в новых блоках  по достаточно ограниченному ряду причин. У менея даже есть небольшой список что надо обязательно сделать при создании нового блока, но все равно время от времени на этом прокалываюсь. Щсновная из причин - не полная реализация метода postCopy.  Где то 80% ошибок идут отдуда. Забываю реализовать либо копирование обекта в переменной , либо реализовать PostCopy у самого нового обекта.  И тут никакое тестирование не поможет. Если я вспомню о необходимости написать тест на копирование переменной, то мне быстрее написать одну строчку на копирование чем тест.

Сергей абсолютно точно определил исходный источник проблемы: организацию труда. Выполняется некая рутинная операция. К ней есть определенные требования. Эти требования нужно реализовать. Сама реализация — тривиальна. Пролема в том, что эти требования реализовать тупо забывают. TDD тут ни при чем вообще.

TDD может помочь тогда, когда есть конкретная задача и не ясно, как ее реализовать. TDD — это методология разработки!
 
И самое главное что это не будет менятся в будущем, поэтому проверять не имеет смысла.

TDD и тут ни при чем, но "поживем — увидим"?



Но вот что привлекло мое внимание… (Начну издалека) Если задуматься, для чего вообще пишутся программы? Я предлагаю такую мысль: программы пишутся для того, чтобы снять с человека бремя выполнения рутинных операций. Даже если это утверждение не верно в 100% случаев, часто (и на мой взгляд это очень правильно) дело обстоит именно так. Но разработчики часто оказываются первыми, кто про это забывает. Описанный случай — показательный пример. Слова "забываю реализовать" говорят о том, что здесь нужна автоматизация! 

Разумеется, я не имею ввиду, что надо сделать какой-нибудь виззард с кодогенератором или какой-то подобный монстрообразный наворот. Надо просто создать соответствующую инфраструктуру в коде, которая либо будет заставлять реализовывать этот метод, либо (предпочтительнее) реализует его один раз в общем виде. По второму варианту, не зная кода, ничего сказать не могу, кроме того, что здесь как раз может пригодиться рефлексия Smalltalk-а. А по первому варианту напрашивается как раз написать тест (не TDD-шный!), который будет проходить по всем блокам в системе и проверять правильность выполнения операций, которые должны поддерживаться всеми блоками. 






--

Best regards,


Dennis Schetinin


13 января 2015 г., 6:51 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="2YF6yKryv3YJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Да это была глупая ошибка)))))  Но если честно очень хотелось выпустить версию до нового года, просто прям горело в одном месте. как раз после неё я и решил провести эксперимент с тестированием и TDD. Неудачный. Хотя если честно, ошибки в существующем функционале у меня очень большая редкость.  В основной массе ошибки возникают в новых блоках  по достаточно ограниченному ряду причин. У менея даже есть небольшой список что надо обязательно сделать при создании нового блока, но все равно время от времени на этом прокалываюсь. Щсновная из причин - не полная реализация метода postCopy.  Где то 80% ошибок идут отдуда. Забываю реализовать либо копирование обекта в переменной , либо реализовать PostCopy у самого нового обекта.  И тут никакое тестирование не поможет. Если я вспомню о необходимости написать тест на копирование переменной, то мне быстрее написать одну строчку на копирование чем тест. И самое главное что это не будет менятся в будущем, поэтому проверять не имеет смысла. Ну и конечно спасибо моим тестерам. Их только зарегестрированных уже почти 400. А реально скачивают новую версию более полутора тысяч раз. Ну и очень помогает в тестировании версии написание видеоуроках. Во время видеоурока показывается весь новый функционал, поэтому и проверяется по полной. Еще по моему не было не одной записи во время которой не нашлось бы несколько ошибок. Так что пока обходимся без автоматического тестирования.
вторник, 13 января 2015 г., 3:54:54 UTC+5 пользователь Assargadon написал:
Не могу удержаться от небольшого ёрничанья.
Выдержка из новогодней новости на сайте проекта (курсив мой):

...При  сохранении проекта программа падает. Правильно говорят что торопится нельзя и надо полнее производить проверку программы.

Как бы намекает...

P.S. Конечно, я понимаю, что TDD и "просто тестирование" - вещи разные. Но мне казалось, что критика Сергея относилась не только к TDD, но и к тестам вообще. Хотя бы потому, что в конце повествования он снёс SUnit :)

10 января 2015 г., 14:13 пользователь Dennis Schetinin <[hidden email]> написал:

7 января 2015 г., 9:08 пользователь Сергей Глушенко <[hidden email]> написал:
По результатам моего небольшого эксперимента он жестко ограничивает свободу разработчика, при этом являясь огромным тормозом в скорости разработки.

А по результатам моего многолетнего эксперимента TDD либо повышает (при программировании в Smalltalk), либо не влияет в среднесрочной и повышает в долгосрочной перспективе производительность (в C# и Java). 

Первое означает, что даже на 15-минутной задаче я через TDD чаще сделаю быстрее, чем "напрямую", если учитывать все время на обдумывание задачи, ее понимание и проектирование. 

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

Насчет "жесткого ограничения свободы разработчика" — вопрос интересный. Можно обсудить — это может привести нас к взаимопониманию по вопросу что такое TDD. Если возникнет желание, то предлагаю начать с вопроса о том, что вы понимаете под свободой разработчика и как TDD ее ограничивает (желательно с примерами).

--

Best regards,


Dennis Schetinin

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="2YF6yKryv3YJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

vmusulainen-2
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="rPU2fyoXE3YJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Nikolay Kleptsov
Если одним методом postCopy не получается, тогда сделать декомпозицию методов, может и классов. Попробовать выделить общий функционал блоков и дополнительные свойства. Количество реализаций блоков не бесконечно. Без кода трудно точнее что-то сказать

13 января 2015 г., 12:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Конечно композицию, наследование я использую. В основном наследование, поскольку композицию я не очень люблю. Она менее наглядна.  Когда сразу понятно что блоки будут иметь общие свойства, или когда набирается какое то количество классов с похожими характеричтиками. Да и при построении нового блока я внимательно продумываю от какого какого класса в иерархии блоков наследоваться. Но дело в том что часто в начале реализации класса не всегда знаеш что в конце получится. Тут и проблеммы при компиляции в скетч если разные функции блока конфликтуют между совой (например в скоростном счетчике они могут подраться за использование единственного аппаратного таймера - горячий пример,только позавчера воевал), и приходится переделывать уже готовый функционал.Второй вопрос, после окончания работы с блоком и обкатке его на пользователях я про него забываю. Он работает, и на другие блоки не влияет. Это основная концепция проекта - по возможности исключить влияние блоков друг на друга. Важно что бы при создании нового блока ничего не происходило с существующими. Этакие сфкрические кони в вакуме. Не всегда конечно это получается, все таки некоторые блоки дерутся между собой за прерывания например, за ины контроллера, за порты и шины данных, но в большинстве случаев получается обходится малой кровью. Так же это позволяет осуществлять прямую совместимост проекта. То ест в версии 1.6.2 (вышедшей сегодня ночью) можно открыть проект версии 1. Он заработает и скомпилится. Скетчь конечно получится совершенно другой, не тот какой бы получился в версии1, но работать он будет точно так же. Ну и самое главное я не знаю какой я буду делать блок завтра. Это зависит в основном от пожеланий пользователей, наличия у меня времени, наличия в коробочке очередного шилда, да и вообще с какой ноги я встану и в каком ухе у меня зажужжит. Так что планировать какую то иерархию заранее невозможно.  Ну а насчет небесконечности реализаций, зайдите на ебай и наберите arduino shiteld, потом arduino sensors. Ну а что бы окончательно все понять наберите просто Arduino. Так что проект FLProg не будет закончен никогда. К тому - же кроме ардуинок есть еще STM, PIC, да и в конце концов ко мне уже из бауманки едет Intel Galileo. Плюс впереди Scada Sistem.Правда в каком порядке это все будет реализовываться и как будет в итоге выглядеть я не имею ни малейшего представления. Как тут планировать архитектуру? Есть общая идеология, есть какие то базовые классы интерфейса которых я стараюсь придерживаться. Но не более.

вторник, 13 января 2015 г., 15:04:11 UTC+5 пользователь Kleptsov Nikolay написал:
Если одним методом postCopy не получается, тогда сделать декомпозицию методов, может и классов. Попробовать выделить общий функционал блоков и дополнительные свойства. Количество реализаций блоков не бесконечно. Без кода трудно точнее что-то сказать

13 января 2015 г., 12:29 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="AWjKzzanMYwJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="AWjKzzanMYwJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Nikolay Kleptsov
Может попробовать прототипы

13 января 2015 г., 16:28 пользователь Сергей Глушенко <[hidden email]> написал:
Конечно композицию, наследование я использую. В основном наследование, поскольку композицию я не очень люблю. Она менее наглядна.  Когда сразу понятно что блоки будут иметь общие свойства, или когда набирается какое то количество классов с похожими характеричтиками. Да и при построении нового блока я внимательно продумываю от какого какого класса в иерархии блоков наследоваться. Но дело в том что часто в начале реализации класса не всегда знаеш что в конце получится. Тут и проблеммы при компиляции в скетч если разные функции блока конфликтуют между совой (например в скоростном счетчике они могут подраться за использование единственного аппаратного таймера - горячий пример,только позавчера воевал), и приходится переделывать уже готовый функционал.Второй вопрос, после окончания работы с блоком и обкатке его на пользователях я про него забываю. Он работает, и на другие блоки не влияет. Это основная концепция проекта - по возможности исключить влияние блоков друг на друга. Важно что бы при создании нового блока ничего не происходило с существующими. Этакие сфкрические кони в вакуме. Не всегда конечно это получается, все таки некоторые блоки дерутся между собой за прерывания например, за ины контроллера, за порты и шины данных, но в большинстве случаев получается обходится малой кровью. Так же это позволяет осуществлять прямую совместимост проекта. То ест в версии 1.6.2 (вышедшей сегодня ночью) можно открыть проект версии 1. Он заработает и скомпилится. Скетчь конечно получится совершенно другой, не тот какой бы получился в версии1, но работать он будет точно так же. Ну и самое главное я не знаю какой я буду делать блок завтра. Это зависит в основном от пожеланий пользователей, наличия у меня времени, наличия в коробочке очередного шилда, да и вообще с какой ноги я встану и в каком ухе у меня зажужжит. Так что планировать какую то иерархию заранее невозможно.  Ну а насчет небесконечности реализаций, зайдите на ебай и наберите arduino shiteld, потом arduino sensors. Ну а что бы окончательно все понять наберите просто Arduino. Так что проект FLProg не будет закончен никогда. К тому - же кроме ардуинок есть еще STM, PIC, да и в конце концов ко мне уже из бауманки едет Intel Galileo. Плюс впереди Scada Sistem.Правда в каком порядке это все будет реализовываться и как будет в итоге выглядеть я не имею ни малейшего представления. Как тут планировать архитектуру? Есть общая идеология, есть какие то базовые классы интерфейса которых я стараюсь придерживаться. Но не более.

вторник, 13 января 2015 г., 15:04:11 UTC+5 пользователь Kleptsov Nikolay написал:
Если одним методом postCopy не получается, тогда сделать декомпозицию методов, может и классов. Попробовать выделить общий функционал блоков и дополнительные свойства. Количество реализаций блоков не бесконечно. Без кода трудно точнее что-то сказать

13 января 2015 г., 12:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Честно говоря не знаком с понятием прототипы. Что то слышал, но в голове не отложилось. Я все таки не профессиональный программист  инженер электронщик и не имею фундаментального программистского образования. Любитель одним словом

вторник, 13 января 2015 г., 15:41:51 UTC+5 пользователь Kleptsov Nikolay написал:
Может попробовать прототипы

13 января 2015 г., 16:28 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="1XWp-QnyTpQJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Конечно композицию, наследование я использую. В основном наследование, поскольку композицию я не очень люблю. Она менее наглядна.  Когда сразу понятно что блоки будут иметь общие свойства, или когда набирается какое то количество классов с похожими характеричтиками. Да и при построении нового блока я внимательно продумываю от какого какого класса в иерархии блоков наследоваться. Но дело в том что часто в начале реализации класса не всегда знаеш что в конце получится. Тут и проблеммы при компиляции в скетч если разные функции блока конфликтуют между совой (например в скоростном счетчике они могут подраться за использование единственного аппаратного таймера - горячий пример,только позавчера воевал), и приходится переделывать уже готовый функционал.Второй вопрос, после окончания работы с блоком и обкатке его на пользователях я про него забываю. Он работает, и на другие блоки не влияет. Это основная концепция проекта - по возможности исключить влияние блоков друг на друга. Важно что бы при создании нового блока ничего не происходило с существующими. Этакие сфкрические кони в вакуме. Не всегда конечно это получается, все таки некоторые блоки дерутся между собой за прерывания например, за ины контроллера, за порты и шины данных, но в большинстве случаев получается обходится малой кровью. Так же это позволяет осуществлять прямую совместимост проекта. То ест в версии 1.6.2 (вышедшей сегодня ночью) можно открыть проект версии 1. Он заработает и скомпилится. Скетчь конечно получится совершенно другой, не тот какой бы получился в версии1, но работать он будет точно так же. Ну и самое главное я не знаю какой я буду делать блок завтра. Это зависит в основном от пожеланий пользователей, наличия у меня времени, наличия в коробочке очередного шилда, да и вообще с какой ноги я встану и в каком ухе у меня зажужжит. Так что планировать какую то иерархию заранее невозможно.  Ну а насчет небесконечности реализаций, зайдите на ебай и наберите arduino shiteld, потом arduino sensors. Ну а что бы окончательно все понять наберите просто Arduino. Так что проект FLProg не будет закончен никогда. К тому - же кроме ардуинок есть еще STM, PIC, да и в конце концов ко мне уже из бауманки едет Intel Galileo. Плюс впереди Scada Sistem.Правда в каком порядке это все будет реализовываться и как будет в итоге выглядеть я не имею ни малейшего представления. Как тут планировать архитектуру? Есть общая идеология, есть какие то базовые классы интерфейса которых я стараюсь придерживаться. Но не более.

вторник, 13 января 2015 г., 15:04:11 UTC+5 пользователь Kleptsov Nikolay написал:
Если одним методом postCopy не получается, тогда сделать декомпозицию методов, может и классов. Попробовать выделить общий функционал блоков и дополнительные свойства. Количество реализаций блоков не бесконечно. Без кода трудно точнее что-то сказать

13 января 2015 г., 12:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="1XWp-QnyTpQJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Сергей Глушенко
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="QycWkYtoh6QJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="QycWkYtoh6QJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
А можно увидеть наиболее типичные реализации методов isUse…, has…?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 15:28 пользователь Сергей Глушенко <[hidden email]> написал:
Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Nikolay Kleptsov
In reply to this post by Сергей Глушенко
если смотреть только на один метод, могу и ошибаться,
isUseCountInTimeFunction и countTime выделить в отдельную сущность
также относиться и к
- (isUsePulseDurationFunction hasPositivDurationOutput hasNegativeDurationOutput)
-
(isUseDelayLineFunction hasDelayTimeInput delayTimeConstant hasDestinationOutput controllerDestinationpinNumber controllerDestinationpinNumber)

в этих объектах (сущностях) реализовать метод isCorrect или использовать callback методы (например, сложение разных типов чисел) где сначала идет общий метод сложения, далее у разных типов чисел через уточняющие методы происходит сложение

13 января 2015 г., 17:28 пользователь Сергей Глушенко <[hidden email]> написал:
Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Сергей Глушенко
In reply to this post by Dennis Schetinin
Конечно

isUseCountInTimeFunction

    isUseCountInTimeFunction ifNotNil
: [^isUseCountInTimeFunction].
    isUseCountInTimeFunction
:= true.
   
^isUseCountInTimeFunction


isNeededPositiveInterruptFunction

   
self hasInputValueOutput ifTrue: [^true].
   
self isUseDelayLineFunction
        ifTrue
: [self hasDelayPositiveFront ifTrue: [^true]].
   
self isUsePulseDurationFunction ifTrue: [^true].
   
(self isUseCountPulseFunction and: [self isUsePositiveFrontForPulseCount])
        ifTrue
: [^true].
   
^false

isSpeedCounter

   
^true

hasDestinationOutput

   
^destinationOutput isNil not

canConnectOutput
: aArduinoFBDInputOutput to: aArduinoFBDConnection
aArduinoFBDInputOutput isBooleanType ifTrue
:[^aArduinoFBDConnection isBooleanType].
   
^aArduinoFBDConnection isNumberType


ну я так пробежался по тестовым методам. там их много

вторник, 13 января 2015 г., 17:00:22 UTC+5 пользователь chaetal написал:
А можно увидеть наиболее типичные реализации методов isUse…, has…?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 15:28 пользователь Сергей Глушенко <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="4uCYp0hWsusJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sup...@...> написал:
Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
<a href="http://groups.google.ru/group/sugr" target="_blank" onmousedown="this.href='http://groups.google.ru/group/sugr';return true;" onclick="this.href='http://groups.google.ru/group/sugr';return true;">http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес <a href="javascript:" target="_blank" gdf-obfuscated-mailto="4uCYp0hWsusJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке <a href="https://groups.google.com/d/optout" target="_blank" onmousedown="this.href='https://groups.google.com/d/optout';return true;" onclick="this.href='https://groups.google.com/d/optout';return true;">https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: TDD и вообще юнит-тесты in the wild

Dennis Schetinin
In reply to this post by Nikolay Kleptsov
Вообще, напрашивается что-то вроде

^ elements anySatisfy: [:each | each isEffective and: [each isCorrect not]]) 


--

Best regards,


Dennis Schetinin


13 января 2015 г., 16:01 пользователь Nikolay Kleptsov <[hidden email]> написал:
если смотреть только на один метод, могу и ошибаться,
isUseCountInTimeFunction и countTime выделить в отдельную сущность
также относиться и к
- (isUsePulseDurationFunction hasPositivDurationOutput hasNegativeDurationOutput)
-
(isUseDelayLineFunction hasDelayTimeInput delayTimeConstant hasDestinationOutput controllerDestinationpinNumber controllerDestinationpinNumber)

в этих объектах (сущностях) реализовать метод isCorrect или использовать callback методы (например, сложение разных типов чисел) где сначала идет общий метод сложения, далее у разных типов чисел через уточняющие методы происходит сложение

13 января 2015 г., 17:28 пользователь Сергей Глушенко <[hidden email]> написал:

Не вся конечно. Классы имеют свое поведение. Умеют рисоваться, каждый тип данных (Boolean, Float, Integer ...) Это отдельный класс со своим поведением. Назначение блока задает его тим. Блок это просто хранитель данных. Его тип - его описатель. В библиотеке элементов лежат типы на основании которых создаются инстансы блоков. Переменные - это то же блок, внури которых лежит тэг. в теге лежит тип, ну и еще кое что необходимое. Поведение блока задается комбинацией содержимого. Например если значение какгого то параметра может быть константой или задаваться со входа  то в зависимости от выбора пользователя в переменной value лежит инстанс класса  InputValue или класса ConstantValue. и кода компилятор спросит у блока значение этой величины, один инстанс отдаст значение логической стоки для входа, а другой значение хранящейся в нем константы. Ну где то так только немного посложнее. Это сильное упрощение. Например константа может быть разной размерности Например: микросекунды, милисекунды, минуты-секунды-милисекунды. А в скетче нужны микросекунда. Соответственно инстанс все пересчитает. И так далее. Я знаю что это называется композиция, но конствнты находятся в иерархии с головой ParametrValue. И эти классы применяются при необходимости во всех классах. If-ы конечно есть, от них никуда не денешся. И я не считаю злом их использование. Если где то можно обойтись небольшими количеством If-ов не создавая лишний класс, я не стесняюсь их использовать. Главное что бы не было большого вложения. Если начинаются вложения, лучше сделать отдельный метод с выходами по условиям. Получается красиво и и наглядно.
Например метод проверки корректности модуля скоростного счетчика:

isCorrect

   
super isCorrect ifFalse: [^false].
    pinNumber ifNil
: [^false].
   
self isUseCountInTimeFunction ifTrue: [countTime ifNil: [^false]].
   
self isUsePulseDurationFunction
        ifTrue
:
           
[(self hasPositivDurationOutput or: [self hasNegativeDurationOutput])
                ifFalse
: [^false]].
   
self isUseDelayLineFunction
        ifTrue
:
           
[self hasDelayTimeInput ifFalse: [self delayTimeConstant ifNil: [^false]].
           
self hasDestinationOutput
                ifFalse
: [self controllerDestinationpinNumber ifNil: [^false]]].
   
^true
 P.S. Не ругайте за английский, я в нем не силен


вторник, 13 января 2015 г., 16:02:05 UTC+5 пользователь chaetal написал:
И вся эта логика на if-ах — я правильно понимаю?


--

Best regards,


Dennis Schetinin


13 января 2015 г., 10:29 пользователь Сергей Глушенко <[hidden email]> написал:
Я об этом думал, не поможет.
Вот смотри.
Реализация PostCopy  в разных блоках сильно отличается.
       Вода - выхода - вход может быть, или его может не быть. Если он есть - (не nil) то надо сделать его копию и привязать к новому блоку. Конечно ссылка на родительский объект в дочернем - это полхо - я понимаю, но поиск родителя через проект безумно тормозит отрисовку. Поэтому я пошол на этот не самый лучший шаг.  кроме входов в блоке куча других переменных. и работа с ними в разных блоках отличается. Например блок датчика DHT-11. При копировании блока необходимо в переменную содержащую модель датчика положить новый чистый инстанс модели. Блок дисплея. Если дисплей прямого подключения - его надо снести (засунуть nil), если дисплей по i2С даже копировать не надо. И так в каждом конкретном случае рассматривается, что надо скопировать. что надо снести, что надо оставить без изменения. Кое где необходимо просто поменять внутри данные, без копирования. 

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


вторник, 13 января 2015 г., 11:11:00 UTC+5 пользователь Vladimir Musulainen написал:
Все объекты, которым надо копироваться полностью, включая копии объектов в instance variable наследуем от одного класса, который называем CopyableObject.
У класса CopyableObject определяем метод postCopy что-то типа
postCopy

postCopy
super postCopy.
myInstanceVariablesNames do: [:each | self at: each name put: each copy]


Это не решит всех проблем с PostCopy?




13 янв. 2015 г., в 7:06, Сергей Глушенко <[hidden email]> написал(а):

Для "простых" блоков где входа и выхода - коллекции у меня реализовано  автоматическая операция PostCopy. Для более навороченных которые сейчас в основном разрабатываются где входы и выходы именные все сложнее. Я пока не придумал реализацию как производить проверку правильности копирования. Плюс в блоках чаще всего вложенны другие сложные объекты. Все блоки по этому критерию отличаются так что универсального теста не сделать. Большинство блоков после создания не модернизируются.соответственно правильно сделанные и проверенные не нуждаются в дальнейшем тестировании. 
Для себя я решил проблемму старым проверенным способом. Бумажка на мониторе))) Цитирую:
PostCopy!!!!! (Там знаков большею Каждый раз когда матерюсь что забыл, ставлю один восклицательный знак.)
LAD - тип входов (при переносе в блока в LAD необходимо сменить тип входов. Все не решаюсь привести в FBD и LAD ихода и выхода к одному классу. Могут полететь старые проекты, хотя идея более менее безопасного перехода уже есть)
isCorrect- проверить (проверить правильность выполнения проверки корректности блока. Если упустить какое либо некорректное состояние блока, например не заполненное полк номера пинато пользователи обязательно на это состояние напорятся и при компиляции либо получат ошибку, либо скетч не будет работать  )

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес sugr+uns...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

--
--
http://groups.google.ru/group/sugr
---
Вы получили это сообщение, поскольку подписаны на группу "Russian Smalltalk User Group".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес [hidden email].
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.
1234