Обновить
26
ApeCoder@ApeCoder

Разработчик

6
Подписчики
Отправить сообщение
Нет, вложенные функции покрыты своими тестами, поэтому тестировать их косвенно нет необходимости. Так же как с "библиотечными" функциями.

Тогда почему вас насторожило что round не покрыт косвенными тестами настолько что он может быть отличен от trunc?


Именно так, модульные тесты — фикция и профанация.

Теперь надо применить эту же логику последовательно к компонентным тестам и end-to-end тестам: если X используется в соединении с Y для тестирования, то это уже тестирование не X а еще и Y.


Исходя из этого нет никаких компонентных тестов, а есть только вселенские тесты. Вы же не разрабатываете отдельные компьютеры для тестирования ваших компонентов?


А у меня другая логика unit тестом называется тест юнита отдельно от остальной системы. При этом можно переиспользовать части которые используются для строительства этой системы.


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

Ну хозяев с рабами то у всех есть, а вот какая целевая аудитория должна понимать сразу что sub это submissive? Ссылку можете дать на кого-то кто не вы и не BDSM (если это разные категории) и использует это сокращение в программировании? Я вот только знаю тег sub.
Слепое следование ТДД даёт гарантированно меньшее покрытие при большей трудоёмкости.

Я не понял о чём вы

Вы не поняли и при этом продолжили рассуждения!


Я вот о чем — вы вашем примере снизили количество кейзов, как с 27 до 9 за счет того, что тестируете кейзы вложенных выовов только в одном кейзе вызывающей функции — так? Условно, соответственно когда тестируюете другой кейз, вызывающей функции вы не гарантируете от соверщенно такой же подмены вызываемой функции на другую, совпадающую в одном тестируемом кейзе но не совпадающую в других. Совершенно так же как замена round на trunc.


чтобы не мокать каждый оператор и стандартную функцию,

Таким образом, никаких модульных тестов не существует: как только мы используем что-то не мокая оно обращается в компонентный тест! (вы повторили цепочку рассуждений из другого обсуждения, но с другими выводами :D )

С чего бы?

С того, что описаться в буквах s, h, o, u, l и d сложнее чем в одной s.


Это общепринятое сокращение?

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


Я поискал "submissive sub programming" и в первой строке было вот что


For in BDSM the submissive (or “sub”) willingly grants the dominant (or “dom”) power over them, and they do so out of trust and respect.

Теперь мне стало понятно, в какой именно среде это общепринятые термины и все стало ясно. Спасибо!

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

Какие аргументы у сторонников TDD за эти итерации? Или вы опять пытаетесь очень уверенно критиковать то, в чем не разобрались?


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

Подумал. А тут не тот же самый компромисс между трудоемкостью покрытия и точностью результата как и в вашей фразе ранее?


"Каждый из этих приватных методов (а точнее их видимость придётся повысить) тестируется в предположении, что вызываемые им методы уже протестированы. Это даст 3+3+3 = 9 кейсов."


Т.е. у вас дополнительный вызов метода уровня 2 покрывается ровно одним кейзом уровня 1. Разница только в том, что в этой новой задаче этот дополнительный вызов находится в отдельном методе, а метод уровня два библиотечный.

Это удобно и позволяет не запутаться. Одна и та же сущность во всех контекстах называется одинаково.

По мне, так это недостаток — отсутствие учета контекста. Ну да ладно. Многочисленные пользователи фреймворка смотрят на меня свысока ;)


Ага, опечатался.

Возможно, если бы была привычка писать should было бы сложнее


Я хз, как это однозначно сформулировать на английском.

Я бы написал что-то типа
"prints a given recipient name in a greeting"


Поэтому читайте лучше код — он однозначный.

Я бы предпочел читать код того, кто дает понятные имена


Сокращение от submissive.

Это общепринятое сокращение? Честно говоря, мне от расшифровки яснее не стало. Почему добавление в submissive это print?

Это пространства имён. Если вам режет глаз, то вы точно так же как и с импортами можете переименовать:

Зачем же вы живете с этим mol не переименовывая?


Вы таки гуманитарий?

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


даже test('returns greeting') читается чуть легче чем mol_test('return greeting') за счет третьего лица и удаления префикса.


в 'print greeting to defined target' вообще неоднозначность — я сначала прочитал это что надо распечатать что-то в target.


Там же английским по белому написано: печатает правильное приветствие указанному адресату.

Неа, там написано "напечатать", а не "печатает", а во-вторых не однозначно, к чему относится "to" — к print или greeting.


"печатать приветствие к определенной цели".


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


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


Кстати, что такое sub — там про сендвичи, или это какая-то концепция понятная вебдевам с первого взгляда?

Пишем код — тест зеленеет.

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


Это не юнит тест по определению, ибо тестирует разрозненные куски кода, не являющиеся единым целым. Это компонентный тест.

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


UPD: вернее, само обсуждение начинается отсюда


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

Уверенность в себе это хорошо. Но я не всегда доверяю чужой уверенности в себе :)

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

Совершенно верно. Только если метод является приватным мы декларируем что это особенность реализации класса. Это значит что либо он пользуется какими-то особенностями состояния объекта класса, и тогда нам надо как-то предоставить ему это состояние (и тест будет зависеть от интимных подробностей реализации класса таким образом будет хрупким) либо он завидует какому-то еще классу.

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

Еще хотелось бы отметить элегантноть выбранного фреймворка и стиля тестов в статье:


// Нахрена везде повторять этот "мол"?
$mol_test({
 // В названии теста не отражено требование которое он проверяет
'print greeting to defined target'() {
        const app = new $my_hello_message
        app.target = ()=> 'Jin'
        // опять mol. зачем, мол, повторять, мол, везде, мол?
        $mol_assert_equal( app.sub().join( '' ) , 'Hello, Jin' )
    } ,

})

