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

__>это уже другой вопрос — как локализовать область появления расхождения ожидаемого от реального


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

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


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


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


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

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

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

это слишком громкое заявление

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

E>Скорее гарантируют соответствие блоков номиналам

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

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


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

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

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


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

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


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


__> можете накидать на автомате для sqrt(uint32_t x)


ASSERT_EQ_WITHIN_E(0, sqrt(0), e);
ASSERT_EQ_WITHIN_E(1, sqrt(1), e);
ASSERT_EQ_WITHIN_E(2, sqrt(4), e);

ASSERT_EQ_WITHIN_E(A, sqrt(MAX_UINT32), e);
Re[43]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 22:40
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


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


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


ну, так это же "пальцем в небо". и если достижение только в том, чтобы оформить такое тыкание пальцем в небо в виде отдельного программного компонента, то вроде ничего революционного

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


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


__>> можете накидать на автомате для sqrt(uint32_t x)


L>
L>ASSERT_EQ_WITHIN_E(0, sqrt(0), e);
L>ASSERT_EQ_WITHIN_E(1, sqrt(1), e);
L>ASSERT_EQ_WITHIN_E(2, sqrt(4), e);

L>ASSERT_EQ_WITHIN_E(A, sqrt(MAX_UINT32), e);
L>


понятно. а то, что при x = 0xfffffff1 могут начаться сказываться эффекты переполнения, это, конечно, должен дописать тот, кто в этом разбирается а если такого нет, ну и фиг с ним. будем рапортовать, что функция оттестирована, и что все работает ок
Re[44]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 06.05.16 22:45
Оценка:
Здравствуйте, _hum_, Вы писали:

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


Нет, не пальцем в небо. Программист пишет код. Он видит, какие могут быть сценарии выполнения. Пишет тесты для них. Я ж не зря неоднократно упоминал whie-box тестирование.

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


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


__>>> можете накидать на автомате для sqrt(uint32_t x)


L>>
L>>ASSERT_EQ_WITHIN_E(0, sqrt(0), e);
L>>ASSERT_EQ_WITHIN_E(1, sqrt(1), e);
L>>ASSERT_EQ_WITHIN_E(2, sqrt(4), e);

L>>ASSERT_EQ_WITHIN_E(A, sqrt(MAX_UINT32), e);
L>>


__>понятно. а то, что при x = 0xfffffff1 могут начаться сказываться эффекты переполнения, это, конечно, должен дописать тот, кто в этом разбирается


Если эффекты есть, то выделенный тест их должен показать.

__>а если такого нет, ну и фиг с ним. будем рапортовать, что функция оттестирована, и что все работает ок


Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.
Re[45]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 22:54
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


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


L>Нет, не пальцем в небо. Программист пишет код. Он видит, какие могут быть сценарии выполнения. Пишет тесты для них. Я ж не зря неоднократно упоминал whie-box тестирование.


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

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


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


__>>>> можете накидать на автомате для sqrt(uint32_t x)


L>>>
L>>>ASSERT_EQ_WITHIN_E(0, sqrt(0), e);
L>>>ASSERT_EQ_WITHIN_E(1, sqrt(1), e);
L>>>ASSERT_EQ_WITHIN_E(2, sqrt(4), e);

L>>>ASSERT_EQ_WITHIN_E(A, sqrt(MAX_UINT32), e);
L>>>


__>>понятно. а то, что при x = 0xfffffff1 могут начаться сказываться эффекты переполнения, это, конечно, должен дописать тот, кто в этом разбирается


L>Если эффекты есть, то выделенный тест их должен показать.


не заметил. сори. хотя все равно не гарантия (на самом граничном может не быть, а на приграничных появиться)

__>>а если такого нет, ну и фиг с ним. будем рапортовать, что функция оттестирована, и что все работает ок


L>Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.


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

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

L>>Нет, не пальцем в небо. Программист пишет код. Он видит, какие могут быть сценарии выполнения. Пишет тесты для них. Я ж не зря неоднократно упоминал whie-box тестирование.
__>понятно. но тогда, получается, тест может написать только автор кода. и если кто-то другой решит код переписать, то все тесты пойдут на смарку.

Э, нет. Что значит "переписать"? Имеющиеся тесты покажут, если вносимые изменения ломают поведение кода. Как раз при рефакторинге полезность тестов зачастую неоценима.

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


Отсутствие ошибок не гарантируют. Но гарантируют то, что в определенных условиях код выполняет именно то, что от него просят.

L>>Если эффекты есть, то выделенный тест их должен показать.

__>не заметил. сори. хотя все равно не гарантия (на самом граничном может не быть, а на приграничных появиться)

Добавь еще один в приграничную зону. Это бесплатно.

__>>>а если такого нет, ну и фиг с ним. будем рапортовать, что функция оттестирована, и что все работает ок

