LINUX.ORG.RU

Почему тесты не пишут вместе с кодом?

 ,


0

2

Всюду рекомендуют делать для тестирования отдельные классы в отдельных файлах, а то и в отдельных проектах.

В результате при изменении задачи работаешь в двух файлах почти одновременно. Не проще воткнуть методы тестирования рядом с кодом?

★★★★★

Последнее исправление: monk (всего исправлений: 2)

На расте так пишут модульные тесты. Где-то глубоко в коде можно писать тесты и проверять значения приватных полей.

vlad9486
()

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

anonymous
()

работаешь в двух файлах почти одновременно

И что в этом такого? Большинство изменений кода кроме самых тривиальных случаев затрагивают несколько файлов сразу.

Не проще воткнуть методы тестирования рядом с кодом?

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

slovazap ★★★★★
()

В результате при изменении задачи работаешь в двух файлах почти одновременно.

Почему одновременно? Ты либо сначала пишешь тесты и под тесты пишешь код, либо пишешь код и покрываешь его тестами. Зачем писать их одновременно?)

TDrive ★★★★★
()
Ответ на: комментарий от TDrive

Зачем писать их одновременно?)

Подгонять обход косяков и там и там =)

LINUX-ORG-RU ★★★★★
()

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

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

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

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

Короче говоря, от такого отделения — сплошные плюсы.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

ну тебя понесло.

Человек дело говорит. И да - ifdef’ами в целях тестирования обмазываться не стОит никогда: интересно прогонять именно prod/release сборки через тесты - там много чего интересного иногда вылезает.

bugfixer ★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от anonymous

позволяет, например, не запускать CI по каждому коммиту в тесты

Тогда будет выложен код, не проходящий тесты. Это разве правильно?

monk ★★★★★
() автор топика
Ответ на: комментарий от bugfixer

ifdef’ами в целях тестирования обмазываться не стОит никогда: интересно прогонять именно prod/release сборки через тесты

Так ifdef именно на код тестов. То есть make test скомпилирует и запустит тесты, а make release даст бинарник без тестов.

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

Вот, наверное, единственный реальный аргумент.

Пример кода с тестами вот: https://github.com/sol/doctest

-- | Compute Fibonacci numbers
--
-- Examples:
--
-- >>> fib 10
-- 55
--
-- >>> fib 5
-- 5
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
monk ★★★★★
() автор топика
Ответ на: комментарий от slovazap

Не проще. Код засирается не относящейся к нему информацией, что гарантировано мешает его восприятию.

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

monk ★★★★★
() автор топика
Ответ на: комментарий от vlad9486

Это где на расте? Смотрю https://github.com/dtolnay/syn/blob/master/src/expr.rs . Тесты к нему в https://github.com/dtolnay/syn/blob/master/tests/test_expr.rs .

Причём часть конструкций описаны в комментариях, но пропущены в тестах. Если бы тесты были рядом с комментариями, то, скорее всего, не были бы пропущены.

monk ★★★★★
() автор топика

Идея совмещения кода и тестов в одном месте так себе.

Ещё бы попробовал жену с любовницей объединить в постели)

anonymous
()
Ответ на: комментарий от izzholtik

Попробуй сделать что-нибудь на верилоге. Так поймёшь.

Ха. Вот как раз в верилоге это можно делать. Я пишу формальные «тесты» для symbiyosys непосредственно в коде модуля.

Puzan ★★★★★
()
Ответ на: комментарий от fsb4000

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

С другой стороны это отчасти объясняет почему в некомпилируемых языках тесты рядом с кодом могут стать проблемой.

anonymous-angler ★☆
()

Самому интересно. Лично я считаю, что тесты должны быть рядом с кодом. Вроде в Rust так.

Legioner ★★★★★
()
Ответ на: комментарий от Miguel

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

Какие-то с++проблемы. В жаве библиотеки для компиляции и библиотеки для запуска это две разные вещи. Ничего не мешает скомпилировать программу с тестовыми библиотеками и запускать без них. Пока управление не придёт в код для тестирования, проблем не будет.

Legioner ★★★★★
()
Ответ на: комментарий от anonymous-angler

С другой стороны это отчасти объясняет почему в некомпилируемых языках тесты рядом с кодом могут стать проблемой.

Так в некомпилируемых if testing … fi также надёжно закрывает блок от выполнения. Время на обработку сравнимо с временем обработки комментария.

monk ★★★★★
() автор топика
Ответ на: комментарий от anonymous-angler

В исходниках, как например здесь - unit тесты.

Здесь они тоже в отдельном модуле.

monk ★★★★★
() автор топика
Ответ на: комментарий от Legioner

Так я видел в Haskell (doctest) и в Racket (rackunit). А вот во всех статьях/книжках только отдельные модули с тестами.

monk ★★★★★
() автор топика

Представь, как затянется разработка!

Да, а ведь придется тогда ещё и тесты тестов писать!

anonymous
()
Ответ на: комментарий от bugfixer

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

abcq ★★
()
Ответ на: комментарий от lovesan

А мне нравится. Единственное, что мне в его синтаксисе не нравится это использование одинарной кавычки для шаблонов. Я привык, что кавычки используются для строк. Но, думаю, вопрос привычки.

Legioner ★★★★★
()
Ответ на: комментарий от slovazap

Нет, не являются.

Являются:

https://hackage.haskell.org/package/vector-0.12.3.1/docs/src/Data.Vector.html#iterateN

