Нашел просто потрясающий философский рассказ о unit-тестировании. На русском не было — решил перевести .
Введение переводчика
В мае 2006 года, плохо подготовленная экспедиция в Гималаи сбилась с пути. После двух недель скитаний, страдая от голода, жажды и озонируя воздух, как может его озонировать группа затерявшихся на две недели неопытных путешественников, наши страдальцы оказались у входа в древнюю пещеру.
В пещере они увидели лабиринт боксов (cubicles, кабинок). В каждом боксе был деревянный стол, эргономически правильное бамбуковое кресло, календарь Дилберта и странное компьютеро-подобное механическое устройство. В одном углу офиса они нашли запасы темной жидкости (позже определенной как ранние примеры газированного напитка с высоким содержанием кофеина) и стол для пинг-понга. Путешественники поняли, что пещера была древним софтверным стартапом. Самым древним. Древнее даже чем Netscape...
Среди прочих замечательных вещей они нашли нечто потрясающее: записку, оставленную одним из программистов. Гид экспедиции, будучи не очень хорошим гидом, знал как читать древний язык и перевел записку:
Мы выкатили релиз раньше срока, как обычно. Все тесты проходят, так что в оставшуюся неделю мы решили отдохнуть. Собираемся в морское путешествие. Поскольку это занятие по тим-билдингу, мы надеемся что получим возмещение расходов.
Путешественники смотрели друг на друга в полном недоумении. Они не только открыли самый древний софтверный стартап в истории, но еще и команду разработчиков, которая оказывается релизилась впереди расписания на постоянной основе!
Каков был секрет древних программистов? И что с ними случилось? Путешественники обрыскали каждый бокс в поисках зацепок и нашли две заношенные брошюры. Одна из них называлась "Научись путешествовать по морю за 30 минут", что объясняло судьбу программистов. Вы держите в руках перевод второй брошюры "Путь Тестивуса". Кто написал ее? Что такое Тестивус? Одному Гуглу известно наверняка...
Объясняет ли содержимое этого текста успехи древних программистов? Нельзя сказать точно, но мы верим, что их потрясающая доблесть обязана комбинации философии Тестивуса и приему в больших количествах темной жидкости с кофеином, найденной в пещере.
Прочитайте брошюру и сделайте свои выводы.
Alberto Savoia, CTO/Cofounder of Agitar Software
Апрель 2007, Mountain View, Calif.
Если пишешь код — пиши тесты
Ученик спросил мастера-программиста: "Когда я могу перестать писать тесты?"
Мастер ответил: "Когда ты перестаешь писать код"
Ученик спросил: "Когда я перестаю писать код?"
Мастер ответил: "Когда ты становишься менеджером"
Ученик задрожал и спросил: "Когда я становлюсь менеджером?"
Мастер ответил: "Когда ты перестаешь писать тесты"
Ученик побежал писать тесты.
Остались только следы.
Если код заслуживает быть написанным, он заслуживает иметь тесты.
Не застряньте в догме юнит тестирования
Догма говорит:
"Делай это.
Делай только это.
Делай это только так.
И делай это потому, что я тебе говорю."
Догма не гибкая. Тестированию нужна гибкость.
Догма убивает творчество. Тестированию нужно творчество.
Примите карму юнит тестов
Карма говорит:
"Делай хорошие вещи, и хорошие вещи произойдут с тобой.
Делай их так, как ты знаешь.
Делай их так, как тебе нравится."
Карма гибка. Тестированию нужна гибкость
Карма процветает на творчестве. Тестированию нужно творчество.
Думай о коде и тестах как о едином
Когда пишешь код, думай о тесте.
Когда пишешь тест, думай о коде.
Когда ты думаешь о коде и тесте как о едином,
тестирование просто, а код красив.
Тест важнее, чем юнит
Ученик спросил великого мастера программирования Летящего Пера: "Что превращает тест в юнит тест?"
Великий мастер программирования ответил: "Если он обращается к базе, значит он не юнит тест.
Если он обращается к сети, значит он не юнит тест.
Если он обращается к файловой системе, значит он не юнит тест.
Если он не может выполняться одновременно с другими тестами, значит он не юнит тест.
Если ты должен делать что-то с окружением, чтобы выполнить тест, значит он не юнит тест."
Другой мастер программист присоединился и начал возражать.
"Извините, что я спросил", — сказал ученик.
Позже ночью он получил записку от величайшего мастера программиста. Записка гласила: "Ответ великого мастера Летящего Пера прекрасный ориентир.
Следуй ему, и в большинстве случаев не пожалеешь.
Но не стоит застревать на догме.
Пиши тест, который должен быть написан."
Ученик спал хорошо.
Мастера все еще продолжали спорить глубокой ночью.
Тестируй, пока свежо
Твой код — как глина.
Пока она свежая — она мягкая и податливая.
Со временем она становится твердой и хрупкой.
Если ты пишешь тесты, пока код свежий и легко изменяемый —
тестирование будет проще, а код вместе с тестами будет прочнее.
Тесты без запуска — пустая трата времени
Запускай тесты часто.
Не позволяй им застаиваться.
Радуйся, когда они проходят.
Радуйся, когда они не проходят.
Несовершенный тест сегодня лучше совершенного теста когда-нибудь
Лучшее — враг хорошего.
Не жди лучшего чтобы сделать лучше.
Не жди лучшего чтобы сделать хорошо.
Напиши тест, какой сможешь, сегодня.
Ужасный тест лучше чем никакой
Когда код ужасен — тесты могут быть ужасны.
Ты не любишь писать ужасные тесты,
Но ужасный код нуждается в тестах больше всего.
Не разрешай ужасному коду отговорить тебя писать тесты,
Но позволь ужасному коду отговорить тебя писать ужасный код в будущем
Иногда тест оправдывает средство
Ученик спросил двух мастеров программистов: "Я не могу написать этот код без создания моков и нарушения инкапсуляции.
Что мне делать?"
Один мастер программист ответил: "Моки — это плохо, и ты никогда не должен нарушать инкапсуляцию.
Перепиши код, чтобы можно было тестировать правильно."
Другой мастер ответил: "Моки — это хорошо, и тестирование важнее инкапсуляции."
Обескураженный ученик ушел за пивом. В местной пивной он встретил
Величайшего мастера программиста посасывающего пивко с куриными крылышками. "Величайший мастер!" — сказал ученик, — "Я думал, что вы не пьете.
И разве вы не вегетарианец?"
Величайший мастер улыбнулся и ответил: "Иногда жажда лучше утоляется пивом, а голод — куриными крылышками".
Ученик больше не был обескуражен.
Только дураки обходятся без инструментов
Фермер без плуга — плохой фермер.
Счетовод без абака — плохой счетовод.
Некоторые задачи лучше выполняются голыми руками.
А некоторые — инструментами.
Нет ничего благородного делать что-то руками,
что может быть лучше сделано с инструментом.
Не разумно использовать голову там, где она не нужна.
Хороший тест падает
Ученик подошел к мастеру программисту и сказал: "Все мои тесты всегда проходят. Не заслуживаю ли я повышения?"
Мастер отвесил леща ученику и ответил: "Если все твои тест всегда проходят, тебе стоит лучше писать тесты"
С красной шеей пошел ученик жаловаться в HR.
Но это уже другая история...
Путь Тестивуса
Если пишешь код — пиши тесты
Не застряньте в догме юнит тестирования
Примите карму юнит тестов
Думай о коде и тестах как о едином
Тест важнее, чем юнит
Тестируй, пока свежо
Тесты без запуска — пустая трата времени
Несовершенный тест сегодня лучше совершенного теста когда-нибудь
Ужасный тест лучше чем никакой
Иногда тест оправдывает средство
Только дураки обходятся без инструментов
Хороший тест падает
Кто-то начитался "Дао программирования под Unix", но там хоть не так банально всё было сформулировано.
Нарушается главный закон таких текстов: связывание внешне несвязуемого. Фокус всегда в том, чтобы внешне несвязуемое отражало глубокую, но действительную, а не мнимую связь вещей. Просто опускается длинная цепь промежуточных высказываний. А "путь Тестивуса" по преимуществу — пачка предписаний сдобренных парочкой неплохих наблюдений и завязанных общим посылом: "Это не понятно, но правильно".
A>Если пишешь код — пиши тесты
Ну вот, полный комплект наворотов. На месте ученика я бы тоже убежал от этого ненормального. Уж лучше тесты писать, чем такую пургу слушать.
A>Не застряньте в догме юнит тестирования
Предписание не застревать в самом предписании. Дзен, однако. Кроме того, догма плоха не тем, как она "говорит", а тем, что догма не отражает глубинной связи вещей. Её нельзя понять, её можно только запомнить.
A>Примите карму юнит тестов
Опять таки, нет ясности "почему". Автор берёт в качестве исходной посылки некое положение вещей и подвязывает к нему остальные рассуждения.
A>Думай о коде и тестах как о едином
Ну вот, тот самый случай, когда один более или менее правильный довод придаёт некую осмысленность всему тексту. Хотя опять таки, если почитать тех же китайцев, то они не жмут на такие штуки, как "думай о том и об этом". Китайцы не во всём понятны европейцам, но при этом их нельзя назвать идиотами. Так, в данном случае, нет никакой необходимости предписывать какой-то особый стиль "думанья". Тесты и тестируемый код являются двумя частями единого целого, только и всего. Как инь всегда соседствет с ян.
A>Тест важнее, чем юнит
Эти мастера погрязли во тьме невежества и самолюбований, и потому нуждаются в хорошем уроке бамбуковой дубиной. Нет бы сказать по-простому: юнит-тесту, мол, нужен только тестируемый код. Так нет же, расползаются мыслью по древу, от того и спорят всю ночь. Спали бы лучше, глядишь, голова была бы посвежее! Тоже мне, мудрецы...
A>Тестируй, пока свежо
А вот это вообще глупость, недостойная настоящего джедая. Потому что "свежая" программа сопровождается не менее свежими размышлениями, которые зачастую ошибочны, как и сама программа. Ошибочность доказывается временем, следовательно ценность таких тестов кратковременна и мимолётна как... А, неважно.
Говоря словами автора: если глина стала слишком хрупкой, то нужно задуматься о правильности самого изделия, или о правильности его использования, или о том и другом одновременно.
A>Тесты без запуска — пустая трата времени
См. замечания по "Тестируй, пока свежо".
A>Несовершенный тест сегодня лучше совершенного теста когда-нибудь
Это вообще песня. Сравни с: "совершенство чистого листа" и "слово изреченное есть ложь". Но, в общем, согласен. Не можешь работать головой, работай руками!
A>Ужасный тест лучше чем никакой
Прямое поощрение подхода: "Что тут думать? Прыгать надо!" Воистину, уж лучше бы выспались! Чтобы код не был ужасным, нужно перед тем, как его писать, обстоятельно поразмыслить: что надо, что не надо, что изменится и что останется постоянным. Отсюда вырастет то, что назовут "ортогональностью абстракций".
A>Иногда тест оправдывает средство
Про пиво и крылышки — хорошо. И я знаю, почему тот мастер был в кафе, а не за компьютером. Он знал, что иногда потребность в тестировании удовлетворяется вдумчивым чтением кода и сосредоточением во время разработки. А для этого ничто не должно беспокоить программиста: ни голод, ни жажда.
A>Только дураки обходятся без инструментов
Если обходятся — значит, инструменты лишние. Если инструменты необходимы, то без них никакой дурак не обойдётся.
A>Хороший тест падает
Ещё одно относительно хорошее наблюдение в этом тексте. Да, хорошо, если тест упал, поскольку таким образом мы увидели изъян в программе. Но как увидеть изъян в самом тесте?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
A>>Ужасный тест лучше чем никакой ГВ>Прямое поощрение подхода: "Что тут думать? Прыгать надо!" Воистину, уж лучше бы выспались! Чтобы код не был ужасным, нужно перед тем, как его писать, обстоятельно поразмыслить: что надо, что не надо, что изменится и что останется постоянным.
ну, это козе понятно, что лучше быть богатым и здоровым, чем бедным и больным
A>>Только дураки обходятся без инструментов ГВ>Если обходятся — значит, инструменты лишние.
или времени у них лишнего дофига, или качество лишнее
Здравствуйте, Odi$$ey, Вы писали:
A>>>Ужасный тест лучше чем никакой ГВ>>Прямое поощрение подхода: "Что тут думать? Прыгать надо!" Воистину, уж лучше бы выспались! Чтобы код не был ужасным, нужно перед тем, как его писать, обстоятельно поразмыслить: что надо, что не надо, что изменится и что останется постоянным.
OE>ну, это козе понятно, что лучше быть богатым и здоровым, чем бедным и больным
При чём здесь это?
A>>>Только дураки обходятся без инструментов ГВ>>Если обходятся — значит, инструменты лишние. OE>или времени у них лишнего дофига, или качество лишнее
Или ещё тысяча и одна причина.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
A>>>>Ужасный тест лучше чем никакой ГВ>>>Прямое поощрение подхода: "Что тут думать? Прыгать надо!" Воистину, уж лучше бы выспались! Чтобы код не был ужасным, нужно перед тем, как его писать, обстоятельно поразмыслить: что надо, что не надо, что изменится и что останется постоянным. OE>>ну, это козе понятно, что лучше быть богатым и здоровым, чем бедным и больным
ГВ>При чём здесь это?
при том что с тем что хорошый тест лучше плохого никто и не спорил, в оригинальном утверждении присутствуют "Ужасный" и "никакой".
Здравствуйте, Odi$$ey, Вы писали:
A>>>>>Ужасный тест лучше чем никакой ГВ>>>>Прямое поощрение подхода: "Что тут думать? Прыгать надо!" Воистину, уж лучше бы выспались! Чтобы код не был ужасным, нужно перед тем, как его писать, обстоятельно поразмыслить: что надо, что не надо, что изменится и что останется постоянным. OE>>>ну, это козе понятно, что лучше быть богатым и здоровым, чем бедным и больным
ГВ>>При чём здесь это?
OE>при том что с тем что хорошый тест лучше плохого никто и не спорил, в оригинальном утверждении присутствуют "Ужасный" и "никакой".
Хе-хе. В оригинальном тексте всё веселее.
Когда код ужасен — тесты могут быть ужасны.
Ты не любишь писать ужасные тесты,
Но ужасный код нуждается в тестах больше всего.
Не разрешай ужасному коду отговорить тебя писать тесты,
Но позволь ужасному коду отговорить тебя писать ужасный код в будущем
Я понимаю, что именно он пытается облечь в форму рассуждений мастера: плохо написанный код нужно тщательно тестировать. Но действительность-то на порядок сложнее. Если уж что-то определилось, как "плохо написанное", то лучше, пожалуй, не тратить время на тестирование этого ужаса, а просто переписать. Тут совокупность факторов: с одной стороны, раз это настолько плохо написано, то следовательно, не совсем ясна задача, для которой это всё сделано. Раз задача не ясна, то не ясно, как писать тесты. Если не ясно, как писать тесты, то зачем их вообще писать?
С другой стороны, если глядя на плохой код программист знает, что и как этот код должен на самом деле реализовывать, то лучше всего взять и переделать этот самый плохой код, отдав ему соотвествующие почести, как неизбежному этапу обучения. Тогда и тестирование может не понадобиться, или оно понадобится в гораздо меньшем объёме. Да даже если объём тестирования окажется большим, чем предполагалось изначально, так хотя бы будет более ясная структура реализации, что превратится в более надёжный и качественный продукт.
Ну вот и спрашивается — зачем обязательно писать тесты на то, что на самом деле нужно переделать? Ради соблюдения Дао Тестирования? Гы.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, anvaka, Вы писали:
A>[i]"Я не могу написать этот код без создания моков и нарушения инкапсуляции.
А кто такие моки?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, ., Вы писали:
>> А кто такие моки? .>http://en.wikipedia.org/wiki/Mock_object
Спасибо конечно, но нет бы вот коротенько объяснить своими словами.
То, что это "пародия" я предпологал...
mock [mɔk] 1. ; 1) высмеивание, осмеяние; насмешка Syn: ridicule , derision 2) объект для насмешек; посмешище I could never forgive her for making a mock of me. — Я никогда не мог простить ей того, что она сделала из меня посмешище. Syn: laughing-stock 3) подражание; имитирование, копирование, пародия Syn: imitation , parody 4) подделка, фальсификация, жульничество Syn: counterfeit 2. 1) поддельный, фальшивый, фиктивный; суррогатный mock croc — искусственная крокодиловая кожа mock marriage — фиктивный брак Syn: sham , counterfeit , spurious 2) притворный; мнимый; ложный mock attack — ложное наступление Syn: feigned , pretended 3) пародийный; шуточный 4) репетиционный (о пробном экзамене в школе, проводящимся перед основным) •• — mock moon — mock sun 3. 1) а) насмехаться; высмеивать, осмеивать It's rude and cruel to mock at a foreign student's mistakes in English. — Грубо и жестоко насмехаться над ошибками иностранных студентов в английском. Syn: deride б) глумиться, издеваться Syn: jeer , scoff , flout 2) передразнивать; пародировать Syn: mimic , take off , counterfeit 3) сводить на нет (усилия) ; делать бесполезным, бесплодным • — mock up Осталось дней до окончания испытательного периода: 7. mock 1. verb [with obj.] 1) tease or laugh at in a scornful or contemptuous manner Вся статья >> Осталось дней до окончания испытательного периода: 7. mock [m'ɒk] mocks, mocking, mocked 1) If someone mocks you, they show or pretend that they think you are foolish or inferior, for example by saying something funny about you, or by imitating your behaviour. Вся статья >> Осталось дней до окончания испытательного периода: 7. mock — put the mock on smb. Осталось дней до окончания испытательного периода: 7. mock 1. v. [trans.] tease or laugh at in a scornful or contemptuous manner he mocks them as Washington insiders | [as .] mocking the mocking hostility in his voice made her wince Вся статья >> Осталось дней до окончания испытательного периода: 7. mock поддельный; фальшивый; мнимый; ложный, притворный Осталось дней до окончания испытательного периода: 7. mock имитация, подделка || поддельный, фальшивый Осталось дней до окончания испытательного периода: 7.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Erop wrote:
> поддельный, фальшивый, фиктивный; суррогатный mock croc — > искусственная крокодиловая кожа mock marriage — фиктивный брак Syn:
скорее ближе к этому значению. Там в вики ссылка русскую статью, как раз коротенько.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
* Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
* Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
* Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
* Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
чуть ниже более конкретно:
There is a difference in that the stub uses state verification while the mock uses behavior verification.
Мда. Интересно, хотя, честно говоря, Фаулер в своём репертуаре. По сути дела, всё сводится к той или иной комбинации трассировки, имитаций окружения, глушения ненужных вызовов и проверок последовательности обращений или состояния. А слов-то, слов-то... И все новые. И как всегда, обязательно нужно "обратить внимание на difference между A и B".
А что, если нужно совместить свойства, скажем, Mock, Fake и Dummy? Это так и будет — MockFakeDummy? Или их нужно обязательно разделять? Если да, то кому это нужно и зачем?
Казалось бы, если есть возможность сделать тестовое окружение с полным комплектом проверок и имитаций, то какая разница, как они называются по частям? Если такой возможности нет, то тем более не важно: просто реализовали, что удалось, а на остальное забили.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Ну вот и спрашивается — зачем обязательно писать тесты на то, что на самом деле нужно переделать? Ради соблюдения Дао Тестирования? Гы.
Чтобы после переделки запустить эти тесты и проверить, что "ужасный и правильный" код был заменен на "красивый и правильный", а не на "красивый и неправильный"
Сейчас читаю "XP. Разработка через тестирование", Кент Бек. Оттуда понабрался таких мыслей
Здравствуйте, Eugene Sh, Вы писали:
ГВ>>Ну вот и спрашивается — зачем обязательно писать тесты на то, что на самом деле нужно переделать? Ради соблюдения Дао Тестирования? Гы.
ES>Чтобы после переделки запустить эти тесты и проверить, что "ужасный и правильный" код был заменен на "красивый и правильный", а не на "красивый и неправильный"
Тут совокупность факторов: с одной стороны, раз это настолько плохо написано, то следовательно, не совсем ясна задача, для которой это всё сделано. Раз задача не ясна, то не ясно, как писать тесты. Если не ясно, как писать тесты, то зачем их вообще писать?
Ясно?
ES>Сейчас читаю "XP. Разработка через тестирование", Кент Бек. Оттуда понабрался таких мыслей
Не читайте советских газет по утрам. (c)
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Тут совокупность факторов: с одной стороны, раз это настолько плохо написано, то следовательно, не совсем ясна задача, для которой это всё сделано
Если не ясна задача, для которой написан плохой код, то и переписать его не получится. Какую задачу будет решать новый код?
Ту же самую? Но мы ведь не знаем ее.
Какую-то новую? Но тогда это не называется "переписыванием кода".
Я же исходил из предположения, что есть плохой код, который реализует известную функциональность. И этот код надо улучшить. Вот здесь и пригодятся тесты.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>[q]Тут совокупность факторов: с одной стороны, раз это настолько плохо написано, то следовательно, не совсем ясна задача
т.е. если задача ясна, код автоматически будет хорошим? Не думаю.