L>>Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.
__>меня смущает, что все как-то нестрого, на усмотрение разработчика нет системы...

И не надо, по большому счету. Тесты — для удобства разработчика в первую очередь, а не для отчетности.
Re[47]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 06.05.16 23:12
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


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

L>>>Нет, не пальцем в небо. Программист пишет код. Он видит, какие могут быть сценарии выполнения. Пишет тесты для них. Я ж не зря неоднократно упоминал whie-box тестирование.
__>>понятно. но тогда, получается, тест может написать только автор кода. и если кто-то другой решит код переписать, то все тесты пойдут на смарку.

L>Э, нет. Что значит "переписать"? Имеющиеся тесты покажут, если вносимые изменения ломают поведение кода. Как раз при рефакторинге полезность тестов зачастую неоценима.


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

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


L>Отсутствие ошибок не гарантируют. Но гарантируют то, что в определенных условиях код выполняет именно то, что от него просят.


да, гарантируют, что
sqrt(0) = 0
sqrt(1) = 1
sqrt(4) = 2
sqrt(MAX_UINT32) = A;

и все...


L>>>Если эффекты есть, то выделенный тест их должен показать.

__>>не заметил. сори. хотя все равно не гарантия (на самом граничном может не быть, а на приграничных появиться)

L>Добавь еще один в приграничную зону. Это бесплатно.


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

__>>>>а если такого нет, ну и фиг с ним. будем рапортовать, что функция оттестирована, и что все работает ок

L>>>Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.
__>>меня смущает, что все как-то нестрого, на усмотрение разработчика нет системы...

L>И не надо, по большому счету. Тесты — для удобства разработчика в первую очередь, а не для отчетности.


надо для введения метрик надежности тестов. иначе все достоинство сводится к возможности переиспользорвания теста (в отличие от моего самописного прогона, который один раз сделал и забыл, тесты можно оформить отдельно и потом переиспользовать для повторных прогонов)
Re[46]: Долгая компиляция на с++ - смерть для больших проект
От: PM  
Дата: 07.05.16 13:59
Оценка: +1
Здравствуйте, _hum_, Вы писали:

L>>Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.


__>меня смущает, что все как-то нестрого, на усмотрение разработчика нет системы...


Хм, похоже вы ищете серебряную пулю. После того как начнете пользоваться юнит-тестами, почитайте про property-based testing: https://www.google.ru/search?q=quickcheck+c%2B%2B

Например, https://github.com/thejohnfreeman/autocheck/wiki/Tutorial
Re[48]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 07.05.16 16:02
Оценка:
Здравствуйте, _hum_, Вы писали:

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


Почему? Как раз нет, замена алгоритма не должна менять наблюдаемое поведение. Поэтому юнит-тесты незаменимы при рефакторинге.

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

L>>Отсутствие ошибок не гарантируют. Но гарантируют то, что в определенных условиях код выполняет именно то, что от него просят.

__>да, гарантируют, что

__>sqrt(0) = 0
__>sqrt(1) = 1
__>sqrt(4) = 2
__>sqrt(MAX_UINT32) = A;

__>и все...


А что еще? Больше ничего не нужно. Реализация алгоритма должна обеспечивать, что если F(X_n) соответствует ожиданиям, то и F(X_n+1) им соответствует тоже. Индукция.

L>>Добавь еще один в приграничную зону. Это бесплатно.

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

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

L>>И не надо, по большому счету. Тесты — для удобства разработчика в первую очередь, а не для отчетности.


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


Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.
Не нужны никакие метрики. Даже кое-как написанные тесты в 100500 раз лучше отсутствия тестов. Единственный разумный критерий для тестов — их поддержка не должна ничего стоить. А это обеспечивается соблюдением критериев тестируемости самого тестируемого года.
Re[49]: Долгая компиляция на с++ - смерть для больших проект
От: Erop Россия  
Дата: 07.05.16 22:43
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.

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

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


L>>>Рапортовать не надо. У вас есть набор юнит-тестов, которые в некотором смысле являются документацией к функции.


__>>меня смущает, что все как-то нестрого, на усмотрение разработчика нет системы...


PM>Хм, похоже вы ищете серебряную пулю.


похоже, вы рассуждаете крайностями. если кто-то хочет системы, это не значит, что он требует идеала

После того как начнете пользоваться юнит-тестами, почитайте про property-based testing: https://www.google.ru/search?q=quickcheck+c%2B%2B

PM>Например, https://github.com/thejohnfreeman/autocheck/wiki/Tutorial


спасибо, это уже ближе к моему представлению
Re[49]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 08.05.16 11:18
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


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


L>Почему? Как раз нет, замена алгоритма не должна менять наблюдаемое поведение. Поэтому юнит-тесты незаменимы при рефакторинге.


