Как тестировать приватные функции класса?
От: denis miller Россия http://agile20.ru
Дата: 06.12.08 23:34
Оценка: 7 (3) -3 :)))
Знакомый вопрос? И какие у нас есть решения
1. Использовать рефлекшн
2. Директивы компиляции #if DEBUG — ужас
3. Ваше любимое

Если первое решение смерть всему поколению поддержки, а второе ужас на крыльях ночи, то стоит вопрос — а чего делать-то?

TDD нас учит — пишите тесты и всё будет пучком. Действительно будет, но жизнь не идеальна. И появляются приватные методы и конечно же возникает желание их потестить.

Почему многие бьются, но не находят решения? А потому как мы находимся в такой парадигме программирования, которые не предполагает решения. Там его просто нет. Спросите, а что не так с нашей парадигмой? Да всё просто — мы со своей теорией знания ООП лезем в бизнес-разработку. Теория ООП — это академически дисцеплина. А наш код — это бизнес-реальность.

Что говорит теория — инкапсулируй, скрывай и т.п.

А что говорит бизнес? Гони нам качественное и дешевое решений! А почему же теория делает нам решение не дешёвым? А все просто — нету тестов, запутанный код, неясная логика, неадекватные называния и огромная связанность даёт прибавки в стоимости нашего кода в части поддержки и развития. Мы платим огромные сумма за поддержку и развитие кода, нежели его создания. Пусть икает тот разработчик, который первый породил тот или инной класс. И получил свои 10$ за него. Теперь мы дни тратим понимая, почему он вызывает отъезжание в другом месте и днями на пролёт эксперементируем как к этому делу прикрутить чуть больше функций. И платим за это сотни, а может быть даже тысячи баксов.

То есть задача бизнес кода — получить дешевое решение. Которое легко развивать, сопровождать, читать, анализировать и оно обладает минимальной связанностью. Конечно же TestFirst, TDD, Refactoring, Patterns, Continuous Integration здесь наше спасение. Но вернёмся к приватам.

Парадигма "бизнес разработки" такова, что нужно посмотреть, кто является клиентами нашего кода. Кто использует продукт нашего творчества? Мы должны сделать все возможное и невозможное, нарушая теоретические полёты мысле теоретиков от ООП, с целью удешевления поддержки и развития.

А клиентами нашего кода являются: конечные пользователи и разработчики. Причем ещё не ясно, кто больше наш код использует. Пользователи тыкают конечно приложение. Но кто вас чаще вспоминать будет, если вы нагородили подлянок на каждом шагу, не проводили рефакторинги и вообще оставили тучу смеллов не покрытых тестами?

Итог. Клиенты кода — это заказчик + разработчики. Причем последний в большей мере. Так какого мы тресёмся за теоретическую инкапсуляцию и забиваем на тесты открывая нужные функции, делая их protected (шунтируя для теста класс, например) или даже public? Кончайте голову себе и другим пудрить! Делайте дело и используйте всё многообразие подходов, чтобы качество кода было 101% и его цена минимальна!
Re: Как тестировать приватные функции класса?
От: SergH Россия  
Дата: 06.12.08 23:38
Оценка: 1 (1) +3 :)
Здравствуйте, denis miller, Вы писали:

...

Мне кажется, ты не программист, а маркетолог.
Ты точно не ошибся сайтом?
Делай что должно, и будь что будет
Re[2]: Как тестировать приватные функции класса?
От: denis miller Россия http://agile20.ru
Дата: 06.12.08 23:39
Оценка: :)
SH>Мне кажется, ты не программист, а маркетолог.
SH>Ты точно не ошибся сайтом?

Нет.

А вот ты точно программист. Если не понял суть сообщения.
Re[3]: Как тестировать приватные функции класса?
От: denis miller Россия http://agile20.ru
Дата: 06.12.08 23:40
Оценка: +1 -2
А вот ты точно НЕ программист. Если не понял суть сообщения.
Re: Как тестировать приватные функции класса?
От: MozgC США http://nightcoder.livejournal.com
Дата: 07.12.08 01:13
Оценка:
Здравствуйте, denis miller, Вы писали:

DM>Так какого мы тресёмся за теоретическую инкапсуляцию и забиваем на тесты открывая нужные функции, делая их protected (шунтируя для теста класс, например) или даже public?

Я не очень понял это предложение. Что вы имели в виду?

Я так же не очень понял что вы предлагаете. Не заморачиваться и делать методы protected/public?
Re[4]: Как тестировать приватные функции класса?
От: SergH Россия  
Дата: 07.12.08 02:03
Оценка:
Здравствуйте, denis miller, Вы писали:

DM>А вот ты точно НЕ программист. Если не понял суть сообщения.


А если понял?
Делай что должно, и будь что будет
Re: Как тестировать приватные функции класса?
От: Igor Sukhov  
Дата: 07.12.08 02:58
Оценка:
Здравствуйте, denis miller, Вы писали:

DM>Знакомый вопрос? И какие у нас есть решения

DM>1. Использовать рефлекшн
DM>2. Директивы компиляции #if DEBUG — ужас
DM>3. Ваше любимое

DM>Если первое решение смерть всему поколению поддержки, а второе ужас на крыльях ночи, то стоит вопрос — а чего делать-то?


DM>TDD нас учит — пишите тесты и всё будет пучком. Действительно будет, но жизнь не идеальна. И появляются приватные методы и конечно же возникает желание их потестить.


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

вопрос в другом — готовы ли вы встретиться с этим животным сегодны или завтра. многие скажут нет. придет он завтра? — нет. тогда.
готовы ли вы встретится с песцом в будущем. конечно! who gives a damn.
... << RSDN@Home 1.2.0 alpha rev. 0>>
* thriving in a production environment *
Re: Как тестировать приватные функции класса?
От: Рек Россия  
Дата: 07.12.08 03:46
Оценка: +1
Здравствуйте, denis miller, Вы писали:

DM>Знакомый вопрос? И какие у нас есть решения

DM>1. Использовать рефлекшн
DM>2. Директивы компиляции #if DEBUG — ужас
DM>3. Ваше любимое

4. Сделать приватные методы internal (не очень большой грех в смысле инкапсуляции)
+ объявить сборку с тестами как [assembly:InternalsVisibleTo( "Tests")].
internalsvisibleto
Re: Как тестировать приватные функции класса?
От: IT Россия linq2db.com
Дата: 07.12.08 05:01
Оценка:
Здравствуйте, denis miller, Вы писали:

DM>Знакомый вопрос? И какие у нас есть решения


Для internal методов можно использовать InternalsVisibleToAttribute.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Как тестировать приватные функции класса?
От: denis miller Россия http://agile20.ru
Дата: 07.12.08 08:35
Оценка: -2
DM>>Знакомый вопрос? И какие у нас есть решения
DM>>1. Использовать рефлекшн
DM>>2. Директивы компиляции #if DEBUG — ужас
DM>>3. Ваше любимое
Рек>4. Сделать приватные методы internal (не очень большой грех в смысле инкапсуляции)
Рек> + объявить сборку с тестами как [assembly:InternalsVisibleTo( "Tests")].
Сделать фрэнда в общем.
5. Использовать средства IDE (например студия делает обёртку над рефлекшн).

MozgC, понял почти верно. С нюансом, если потребуется написать тест, то останавливаться на вышеперечисленных 5 методах не стоит. Просто открываем (protected/public в зависимости от способа тестирования).
SergH, если понял — то критикуй или развивай. Идея интересная (покрайне мере мне), требует разложения по полочкам.
Igor Sukhov, здесь разговор не о TDD. Но твоё представление тоже имеет место быть. Тут не поспоришь
Рек, IT — учёл фрэндов.

Отлично, спасибо за идеи. Но я хотел бы подчеркнуть. Выжимку
Я выделил 3 парадигмы разработки, который порождает рассматриваемый случай
1. "Теоретическая" (когда неуклонно следуем ООП и придумываем обходные манёвры о которых в ООП ничего не говорится и считаем их хорошими — см. п.1-п.5 выше). Максимальное количество private.
2. TDD — уже смещает парадигму мышления и на выходе получаем изолированные модули. Но и там проскакивает приват. Который приводит к одному из п.1-п.5
3. "Бизнес-программирование". Используем TDD + открываем (protected|public) методы для нужд тестирования. Так как я являюсь пользователем своего кода и мне важно его качество выраженное через 1) покрытие тестами, 2) просте чтения.
Re: Как тестировать приватные функции класса?
От: LexxFedoroff  
Дата: 07.12.08 10:25
Оценка:
Здравствуйте, denis miller, Вы писали:

DM>Знакомый вопрос? И какие у нас есть решения

DM>1. Использовать рефлекшн
DM>2. Директивы компиляции #if DEBUG — ужас
DM>3. Ваше любимое