Сравним с mocha.


import { hello } from './hello-world';
import { expect } from 'chai';
import 'mocha';

describe('Hello function', () => {

  it('should return hello world', () => {
    const result = hello();
    expect(result).to.equal('Hello world!');
  });

});

Читается почти как английский текст

Абстрактная цифра 30% покрытия говорит от том, что не покрыто по крайней мере 70% :)

Этот момент может настать и после 5 тестов, и после 3 и даже после первого же цикла.

Продемонстрируйте мне, пожалуйста, тест который приводит к написанию кода из двух уровней с тремя вариантами каждый при соблюдении правила 2 TDD. "You must not write more of a test than is sufficient to fail, or fail to compile." и 3 "You must not write more production code than is sufficient to make the currently failing test pass.".


Модульные тесты хрупкие по определению. Я писал об этом в той статье, что приводил выше.

Не нашел в статье определения юнит теста, по которому они должны быть хрупкими. Нашел в статье, что solitary юнит тесты с использованием моков должны иногда давать не те же результаты, что и тестирование с продакшн кодом. Про Solitary vs Sociable и Mocks aren't stubs можно почитать у Фаулера.


Вызов внешнего апи, там нечего тестировать.

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

Он требует увольнения любых людей выше или ниже среднего уровня команды.

Можно цитату?


Для нашего менеджмента это единственная ментрика, потому краеугольная.

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

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


см также Front Door First


Еще мне интересно как вы "Каждый из этих приватных методов (а точнее их видимость придётся повысить)" выполняете так, чтобы они не становились видны кому-то еще.

Вот статья самого Сазерленда www.scruminc.com/story-points-why-are-they-better-than
Я так понимаю, что это нужно для того, чтобы примерно представлять сколько фич можно сделать за данное время и как-то приблизительно планировать вперед учитывая все эти отпуски и болезни усредненно.

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

Вопрос. А что такое «несходящиеся спринты» и какой реальный негативный эффект от этого?
Похоже вы вкладываете в понятие ТДД существенно больше, чем все остальные.

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


ТДД-то ту при чём?

https://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html


A few years later this fine granularity was codified into three rules: the so-called Three Laws of TDD.
  1. You must write a failing test before you write any production code.
  2. You must not write more of a test than is sufficient to fail, or fail to compile.
  3. You must not write more production code than is sufficient to make the currently failing test pass.

Как только вы покроете ваши 9 случаев у вас не получится написать красный тест.


А чем инкапсуляция от сокрытия отличается знаете?

The term encapsulation is often used interchangeably with information hiding. Not all agree on the distinctions between the two though; one may think of information hiding as being the principle and encapsulation being the technique. A software module hides information by encapsulating the information into a module or other construct which presents an interface.


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


Что вы там тестировать в слове собрались? Константы?

Я думал, что слова бывают разные и чтобы определить ширину, нужно какое-то вычисление, нет?

А как он висит, если ничего не говорят. Вообще, насколько я помню, сначала в XP предлагали использовать «идеальные часы» и velocity оценивалась как отношение идеальных часов к календарным. Потом решили что это подбивает начальников давить на девелоперов, чтобы они работали согласно идельным часам, потом ввели сторипоинты, чтобы сделать единицу измерения абтрактной и отвязанной от времени.

Нон как видно ни начальники ни девелоперы не хотят разбираться в этой истории — первые предпочитают давить, вторые — страдать и винить сторипоинты :).
Вы сейчас говорите про тестирование белого ящика

Я сейчас говорю о TDD. У меня складывается впечатление, то вы сейчас пытаетесь критиковать процесс, про который не знаете даже теоретически


Каждый из этих приватных методов (а точнее их видимость придётся повысить) тестируется в предположении, что вызываемые им методы уже протестированы. Это даст 3+3+3 = 9 кейсов.

Расскажите, как TDD сделает из этого 27 кейзов.


Каждый из этих приватных методов (а точнее их видимость придётся повысить)

Ээээ? Вы ранее тут что-то говорили при нарушение инкапсуляции?


нужно определить ширины слов

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

"Речь идет только об обязательствах"


https://www.scrum.org/resources/commitment-vs-forecast


"One of the most controversial updates to the 2011 Scrum Guide has been the removal of the term “commit” in favor of “forecast” in regards to the work selected for a Sprint. We used to say that the Development Team commits to which Product Backlog Items it will deliver by the end of the Sprint. Scrum now encourages the Development Team to forecast which Product Backlog Items it will deliver by the end of the Sprint. It may seem to be a simple wording change, but in fact there are strong reasons behind it, and surely it will have great implications. "

У вас может быть 3 приватных последовательно вызывающих друг друга метода. В каждом есть, допустим, 3 ветки логики. Если тестировать через публичный интерфейс, то нужно проверить 3х3х3 = 27 кейсов. Помножьте на число граничных условий и будет совсем ахтунг.

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


Во-вторых, если вы действительно настаиваете на тестировании всех кобинаций, расскажите как вы это делаете? Мне сейчас представляется, что с любым другим подходом эта проблема станет больше — при тестировании через UI вручную количество комбинаций станет больше.


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

Это не делается механически. Если что-то хочется протестировать отдельно, надо подумать почему — представляет оно отдельную концепцию или нет. Условно, если класс Клиент содержит код проверки счета, надо рассмотреть возможность создать класс Счет, перенести код проверки туда и протестировать отдельно.


Т.е. выделение дополнительного слоя абстракции со своей инкапсуляцией.

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность