Re[37]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 06.05.16 18:18
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Ты перепутал хорошесть машины и хорошесть маркетинга.

Вовсе нет.
Но это уже оч. сильно офтоп...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[39]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 06.05.16 18:29
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Им вообще остается проверять сборку на соответствие спецификациям, по большому счету.


Если над уровнем юитов нет какого-то сложного их взаимодействия....
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[39]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 20:17
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


L>>>По-твоему получается, что из статьи следует, что все, что я делал последние 10+ лет, сделать было невозможно? Забавно.


__>>нет, это означает, что то, что вы делали за последние десять лет, на самом деле не "проверить, что поведение в принципе соответствует ожидаемому", а "establish that it[system function] does not function properly under specific conditions"


L>

L>Testing cannot establish that a product functions properly under all conditions but can only establish that it does not function properly under specific conditions.


L>Иными словами, это означает, что в случае ЧЯ тестирования тот факт, что система правильно функционирует в условиях, в которых ее тестеры не поленились прогнать, вовсе не гарантирует, что система будет правильно функционировать вообще во всех условиях. С этим никто не спорит. Все возможные условия просто не проверить (комбинаторный взрыв, однако).


L>Но вот тут и приходит понимание того, в чем вся мощь юнит-тестирования.


L>При правильном подходе к организации кода и покрытию сценариев его использования прогаммист может протестировать все сценарии использования юнита. Абсолютно все.


но это же неправда — даже для обычной foo(uint32_t x, uint32_t y) практически невозможно проверить абсолютно все комбинации аргументов/


L>Обычно. Как правило. Чем опытнее TDD-программист, тем сильнее его "обычно" стремится к "всегда". Иногда это не так, иногда это и правда дорого (привет, Erop), иногда просто лень, иногда тупо непонятно, что нужно делать в случае определенных входных данных, которых никогда быть не должно.


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

L>Что это означает? Что система, состоящая из оттестированных юнитов, в тестировании не нуждается? You wish! Это означает нечто другое, а именно то, что система уже прошла раннюю верификацию. Тестерам не нужно искать сломанное сетевое устройство, чтобы проверить поведение системы в случае общения с устройством, которое портит сообщения, так как логика этого поведения уже проверена.

L>Им вообще остается проверять сборку на соответствие спецификациям, по большому счету.

и опять же я в самом начале про это говорил — что там, где разработка ведется методом "взял готовые функциональные блоки, и скомпоновал их нужным образом" — унит-тестирование выглядит выигрышно, а вот там, где ведется непосредственная разработка этих блоков — не совсем.
Re[33]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 20:27
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


L>>>Хмм.. по мне так оно весьма конкретное. Означает — юнит тесты подают на вход тестируемого юнита некие данные и сравнивают отклик с ожидаемым.

__>>а, ну вот теперь более конкретно.
L>>>Погоди, что запустили? Вот вы начинаете работу над совершенно новым проектом. Твоя задача — реализовать.... ну драйвер сканера (courtesy of Erop). Вот ты пишешь первый класс, уж не знаю, какой. Что ты запускаешь? Ничего запускаемого еще нет и 10 месяцев не будет. Как ты проверишь?
__>>да спокойно. возьму и отдельно повызываю его методы на прогонных значениях (ведь прогон же не считается юнит-тестом?)

L>Таак, уже теплее. Вот это "возьму отдельно и повызываю методы" ты как делаешь? Вот новый проект, ничего запускаемого еще нет. Какие действия?


например, CA A; A.foo(0); A.foo(1); A.foo(0.5)// для крайних значений 0, -1 и обычного 0.5


__>>>>не понял что нельзя написать assert(nullptr != data); ?


L>>>Нет, во многих случаях писать его там бессмысленно.


L>Потому что это либо означает, что нужна полноценная проверка в рантайме, либо архитектура плохо продумана, либо ассерт просто воткнут туда "на всякий случай", потому что "так принято".


это означает, что при нормально работающей системе nullptr-а там быть не должно, а вот на этапе разработке, вполне может появиться, и это будет свидетельствовать об ошибке

L>>>>>Чтобы верифицировать поведение do_smth, код ассерта должен полностью реализовывать алгоритм, который он верифицирует.

__>>>>ну, то есть, опять же, отличие в невозможности ассерта протестировать именно функциональность (работу функции при всевозможных различных аргументах)? так?
L>>>Как минимум, для начала.

__>>ок. спасибо.


L>Это, на самом деле, отличие, которое и отличает каменный век от века полетов в космос


ммм... пока не понял, как именно осуществляется тестирование функциональности (задача вроде неподъемная из-за "комбинаторного взрыва"), и почему его нужно считать качественным шагом вперед. но спасибо за диалог — начало что-то проясняться
Re[35]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 20:37
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


__>>>>так в сложных случаях есть брейк-поинты, когда вместо того, чтобы анализировать весь поток управления, выделяют отдельные его фрагменты, подпадающие под подозрение (с помощью тех же ассертов)

L>>>Это тоже крайне простые случаи.
__>>а какие сложные? (если не брать во внимание многопроцессные проги)?

L>Многопоточные, наверное? Они, родимые.


не, их в рассмотрение не включаем это отдельная головная боль

L>Да даже и в однопоточной факт наблюдения чертовщины в отладчике вовсе не гарантирует, что она вызвана именно на этом месте в call stack.


это почему же?
Re[39]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 20:39
Оценка:
Здравствуйте, Erop, Вы писали:

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


__>>вооот!!!! у вас повилось понятие "шаг" и "лог", а это есть ни что иное, как шаг дебагера и состояние процесса (watched variables)


E>Логи удобнее.


неважно. де-факто вы производите поиск ошибок путем последовательного отслеживания состояний процесса — в точности то, что делает дебагер.
Re[40]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 06.05.16 20:46
Оценка: +1
Здравствуйте, _hum_, Вы писали:

__>но это же неправда — даже для обычной foo(uint32_t x, uint32_t y) практически невозможно проверить абсолютно все комбинации аргументов/


А все и не нужно... Нужно протестить все границы и ветки, а не все комбинации...

L>>Им вообще остается проверять сборку на соответствие спецификациям, по большому счету.


__>и опять же я в самом начале про это говорил — что там, где разработка ведется методом "взял готовые функциональные блоки, и скомпоновал их нужным образом" — унит-тестирование выглядит выигрышно, а вот там, где ведется непосредственная разработка этих блоков — не совсем.


IMHO всё ровно наоборот. Если есть оттестированные блоки, которые мы компонуем типа, то юнит-тест не много дадут, а вот если мы новые блоки пишем, то там юнит-тесты блоков зело полезны...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[40]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 20:47
Оценка:
Здравствуйте, _hum_, Вы писали:

L>>При правильном подходе к организации кода и покрытию сценариев его использования прогаммист может протестировать все сценарии использования юнита. Абсолютно все.

__>но это же неправда — даже для обычной foo(uint32_t x, uint32_t y) практически невозможно проверить абсолютно все комбинации аргументов/

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

L>>Обычно. Как правило. Чем опытнее TDD-программист, тем сильнее его "обычно" стремится к "всегда". Иногда это не так, иногда это и правда дорого (привет, Erop), иногда просто лень, иногда тупо непонятно, что нужно делать в случае определенных входных данных, которых никогда быть не должно.


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


Не требуют они затрат. Пишутся на автомате.

__>и опять же я в самом начале про это говорил — что там, где разработка ведется методом "взял готовые функциональные блоки, и скомпоновал их нужным образом" — унит-тестирование выглядит выигрышно, а вот там, где ведется непосредственная разработка этих блоков — не совсем.


Юнит-тесты применяются в основном как раз для тестирования этих самых блоков при их разработке. Любое другое тестирование при этом выглядит проигрышно.
Re[36]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 20:48
Оценка:
Здравствуйте, _hum_, Вы писали:

L>>Многопоточные, наверное? Они, родимые.

__>не, их в рассмотрение не включаем это отдельная головная боль

А вот надо включать, чтобы головную боль как можно раньше отгильотинить

L>>Да даже и в однопоточной факт наблюдения чертовщины в отладчике вовсе не гарантирует, что она вызвана именно на этом месте в call stack.

__>это почему же?

Ну тут уже упоминали такую приятную вещь, как стрельбу по памяти, например.
Re[41]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 20:54
Оценка: +1
Здравствуйте, Erop, Вы писали:

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


__>>но это же неправда — даже для обычной foo(uint32_t x, uint32_t y) практически невозможно проверить абсолютно все комбинации аргументов/


E>А все и не нужно... Нужно протестить все границы и ветки, а не все комбинации...


во-первых, что такое "границы" ? граничные точки области определения функции? и почему именно в них нужно, а в других точках — не нужно?

а во-вторых, таких граничных точек может быть тоже неподъемно много для обычных вычислений

L>>>Им вообще остается проверять сборку на соответствие спецификациям, по большому счету.


