?

Log in

Насколько я помню себя 10 лет назад, у меня было такое отношение,… - Оживший юзерпик

Nov. 27th, 2014

10:21 am

Previous Entry Share Next Entry

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

Ну, вдруг кто-то не читает Авву.

Comments:

[User Picture]
From:besm6
Date:November 27th, 2014 07:37 am (UTC)
(Link)
Вот я некоторое время назад подсел на Хаскель. Ключевое свойство - язык со строгой типизацией времени компиляции, но с выразительной системой типов. Вот там - вполне нормально. Почти все нетривиальные куски кода формулируются с помощью типов, и покрывать тестами остается пару-тройку мест, где реально посадить арифметическую ошибку или перепутать "меньше" с "больше".

У меня есть большой проект, где вообще нет ни одного теста. За три года успешно проскочили, не замеченные компилятором, одна арифметическая ошибка, одна логическая вышеупомянутого типа, и одна действительно нетривиальная, которую вообще непонятно, как тестировать. Была поймана логическим рассуждением - мне типа не нравилось то место, я на него посмотрел попристальнее, и ... Хрень работает, нареканий нет.
(Reply) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 08:15 am (UTC)
(Link)
По аналогии переносить этот опыт на C, увы, сложно.
(Reply) (Parent) (Thread)
[User Picture]
From:besm6
Date:November 27th, 2014 08:44 am (UTC)
(Link)
На C, разумеется, нереально. Разве что посредством компиляции хаскеля в C (ghc так умеет, но с библиотеками, вероятно, будет немалый геморрой). Или посредством написания на хаскеле DSL и кодогенератора в C к нему, но это тоже немалый геморрой, я полагаю. Я поэтому стараюсь не писать на C. Пока получается :)
(Reply) (Parent) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 08:46 am (UTC)
(Link)
Это я к тому, что FreeBSD не написан на хаскеле, так что аргументировать отсутствие тестов им сложнее.
(Reply) (Parent) (Thread)
[User Picture]
From:besm6
Date:November 27th, 2014 10:05 am (UTC)
(Link)
Ну почему, они могут сказать, что вот уже собираются переписать на хаскеле...

Как бы уже почти реально.

Вот аргументировать агдой будет сложнее. Хотя если бы удалось, там тесты вообще были бы не нужны, пруфчекер в комплекте. Но увы, говорят, что для взаимодействия с RealWorld агде пока приходится говорить "мамой клянус!".

Edited at 2014-11-27 10:07 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 10:08 am (UTC)
(Link)
Тебе попадались хоть какие-нибудь ядра ОС на хаскеле? House, по-моему, умер в 2009. Линуксовый эксперимент https://www.haskell.org/haskellwiki/Kernel_Modules тоже не обновлялся с 2009. Что еще есть?
(Reply) (Parent) (Thread)
[User Picture]
From:besm6
Date:November 27th, 2014 10:19 am (UTC)
(Link)
Мне притащили ссылку на Haskell Machine: https://github.com/GaloisInc/HaLVM

Это, конечно, не ядро ОС, но движение в нужном направлении.
(Reply) (Parent) (Thread)
[User Picture]
From:_slw
Date:November 27th, 2014 10:10 am (UTC)
(Link)
а зачем им аргументировать отсутсвием тестов?
(Reply) (Parent) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 10:13 am (UTC)
(Link)
Отсутствием -- незачем. Доказывать, что тесты не нужны, потому что написано на языке икс или игрек, не получится.
(Reply) (Parent) (Thread)
[User Picture]
From:_slw
Date:November 27th, 2014 10:26 am (UTC)
(Link)
а зачем им это доказывать?
(Reply) (Parent) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 10:29 am (UTC)
(Link)
Это у Аввы надо спрашивать, зачем ему покрытие тестами везде.
(Reply) (Parent) (Thread)
[User Picture]
From:_slw
Date:November 27th, 2014 10:34 am (UTC)
(Link)
снобизм.
да. именно снобизм.
причем программиста из компании с немерянным бюджетом и неадекватным ЧСВ.
и нет, я не про то, что тесты не нужны.
но написание тестов -- тоже требует ресурсов.
и если ты не гугл, то у тебя выбор -- или сделать новую фичу (даже, наеврное 3-4 новых фичи) или сделать тесты на старую фичу. в любом случае ты проиграл.

ну это не говоря уж о том, что тесты -- нихуя не серебрянная пуля и тестируют только то, о чём подумали что надо тестировать. а что не подумали -- и не тестируется. а в каком-нибудь TCP такой комбинаторный взрыв вариантов, требующих тестирования...
(Reply) (Parent) (Thread)
[User Picture]
From:abbra
Date:November 27th, 2014 10:48 am (UTC)
(Link)
Именно. С другой стороны, если писать что-то новое, то все же практика обкладывания тестами и документацией скорее доброе дело, чем снобизм.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:rmrfchik
Date:November 27th, 2014 10:39 am (UTC)
(Link)
Типы не ловят логические ошибки. Хаскельными типами не выразишь, что sort возвращает отсортированный по возрастанию список.
(Reply) (Parent) (Thread)
[User Picture]
From:_slw
Date:November 27th, 2014 11:52 am (UTC)
(Link)
а уж ошибки в тз или ошибки прочтения тз...
(Reply) (Parent) (Thread)
[User Picture]
From:besm6
Date:November 27th, 2014 03:00 pm (UTC)
(Link)
А вот их, кстати, часто ловят. Когда начинаешь строить систему типов для прочитанной задачи и видишь, что получается какая-то корявая фигня, идешь уточнять, и находишь ошибку. Были случаи.

Потому что некрасивый самолет не полетит, и если система типов получается корявой, то можно быть почти уверенным, что вычитанная задача не соответствует стоящей в реальности. А уж в прочтении ТЗ ошибка или в его написании - несущественно.
(Reply) (Parent) (Thread)
[User Picture]
From:besm6
Date:November 27th, 2014 02:57 pm (UTC)
(Link)
Скорее всего, уже можно выразить, если копнуть в область зависимых типов, в той мере, в которой ghc их уже научился.

Но так вот сходу не поручусь, я туда только издалека заглядывал.
(Reply) (Parent) (Thread)
[User Picture]
From:rmrfchik
Date:November 28th, 2014 07:31 am (UTC)
(Link)
Не все знания о системе можно запихать в зависимые типы.
Тем более знания о взаимодействии с внешним миром.
Собственно, типы и прочий текст программмы следует рассматривать с точки зрения "что мы сделали", а тесты с точки зрения "что мы хотели".
Ощибки могут быть и там и там, и хотеть мы можем странного и сделать по кривому.
Но имея два взгляда на одну проблему легче поймать ошибки.
(Reply) (Parent) (Thread)
[User Picture]
From:thesz
Date:November 29th, 2014 07:28 pm (UTC)
(Link)
Вот какие сведения о системе нельзя запихнуть в зависимые типы? Особенно знания о взаимодействии с внешним миром.

Вот какие?
(Reply) (Parent) (Thread)
[User Picture]
From:rmrfchik
Date:November 29th, 2014 09:34 pm (UTC)
(Link)
thesz зачем-то скрыл комментарий, отвечаю в пустоту.
Возьмём, к примеру, Oracle, с которым общается наша программа. Посредством sql, который поверх net8, который поверх tcp, который поверх ip, далее ethernet, всякая физика и лирика в виде сетевых карточек.
В каком состоянии должна находиться вся эта конструкция, чтобы мы могли сделать select? И что мы можем получить в ответ? Какие возможные состояния у этой конструкции?
Должны ли мы предусмотреть просто реакцию на ORA-? Что происходит с коннектом после ошибки? А после таймаута? Не придётся ли нам воспроизвести в программе модель всей этой машинерии или мы будем упрощать?
А как мы будем упрощать? Можно свести всё безумное состояние к паре Ok,Fail. Ну, или, к 3-4-10 более понятным состояниям.
Насколько это упрощение верно отражает наш замысел?
А верно ли мы поняли всю внешнюю модель?
Всё это зависимыми типами не выразить, мы вынуждены сильно упрощать.А когда мы упрощаем, нам нужны тесты, чтобы убедиться, что упростили верно.
(Reply) (Parent) (Thread)
[User Picture]
From:thesz
Date:November 30th, 2014 03:35 am (UTC)
(Link)
Скрытие комментариев - свойство сего блога. Видимо, комментарии не от друзей скрываются.

Ответ прост - нам не надо воспроизводить и/или перечислять все возможные состояния внешней системы. Достаточно отклассифицировать их настолько, чтобы было удобно.

Да, здесь нужны тесты. Но 1) мы и работаем с системой, что не имеет зависимых типов и 2) тесты будут высокоуровневыми, функциональными.
(Reply) (Parent) (Thread)
[User Picture]
From:tobotras
Date:November 30th, 2014 08:51 am (UTC)
(Link)
Юнит-тесты — ВООБЩЕ про другое. Это не фунциональное тестирование. Это — тестирование контрактов юнитов. Оно нужно ВООБЩЕ для другого: не для проверки, что наша система работает так, как мы задумали. А для проверки, что каждый мелкий ЮНИТ работает так, как ОН задуман. Потому что цель юнит-тестирования — другая: обеспечение ВОЗМОЖНОСТИ рефакторинга. В большой (БОЛЬШОЙ) системе без тестов просто страшно подойти к тому, чтобы переписать какой-нибудь кусочек: никогда не поймёшь, не изменил ли ты что-то, что потом при странных граничных условиях выстрелит. Наличие юнит-тестов позволяет (в идеале) делать это вообще недрогнувшей рукой: если юнит-тесты после рефакторинга прошли без ошибки, значит, ты ничего не сломал в переписанном юните.
(Reply) (Parent) (Thread)
[User Picture]
From:thesz
Date:November 30th, 2014 10:06 am (UTC)
(Link)
1. Это важно при работе с юнитами с состоянием и (вот здесь очень важное) со слабой системой типов.

2. Рефакторинг не вносит нового функционала и не исправляет старые оошибки (он должен их сохранить - функционал не меняется). Это практически бесполезная деятельность.

3. Поскольку я имел счастье работать с системами без юнитов с состоянием и с хорошей системой типов, я уже не могу прорезонировать с вашим посылом.
(Reply) (Parent) (Thread)
[User Picture]
From:tobotras
Date:November 30th, 2014 10:16 am (UTC)
(Link)
Рефакторинг — бесполезная деятельность. Мама, хочу в советский союз!
(Reply) (Parent) (Thread)
[User Picture]
From:thesz
Date:December 1st, 2014 11:56 am (UTC)
(Link)
Из этого можно заключить, что вы согласны с моими пунктами. Я редко встречаю столь ярко выраженное одобрение, поэтому на некоторое время растерялся.

Большое спасибо за вашу поддержку.
(Reply) (Parent) (Thread) (Expand)