да, наверное так. согласен.

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

L>>>Отсутствие ошибок не гарантируют. Но гарантируют то, что в определенных условиях код выполняет именно то, что от него просят.

__>>да, гарантируют, что

__>>sqrt(0) = 0
__>>sqrt(1) = 1
__>>sqrt(4) = 2
__>>sqrt(MAX_UINT32) = A;

__>>и все...


L>А что еще? Больше ничего не нужно. Реализация алгоритма должна обеспечивать, что если F(X_n) соответствует ожиданиям, то и F(X_n+1) им соответствует тоже. Индукция.


про индукцию вы не говорили. это все меняет — появляется какой-то систематизированный подход к тестированию, наподобие — введите на области определения тестируемой функции частичный порядок, такой, что для каждой подцепи и некоторого свойства P(x) выполняется: если P(x) == true, то и P(next(x)) == true; если P(x) == false, то и P(next(x)) == false; тогда свойство P может выступать в качестве основы для построения теста по правилу P(x_0), где P(x_0) — минимальный элемент подцепи (база индукции).
так? а где про это написано и можно посмотнреть конкретные примерны такого подхода?


L>>>Добавь еще один в приграничную зону. Это бесплатно.

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

L>Что значит додуматься? Кто код-то пишет? Программист обязан понимать, какие могут быть граничные случаи применимости его конкретной реализации. Если это не так, то весь этот разговор смысла не имеет.


нет, я же уже приводил цитату:

Unit tests created in a test-driven development environment are typically created by the developer who is writing the code being tested. Therefore, the tests may share blind spots with the code: if, for example, a developer does not realize that certain input parameters must be checked, most likely neither the test nor the code will verify those parameters. Another example: if the developer misinterprets the requirements for the module he is developing, the code and the unit tests he writes will both be wrong in the same way


например, нужно ли тестировать sqrt(MAX_UINT32) ? или это считается само собой разумеющимся, что функция не должна давать валидные значения на граничных значениях?

кстати, а что делать, если тип аргумента меняется (функцию переписали с uint32_t на double)? пересматривать тесты?


L>>>И не надо, по большому счету. Тесты — для удобства разработчика в первую очередь, а не для отчетности.


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


L>Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.


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

L>Не нужны никакие метрики. Даже кое-как написанные тесты в 100500 раз лучше отсутствия тестов. Единственный разумный критерий для тестов — их поддержка не должна ничего стоить. А это обеспечивается соблюдением критериев тестируемости самого тестируемого года.


Unit_testing_limitations
в частности оттуда:

For example, every boolean decision statement requires at least two tests: one with an outcome of "true" and one with an outcome of "false". As a result, for every line of code written, programmers often need 3 to 5 lines of test code.[6] This obviously takes time and its investment may not be worth the effort.
[...]
In addition, code for a unit test is likely to be at least as buggy as the code it is testing. Fred Brooks in The Mythical Man-Month quotes: "Never go to sea with two chronometers; take one or three."[7] Meaning, if two chronometers contradict, how do you know which one is correct?

Re[50]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 08.05.16 13:47
Оценка: :)
Здравствуйте, Erop, Вы писали:

L>>Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.

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

С этого все и началось. ТС жалуется, что каждое мелкое изменение означает полчаса сборки и прогон вручную под отладчиком.
С UT каждое мелкое изменение есть собственно изменение, написание теста для оного, сборка и прогон юнит-тест проекта. Что при правильной организации проекта выливается не более чем в сборку одной измененной либы и юнит-тест проекта. Меньше минуты.
Re[51]: Долгая компиляция на с++ - смерть для больших проект
От: _hum_ Беларусь  
Дата: 08.05.16 14:00
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


L>>>Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.

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

L>С этого все и началось. ТС жалуется, что каждое мелкое изменение означает полчаса сборки и прогон вручную под отладчиком.


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

просто тут немного еще и другая тема была затронута — как сами ошибки обнаруживать. и вот тут ассерты и юнит-тесты как их усовершенствование, выглядят довольно привлекательно.
Re[50]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 08.05.16 14:15
Оценка:
Здравствуйте, _hum_, Вы писали:

L>>А что еще? Больше ничего не нужно. Реализация алгоритма должна обеспечивать, что если F(X_n) соответствует ожиданиям, то и F(X_n+1) им соответствует тоже. Индукция.


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


Юнит-тесты — это не тестирование. Это подход к разработке. У них есть еще пара полезных побочных эффектов, о которых мы пока не говорили.

__>наподобие — введите на области определения тестируемой функции частичный порядок, такой, что для каждой подцепи и некоторого свойства P(x) выполняется: если P(x) == true, то и P(next(x)) == true; если P(x) == false, то и P(next(x)) == false; тогда свойство P может выступать в качестве основы для построения теста по правилу P(x_0), где P(x_0) — минимальный элемент подцепи (база индукции).