__>>и опять же я в самом начале про это говорил — что там, где разработка ведется методом "взял готовые функциональные блоки, и скомпоновал их нужным образом" — унит-тестирование выглядит выигрышно, а вот там, где ведется непосредственная разработка этих блоков — не совсем.


E>IMHO всё ровно наоборот. Если есть оттестированные блоки, которые мы компонуем типа, то юнит-тест не много дадут, а вот если мы новые блоки пишем, то там юнит-тесты блоков зело полезны...


если проводить аналогию, то юнит-тесты позволят при компоновке электронных блоков отследить перегрузки на входах и выходах.
Re[34]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 20:54
Оценка:
Здравствуйте, _hum_, Вы писали:

__>>>да спокойно. возьму и отдельно повызываю его методы на прогонных значениях (ведь прогон же не считается юнит-тестом?)

L>>Таак, уже теплее. Вот это "возьму отдельно и повызываю методы" ты как делаешь? Вот новый проект, ничего запускаемого еще нет. Какие действия?
__>например, CA A; A.foo(0); A.foo(1); A.foo(0.5)// для крайних значений 0, -1 и обычного 0.5

То есть пишете маленький лончер и запускаете его в отладчике? Поздравляю, вы изобрели юнит-тесты вручную! (Бурные продолжительные аплодисменты, переходящие в овацию.)
Серьезно, все, что вы делаете в отладчике, можно и нужно делать автоматически в коде теста. Потом, через полгода, когда будете править код, сами себе спасибо скажете, и не один раз, а когда новонанятый джун "улучшит" уже "отлаженный" код, скажете еще миллион раз.

__>>>>>не понял что нельзя написать assert(nullptr != data); ?

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

При TDD выделенное почему-то — редкость.

__>>>ок. спасибо.


L>>Это, на самом деле, отличие, которое и отличает каменный век от века полетов в космос


__>ммм... пока не понял, как именно осуществляется тестирование функциональности (задача вроде неподъемная из-за "комбинаторного взрыва"), и почему его нужно считать качественным шагом вперед. но спасибо за диалог — начало что-то проясняться


Функциональность в первую и вторую очередь определяется сценариями, которые реализуют юниты в отдельности. Хорошо изолированные юниты реально полностью провалидировать в отдельности конечным числом юнитов. Когда они уже склеены в систему, сделать это невозможно из-за комбинаторного взрыва, а вот по отдельности — пожалуйста.
Re[41]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 20:55
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>IMHO всё ровно наоборот. Если есть оттестированные блоки, которые мы компонуем типа, то юнит-тест не много дадут, а вот если мы новые блоки пишем, то там юнит-тесты блоков зело полезны...


Это, давай лучше про ракеты
Re[42]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 21:01
Оценка:
Здравствуйте, _hum_, Вы писали:

__>во-первых, что такое "границы" ? граничные точки области определения функции? и почему именно в них нужно, а в других точках — не нужно?


Экстремумы, точки перегиба, границы применимости алгоритма. Или тупо все if или switch..case.

__>а во-вторых, таких граничных точек может быть тоже неподъемно много для обычных вычислений


Не может, иначе реализация такого алгоритма займет бесконечное время.

__>если проводить аналогию, то юнит-тесты позволят при компоновке электронных блоков отследить перегрузки на входах и выходах.


Нет, юнит-тесты — это когда каждый транзистор проверяется на конвеере на фабрике еще до того, как ты поставишь его в схему
Re[41]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 21:19
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


L>>>При правильном подходе к организации кода и покрытию сценариев его использования прогаммист может протестировать все сценарии использования юнита. Абсолютно все.

__>>но это же неправда — даже для обычной foo(uint32_t x, uint32_t y) практически невозможно проверить абсолютно все комбинации аргументов/

L>Все комбинации и не надо. Нужно покрыть все сценарии, а их << комбинаций аргументов. Обычно сценариев три — валидные данные, на которых стабильный алгоритм обязан выдавать предсказуемые данные, и сам алгоритм доказуем по индукции, невалидные данные, на которых должен случаться предсказуемый облом и граничные данные, что есть проверка работы алгоритма на границах применимости, экстремумах и т.п.


вот этого я и не понимаю. если вы проверили sqrt(uint32_t x) для валидного данного x = 2, то это не значит, что для x = 101 все будет работать, ведь у вас может, например, из-за округлений, или ошибки в программе, которая не проявляет себя на четных числах, перестать работать. скорее уж нужно использовать случайное тестирование (случайным образом выбирается точка в пространтсве аргументов и производится тест для нее)