Встроенный в Visual Studio 2008 тестовый движок умеет тестировать приватный методы.
Re: Как тестировать приватные функции класса?
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 07.12.08 10:32
Оценка: 2 (1) +11
На мой взгляд, проблема является надуманной. Юнит-тестирование отдельного (тем более, приватного) метода класса в нашем проекте ещё никогда не приводило к каким-либо положительным результатам. Гораздо полезнее тестировать функционал программы и только если с ним не всё в порядке, разбираться в конкретных методах конкретных классов. Получается дешевле и эффективнее.

Существует стойкое убеждение, что если б я нагородил кучу тестов вокруг каждого метода класса и ещё вдобавок стал бы заморачиваться с проблемой приватности этого метода, то получилась бы гора кода, который просто стало бы невозможно сопровождать.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[2]: Как тестировать приватные функции класса?
От: IT Россия linq2db.com
Дата: 07.12.08 11:08
Оценка: 1 (1) +1 -1
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>На мой взгляд, проблема является надуманной.


Думаю, что надуманность проблемы является как минимум спорным утверждением.

КЛ>Существует стойкое убеждение, что если б я нагородил кучу тестов вокруг каждого метода класса и ещё вдобавок стал бы заморачиваться с проблемой приватности этого метода, то получилась бы гора кода, который просто стало бы невозможно сопровождать.


Разве речь идёт об этом в исходном сообщении?
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Как тестировать приватные функции класса?
От: Aikin Беларусь kavaleu.ru
Дата: 07.12.08 14:49
Оценка: 11 (4) +3
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Кирилл Лебедев, Вы писали:


КЛ>>На мой взгляд, проблема является надуманной.

IT>Думаю, что надуманность проблемы является как минимум спорным утверждением.
Именно надуманна. По другому и не скажешь.

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

С точки зрения тестирования функциональности, а не реализации, если возникает задача протестировать приватный метод, то он явно представляет собой отдельный кусок функциональности. Который "открывают миру" либо (что чаще бывает из за нарушения SRP) переносят из родительского класса в более подходящий.

СУВ, Aikin
Re: Как тестировать приватные функции класса?
От: stump http://stump-workshop.blogspot.com/
Дата: 07.12.08 17:02
Оценка: 49 (5) +9 -1
Здравствуйте, denis miller, Вы писали:

DM>Знакомый вопрос? И какие у нас есть решения

Только через публичный контракт класса.
Если в голову лезут еще какие либо "решения", значит смысл модульного тестирования до вас еще не дошел. (И это старанно, поскольку вы Денис порываетесь преподавать его другим).
Что есть модульный тест? Это пример того, как внешний код будет использовать ваш класс. Зачем может понадобиться модульный тест для приватных методов класса, неужели вы расчитываете на то, что внешний код будет вызывать приватные методы вашего класса? Так почему не сделать их публичными?
Вопрос о тестировании приватных членов — это вопрос новичков. Вот у меня есть куча приватных методов и мне надо покрыть их тестами, как же мне это сделать? Это делается всегда одним и только одним способом — тестированием публичного контракта класса.

Я вот недавно писал библиотеку, в которой доля публичных методов менее 20%, остальные private и protected. Модульные тесты покрывают 95% кода библиотеки, причем тестируются только публичные члены. Я легко достиг бы и 100% покрытия, дописав guard-тесты, поскольку непокрытый код, это по большей части, валидация входных параметров и строки, выкидывающие исключения, но мне просто лень.
Скажу более, в паре приватных методов я нашел большие куски по 6 -10 строк кода, не покрытые тестами. При внимательном рассмотрении, оказалось что этот код просто лишний . Он никогда не вызывался и я его просто выкинул.
Так что, если у вас остались непротестированным какие-то приватные члены, то тут одно из двух: либо у вас плохие тесты, либо в классе лишний код, который никогда не используется.
А все перчислемые здесь "способы" сделают ситуацию только хуже. Хуже станут тесты, или хуже станет дизайн, или и то и другое.

<остальное поскипано ввиду явной бессмысленности>
Понедельник начинается в субботу
Re[2]: Как тестировать приватные функции класса?
От: Mike Chaliy Украина http://chaliy.name
Дата: 07.12.08 17:14
Оценка:
Здравствуйте, stump, Вы писали:

S>Вопрос о тестировании приватных членов — это вопрос новичков. Вот у меня есть куча приватных методов и мне надо покрыть их тестами, как же мне это сделать? Это делается всегда одним и только одним способом — тестированием публичного контракта класса.