__>так? а где про это написано и можно посмотнреть конкретные примерны такого подхода?

Эээ... вот самый обычный пример
some_type sometihg_to_test(some_other_type data)
{
    if (check1(data))
    {
        // do some calculations
        return result;
    }
    else if (check2(data))
    {
        // do some other calculations
        return result;
    }
    else return do_nothing(data);
}


Вам нужно проверить поведение функции при условии попадания data в check1, check2 и когда ни в одно условие данные не попадают. При этом крайне желательно, чтобы код внутри ветвлений реализовывал некий монтонный алгоритм, без экстремумов, перегибов и прочих ветвлений. В таком случае индуктивное доказательство каждого ветвления тривиально.
Это, кстати, объясняет, почему юниты должны быть как можно более мелкими — дополнительные ветвление внутри каждого ветвления означает комбинаторный взрыв

__>нет, я же уже приводил цитату:

__>

__>Unit tests created in a test-driven development environment are typically created by the developer who is writing the code being tested. Therefore, the tests may share blind spots with the code: if, for example, a developer does not realize that certain input parameters must be checked, most likely neither the test nor the code will verify those parameters. Another example: if the developer misinterprets the requirements for the module he is developing, the code and the unit tests he writes will both be wrong in the same way


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

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


Зависит от задачи. Может, клиенты юнита гарантируют, что MAX_UINT32 там никогда не будет подан на вход?
А вообще — все граничные условия должны тестироваться.

__>кстати, а что делать, если тип аргумента меняется (функцию переписали с uint32_t на double)? пересматривать тесты?


Да. И поэтому внезапно оаказывается, что лучше оставить тип аргумента в покое, а использовать перегрузку.

L>>Что значит "можно"? Нужно. Так и делают. И прогоняют всегда, при каждой сборке.


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


Серебряной пули нет. Метрики для тестов реализации логики зависят от собствено реализации.

L>>Не нужны никакие метрики. Даже кое-как написанные тесты в 100500 раз лучше отсутствия тестов. Единственный разумный критерий для тестов — их поддержка не должна ничего стоить. А это обеспечивается соблюдением критериев тестируемости самого тестируемого года.


__>Unit_testing_limitations

__>в частности оттуда:
__>

__>For example, every boolean decision statement requires at least two tests: one with an outcome of "true" and one with an outcome of "false". As a result, for every line of code written, programmers often need 3 to 5 lines of test code.[6] This obviously takes time and its investment may not be worth the effort.


При юнит-тестировании для каждого ветвления нужно всего 3-5 тестов. Всего.
Для того, чтобы покрыть все возможные ветвления функциональным тестом для системы, состоящей из N юнитов, в общем случае тестов понадобится N^3-N^5
Re[51]: Долгая компиляция на с++ - смерть для больших проект
От: jazzer Россия Skype: enerjazzer
Дата: 08.05.16 18:09
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Юнит-тесты — это не тестирование. Это подход к разработке. У них есть еще пара полезных побочных эффектов, о которых мы пока не говорили.


Юнит-тесты — это все-таки тестирование. А подход к разработке — это TDD. Но это терминологический вопрос.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[29]: Долгая компиляция на с++ - смерть для больших проект
От: B0FEE664  
Дата: 09.05.16 09:13
Оценка:
Здравствуйте, landerhigh, Вы писали:

BFE>>>>Ну как "прекрасно". Может оказаться, что для этого надо затратить труд превосходящий по времени написание приложения.

L>>>Вот у нас, почему-то, не оказалось. Мы, наверное, что-то делаем неправильно.
BFE>>Наверное у вас датчики только одного (стандартизованного) типа.

L>Как ты думаешь, сколько типов датчиков поддерживает одна наиболее используемых в мире SCADA систем в мире?

Думаю, что сколько бы не поддерживали у них у вех унифицированный протокол обмена. А что?
И каждый день — без права на ошибку...
Re[30]: Долгая компиляция на с++ - смерть для больших проект
От: landerhigh Пират  
Дата: 09.05.16 09:33
Оценка:
Здравствуйте, B0FEE664, Вы писали:

L>>Как ты думаешь, сколько типов датчиков поддерживает одна наиболее используемых в мире SCADA систем в мире?

BFE>Думаю, что сколько бы не поддерживали у них у вех унифицированный протокол обмена. А что?

В общем, да. Только этих протоколов одних несколько сотен, если говорить о сколько-нибудь унифицированных хотя бы их производителем. Не говоря уже о вариантах каждого из них.
Даже industry standard протоколы существуют в нескольких вариантах, и при этом каждый производитель умудряется по-своему понять определенные пункты стандарта
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.