L>>>Обычно. Как правило. Чем опытнее TDD-программист, тем сильнее его "обычно" стремится к "всегда". Иногда это не так, иногда это и правда дорого (привет, Erop), иногда просто лень, иногда тупо непонятно, что нужно делать в случае определенных входных данных, которых никогда быть не должно.


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


L>Не требуют они затрат. Пишутся на автомате.


можете накидать на автомате для sqrt(uint32_t x) с итерационным алгоритмом?
Re[37]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 21:20
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


L>>>Многопоточные, наверное? Они, родимые.

__>>не, их в рассмотрение не включаем это отдельная головная боль

L>А вот надо включать, чтобы головную боль как можно раньше отгильотинить


L>>>Да даже и в однопоточной факт наблюдения чертовщины в отладчике вовсе не гарантирует, что она вызвана именно на этом месте в call stack.

__>>это почему же?

L>Ну тут уже упоминали такую приятную вещь, как стрельбу по памяти, например.


а можно на пальцах, для тех, кто далек от "стрельбы по памяти"?
Re[35]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 21:26
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


__>>>>да спокойно. возьму и отдельно повызываю его методы на прогонных значениях (ведь прогон же не считается юнит-тестом?)

L>>>Таак, уже теплее. Вот это "возьму отдельно и повызываю методы" ты как делаешь? Вот новый проект, ничего запускаемого еще нет. Какие действия?
__>>например, CA A; A.foo(0); A.foo(1); A.foo(0.5)// для крайних значений 0, -1 и обычного 0.5

L>То есть пишете маленький лончер и запускаете его в отладчике? Поздравляю, вы изобрели юнит-тесты вручную! (Бурные продолжительные аплодисменты, переходящие в овацию.)

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

понятно. непонятно другое, почему такая достатчно неформальная вещь (выбор значений для тестирования — от балды) вызывает такую бурю восторга? или я еще чего-то не допонял?
Re[40]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 06.05.16 21:42
Оценка:
Здравствуйте, _hum_, Вы писали:

E>>Логи удобнее.


__>неважно. де-факто вы производите поиск ошибок путем последовательного отслеживания состояний процесса — в точности то, что делает дебагер.


Ну так "косяки" могут начать проявляться не с первой итерации...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[42]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 06.05.16 21:45
Оценка:
Здравствуйте, _hum_, Вы писали:

__>во-первых, что такое "границы" ?


Параметры, при которых меняется работа функции. Ветвления иначе происходят, переполнения и т. д...

__>а во-вторых, таких граничных точек может быть тоже неподъемно много для обычных вычислений

Ну тут от функции зависит.
Обычно у нормальных функций это не так...

__>если проводить аналогию, то юнит-тесты позволят при компоновке электронных блоков отследить перегрузки на входах и выходах.

Скорее гарантируют соответствие блоков номиналам
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[43]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 21:49
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


__>>во-первых, что такое "границы" ? граничные точки области определения функции? и почему именно в них нужно, а в других точках — не нужно?


L>Экстремумы, точки перегиба, границы применимости алгоритма. Или тупо все if или switch..case.


почему именно они? почему не другие точки? и что такое "экстремум", "точка перегиба" например, для алгоритма обращения списка?

__>>а во-вторых, таких граничных точек может быть тоже неподъемно много для обычных вычислений


L>Не может, иначе реализация такого алгоритма займет бесконечное время.


да легко может, если вы про обычные граничные точки в математическом понимании. например:
вычисления комплексного значения z по итерационной формуле z_n = z_{n-1} ^2 + c, где с = — 0.74543 + 0.11301i

точки, в которых алгоритм не расходится — так называемое множество жюлиа:



__>>если проводить аналогию, то юнит-тесты позволят при компоновке электронных блоков отследить перегрузки на входах и выходах.


L>Нет, юнит-тесты — это когда каждый транзистор проверяется на конвеере на фабрике еще до того, как ты поставишь его в схему


нет, как я понял, юнит тесты идут в связке с блоками, чтоб я мог при использовании их проверить, все ли в порядке.
Re[41]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 21:50
Оценка:
Здравствуйте, Erop, Вы писали:

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


E>>>Логи удобнее.


__>>неважно. де-факто вы производите поиск ошибок путем последовательного отслеживания состояний процесса — в точности то, что делает дебагер.


E>Ну так "косяки" могут начать проявляться не с первой итерации...


это уже другой вопрос — как локализовать область появления расхождения ожидаемого от реального
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.