Это не тока вопрос новичков. Это иногда вопрос потдержки старого кода. А иногда дизайна. А иногда спущеного с верху рекваирмента 90% код кавердж.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[3]: Как тестировать приватные функции класса?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 07.12.08 17:37
Оценка: +2
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, stump, Вы писали:


S>>Вопрос о тестировании приватных членов — это вопрос новичков. Вот у меня есть куча приватных методов и мне надо покрыть их тестами, как же мне это сделать? Это делается всегда одним и только одним способом — тестированием публичного контракта класса.


MC>Это не тока вопрос новичков. Это иногда вопрос потдержки старого кода. А иногда дизайна. А иногда спущеного с верху рекваирмента 90% код кавердж.

Поддержка и покрытие старого не тестированного кода — отдельная тема.

А вот реквайрменты типа 90% покрытия — определенное зло, вследствии которого код красится, но не проверяется (появляются тесты без Assert-ов; проверяются гуард условия, но не функциональность... по достижении 90% тестирование просто прекращается).
В тестировании должны быть заинтересованы разработчики, а не руководство. И если разработчики не догоняют о необходимости тестирования, то требованиями о 90% покрытии ситуацию не исправить. Тесты будут лишь обузой в таком случае.
Re[3]: Как тестировать приватные функции класса?
От: SergH Россия  
Дата: 07.12.08 17:57
Оценка: 80 (8) +8 :)
Здравствуйте, denis miller, Вы писали:

DM>SergH, если понял — то критикуй или развивай. Идея интересная (покрайне мере мне), требует разложения по полочкам.


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

Начнём с конца. Итак, допустим, ты программист, у тебя есть идея, ты хочешь её обдумать с разных сторон с помощью коммунити. Что ты в таком случае делаешь? Пишешь примерно следующее:

1. мужики, смотрите сюда, какую штуку придумал.
2. на мой взгляд, есть вот такая проблема, которую игнорирует стандартный подход. ...
3. и обходные решения не работают. ...
4. а вот если взять и вот так-вот -- всё решается. ...
5. что думаете?

Смотрим, что делаешь ты реальный:




Как тестировать приватные функции класса?
Знакомый вопрос? И какие у нас есть решения
1. Использовать рефлекшн
2. Директивы компиляции #if DEBUG — ужас
3. Ваше любимое

Если первое решение смерть всему поколению поддержки, а второе ужас на крыльях ночи, то стоит вопрос — а чего делать-то?


Это 1+3. Высказанные в сугубо директивной манипулятивной манере. Никаких мыслей о том, есть ли такая проблема вообще, и чего её до сих пор не замечали. Никаких сомнений, что она есть.

TDD нас учит — пишите тесты и всё будет пучком. Действительно будет, но жизнь не идеальна. И появляются приватные методы и конечно же возникает желание их потестить.

Почему многие бьются, но не находят решения?


Что это за многие? Ну, типичный маркетинговый ход.

А потому как мы находимся в такой парадигме программирования, которые не предполагает решения. Там его просто нет. Спросите, а что не так с нашей парадигмой? Да всё просто — мы со своей теорией знания ООП лезем в бизнес-разработку. Теория ООП — это академически дисцеплина. А наш код — это бизнес-реальность.


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

Что говорит теория — инкапсулируй, скрывай и т.п.

А что говорит бизнес? Гони нам качественное и дешевое решений! А почему же теория делает нам решение не дешёвым? А все просто — нету тестов, запутанный код, неясная логика, неадекватные называния и огромная связанность даёт прибавки в стоимости нашего кода в части поддержки и развития.


Какая-то плохая очень теория. Это ещё один маркетинговый ход: повесить все возможные грехи на "старый" товар. И запутанный, и неясный, и названия неадекватны, и связность. И всё это -- потому что "инкапсулируй"? Вообще-то инкапсуляция уменьшает связность. А на названия не влияет... Или потому что "академическая"? Тоже неочевидное следствие.

Мы платим огромные сумма за поддержку и развитие кода, нежели его создания. Пусть икает тот разработчик, который первый породил тот или инной класс. И получил свои 10$ за него. Теперь мы дни тратим понимая, почему он вызывает отъезжание в другом месте и днями на пролёт эксперементируем как к этому делу прикрутить чуть больше функций. И платим за это сотни, а может быть даже тысячи баксов.


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

То есть задача бизнес кода — получить дешевое решение. Которое легко развивать, сопровождать, читать, анализировать и оно обладает минимальной связанностью. Конечно же TestFirst, TDD, Refactoring, Patterns, Continuous Integration здесь наше спасение.



Красиво блеснул английскими словами...

Но вернёмся к приватам.

Парадигма "бизнес разработки" такова, что нужно посмотреть, кто является клиентами нашего кода.


Почему это специфика именно "бизнес-подхода"? Академики об этом не думали?

Кто использует продукт нашего творчества? Мы должны сделать все возможное и невозможное, нарушая теоретические полёты мысле теоретиков от ООП, с целью удешевления поддержки и развития.


Опять шлак про злых теоретиков...

А клиентами нашего кода являются: конечные пользователи и разработчики. Причем ещё не ясно, кто больше наш код использует. Пользователи тыкают конечно приложение. Но кто вас чаще вспоминать будет, если вы нагородили подлянок на каждом шагу, не проводили рефакторинги и вообще оставили тучу смеллов не покрытых тестами?


Как эта ужасная картина связана с приватами и инкапсуляцией? Опять всё вешаем на "старый продукт"?

Итог. Клиенты кода — это заказчик + разработчики. Причем последний в большей мере.


Согласен. Это, кстати, можно было написать первой строчкой, всё предыдущее -- в урну.

Так какого мы тресёмся за теоретическую инкапсуляцию и забиваем на тесты открывая нужные функции, делая их protected (шунтируя для теста класс, например) или даже public?


Это предложение не связано с предыдущим. И что означает слово "шунтирование" в данном случае?

Кончайте голову себе и другим пудрить! Делайте дело и используйте всё многообразие подходов, чтобы качество кода было 101% и его цена минимальна!


Переходите на наш новый продукт и ... 101% и его цена минимальна!




Ну, самому не стыдно?

Почему должно быть стыдно. Потому что у маркетолога и у разработчика принципиально разные цели. Маркетолог хочет _впарить_. Разработчик хочет обсудить идею с коллегами. Маркетолог не брезгует не очень честными приёмами. Разработчик уважает коллег, иначе ему не зачем с ними что-либо обсуждать. Маркетолог скрывает невыгодные стороны, т.к. ему нужно впарить. Разработчик полностью открыт, т.к. ему нужна правда.

Ага?
Делай что должно, и будь что будет
Re[3]: Как тестировать приватные функции класса?
От: Beam Россия  
Дата: 07.12.08 19:09
Оценка: 4 (1)
Здравствуйте, denis miller, Вы писали:

DM>Отлично, спасибо за идеи. Но я хотел бы подчеркнуть. Выжимку

DM>Я выделил 3 парадигмы разработки, который порождает рассматриваемый случай
DM>1. "Теоретическая" (когда неуклонно следуем ООП и придумываем обходные манёвры о которых в ООП ничего не говорится и считаем их хорошими — см. п.1-п.5 выше). Максимальное количество private.

При "теоретической" разработке, надо обеспечивать инкапсуляцию не за счет private методов, а за счет выделения интерфейсов. В этом случае, хоть все методы делай public, сам класс-то не виден... И инкапсуляция не нарушена и тестируй — не хочу.

А вообще наиболее подходящий вариант на мой взгляд, это использование internal.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Best regards, Буравчик
Re[4]: Как тестировать приватные функции класса?
От: Mike Chaliy Украина http://chaliy.name
Дата: 07.12.08 19:21
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Здравствуйте, stump, Вы писали:


S>>>Вопрос о тестировании приватных членов — это вопрос новичков. Вот у меня есть куча приватных методов и мне надо покрыть их тестами, как же мне это сделать? Это делается всегда одним и только одним способом — тестированием публичного контракта класса.


MC>>Это не тока вопрос новичков. Это иногда вопрос потдержки старого кода. А иногда дизайна. А иногда спущеного с верху рекваирмента 90% код кавердж.

S>Поддержка и покрытие старого не тестированного кода — отдельная тема.

S>А вот реквайрменты типа 90% покрытия — определенное зло, вследствии которого код красится, но не проверяется (появляются тесты без Assert-ов; проверяются гуард условия, но не функциональность... по достижении 90% тестирование просто прекращается).

S>В тестировании должны быть заинтересованы разработчики, а не руководство. И если разработчики не догоняют о необходимости тестирования, то требованиями о 90% покрытии ситуацию не исправить. Тесты будут лишь обузой в таком случае.

Не все работают в идеальных компаниях. У нас четко было спущено 90% покрытия. И это на легаси код. И писали эти так сказать тесты, не те люди которые писали код. И рефакторить было запрещено.... Я начинаю хандрить... Тока не отвечайте на этот пост.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.