Под-методы TDD Unit Test - PullRequest
       19

Под-методы TDD Unit Test

0 голосов
/ 07 июня 2019

Передо мной стоит вопрос: напишу ли я тесты для методов, являющихся результатом рефакторинга другого метода.

Первый вопрос, рассмотрите этот сюжет.

class Puzzle(
    val foo: List<Pieces>,
    val bar: List<Pieces>
) {
    init {
       // code to validate foo
       // code to validate bar
    }
}

Здесь я проверяю параметры при построении объекта. Этот код является результатом TDD. Но с TDD мы пишем fail_test -> pass test -> refactor, при рефакторинге я переносил методы валидатора в вспомогательный класс PuzzleHelper.

object PuzzleHelper {

    fun validateFoo() {
         ...
    }

    fun validateBar() {
         ...
    }
}

Нужно ли мне проверять validateFoo и validateBar в этом случае?

Второй вопрос

class Puzzle(
    val foo: List<Pieces>,
    val bar: List<Pieces>
) {
    ...

    fun getPiece(inPosition: Position) {
        validatePosition()
        // return piece at position
    }

    fun removePiece(inPosition: Position) {
        validatePosition()
        // remove piece at position
    }
}

object PuzzleHelper {

    ...

    fun validatePosition() {
         ...
    }
}

Нужно ли мне писать тест для getPiece и removePiece, которые включают проверку позиции?

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

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Нужно ли мне проверять validateFoo и validateBar в этом случае?

Это зависит.

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

Это действительно хорошо работает, когда требуемое поведение вашей системы стабильно.

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

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

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

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

1 голос
/ 07 июня 2019

Когда мы дойдем до стадии рефакторинга цикла Red -> Green -> Refactor, мы не должны добавлять никакого нового поведения. Это означает, что весь код уже протестирован, поэтому никаких новых тестов не требуется. Вы можете легко подтвердить, что вы сделали это, изменив измененный код и наблюдая, как он проваливает тест. Если этого не произойдет, вы добавили что-то, чего не должны были делать.

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

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

Единственное, на что я хотел бы отметить, это то, что размещение методов в статическом объекте (функции класса, глобальные функции, как бы вы ни хотели их вызывать) усложняет тестирование кода. Если вы хотите протестировать методы вашего класса, игнорируя валидацию (оставляя ее всегда проходящей), вы не сможете этого сделать.
Я предпочитаю создавать коллаборатора, который передается классу в качестве аргумента конструктора. Таким образом, ваш класс теперь получает validator: Validator, и вы можете сдать ему все, что хотите, в тесте. Заглушка, настоящая вещь, издевательство и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...