-- > unfoldr (\n -> if n == 0 then Nothing else Just (n,n-1)) 10
-- >  = <10,9,8,7,6,5,4,3,2,1>

-- > unfoldrN 3 (\n -> Just (n,n-1)) 10 = <10,9,8>

-- > unfoldrExactN 3 (\n -> (n,n-1)) 10 = <10,9,8>

и являются тестами и попадают в документацию в качестве примеров.

monk ★★★★★
() автор топика

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

nanosecond
()

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

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Но препроцессор может вырезать дебаг код перед сборкой.
И нормальный текстовый редактор может их просто скрыть по хоткею.

nanosecond
()
Ответ на: комментарий от peregrine

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

abcq ★★
()
Ответ на: комментарий от nanosecond

И нормальный текстовый редактор может их просто скрыть по хоткею.

Вот только это усложняет всё и заставляет зависеть от «нормальных текстовых редакторов». А ещё эти «нормальные текстовые редакторы» начинают дико лагать и падать когда файл переваливает за пару сотен мегабайт. И поиск по таким файлам через жопу работает.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

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

nanosecond
()
Ответ на: комментарий от peregrine

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

abcq ★★
()
Ответ на: комментарий от monk

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

slovazap ★★★★★
()
Ответ на: комментарий от abcq

ничего страшного в этом особо нет

В этом случае тестовый код либо влинковывается в релизные сборки, либо за’ifdef’лен, что в свою очередь делает невозможным их (релизных сборок) полноценное тестирование. Мы тесты кладем рядом, но в отдельных файлах проименованных определённым образом дабы автоматически исключить их из билда собственно библиотечек. При этом тесты библиотечек собираются отдельно (очевидно с зависимостями на сами библиотечки и тестовый framework) и исполняются как часть nightly build с отчётами и всеми делами. Как это сделать лучше - я не знаю.

У D вон даже конструкция и ключ сборки специальный есть

Когда у Вас десятки миллионов строк кода и полный билд занимает несколько часов пересобирать всё дважды становится непростительной роскошью. Да и тестировать Вы будете совсем не то что релизить.

bugfixer ★★★★
()
Ответ на: комментарий от bugfixer

В этом случае тестовый код либо влинковывается в релизные сборки

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

Когда у Вас десятки миллионов строк кода и полный билд занимает несколько часов пересобирать всё дважды становится непростительной роскошью. Да и тестировать Вы будете совсем не то что релизить.

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

abcq ★★
()
Ответ на: комментарий от Legioner

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

anonymous
()

Потому что открывая файл с названием «ПровайдерАутентификации», я хочу видеть провайдер аутентификации, а не тесты.

fernandos ★★★
()
Ответ на: комментарий от fernandos

Я снова купился на эту уловку, они снова подсунули мне тесты! :] раз уж это был мессадж оффтопа, поинтересуюсь, а модерация может скажем отредактировать сообщение вместо того чтобы его удалять, как сообщение анонима которое удалили только что? @hobbit просто оно вроде как смысл имеет даже к контексте беседы, но сквернословие и немного греты

abcq ★★
()
Последнее исправление: abcq (всего исправлений: 1)
Ответ на: комментарий от peregrine

Потому что они засирают файлы с кодом.

Тогда комментарии тоже надо в отдельные файлы писать, чтобы они не «засирали файлы с кодом».

monk ★★★★★
() автор топика
Ответ на: комментарий от monk

Тогда комментарии тоже надо в отдельные файлы писать, чтобы они не «засирали файлы с кодом».

комментариев мало, а тесты занимают много мегабайт…

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)

В результате при изменении задачи работаешь в двух файлах почти одновременно

Так-то тесты пишет отдельный человек.

Не проще воткнуть методы тестирования рядом с кодом

Проще их вообще никуда не втыкать. Бюрократия с тестами нужна только если контора достаточно крупная, чтобы любой факап выливался в миллиарды нефти. Мелкой конторе эффективнее выкатить сырой продукт и порешать проблемы напрямую с клиентами.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от fsb4000

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

abcq ★★
()
Ответ на: комментарий от abcq

А что поделать, если одной директории, тесты теперь аккуратно размазаны тонким, а местами и не очень, слоем по коду.

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

Это раз.

Из-за бага-фичи-уникальной_особенности движка: @hobbit.

а модерация может скажем отредактировать сообщение вместо того чтобы его удалять

Кажется, нет, сообщения не может, может темы.

fernandos ★★★
()
Ответ на: комментарий от slovazap

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

Я всё-таки про юнит-тесты. И про ситуацию, когда один и тот же код в двух-трёх местах (в виде теста, в виде комментария перед функцией, в виде документации). И когда при изменении поведения функции приходится все эти три места синхронизировать.

Или использовать методы, заставляющие читать не комментарии и документацию, а код. Например, как было раньше: «В 1971 году мне представился случай обсудить вопросы мнемоники и содержательности меток с программистом, разрабатывающим важные имитационные программы для Центра пилотируемых космических кораблей НАСА. По его мнению, переменным, подпрограммам и другим меткам не следует давать «значащие» имена, поскольку впоследствии они могут быть ошибочно поняты или истолкованы программистами, обеспечивающими сопровождение. По этой причине он намеренно выбирал такие имена, как QPK17, GLOP42 и ZYX123, ни одно из которых не имело никакой связи с именуемыми переменными и подпрограммами. Он считал, что в этом случае программист будет вынужден тщательно изучить программу, чтобы узнать истинный смыл этих меток»

monk ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.