Статьи

Изучение TDD в JavaScript с небольшим ката

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

Я решил выполнить небольшую и известную Kata, которую мы использовали также во время интервью, чтобы отделить программистов от не программистов: ката FizzBuzz. Моя цель состояла в том, чтобы научиться настраивать платформу для тестовой разработки в JavaScript, следуя совету книги по разработке через тестирование JavaScript.

Параметры, которые меняются от моих привычек — это инструменты для запуска тестов и язык программирования, но моя IDE (Unix & Vim) оставалась неизменной вместе с Kata:

  • Напишите функцию, которая возвращает числовой аргумент.
  • Но для кратных трех верните Fizz вместо числа, а для кратных пяти — Buzz .
  • Для чисел, кратных трем и пяти, верните FizzBuzz .
  • Дополнительное требование: если пройдено кратное 7, вернуть Bang ; когда передано кратное 5 и 7, вернуть BuzzBang ; и так далее для всех комбинаций.

В качестве инструментов для запуска тестов я использовал JsTestDriver и Firefox, как это предлагается в книге « Разработка через JavaScript на основе тестирования», которую я сейчас читаю.

JsTestDriver

JsTestDriver заставит вас снова почувствовать радость зеленого бара. Скачайте его jar, поместите его куда-нибудь и добавьте псевдоним в ваш .bashrc:

export JSTESTDRIVER_HOME=~/bin
alias jstestdriver="java -jar $JSTESTDRIVER_HOME/JsTestDriver-1.3.2.jar"

Запустите сервер:

jstestdriver --port 4224

Укажите открытый браузер (я использовал Firefox) на localhost: 4224. Браузер пингует его через Ajax-запросы на неопределенный срок, чтобы собрать тесты для запуска Теперь мы можем использовать командную строку для запуска тестов, как вы это сделаете с PHPUnit, если вы PHPer:

jstestdriver --tests all

Ката

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

server: http://localhost:4224

load:
- src/*.js
- test/*.js

В JsTestDriver тестовый случай создается путем передачи в TestCase (глобальная функция, предоставляемая JsTestDriver) карта, содержащая анонимные функции.

TestCase("FizzBuzzTest", {
    "test should return Fizz when passed 3" : function () {
        assertEquals("Fizz", fizzbuzz(3));
    }
});

Будут выполнены функции, имена которых начинаются с test ; Есть некоторые зарезервированные ключевые слова, такие как setUp, которые используются в качестве хуков для создания фикстур.

Выполнить тест с помощью команды alias действительно просто:

jstestdriver --tests all

Я сделал первый тестовый тест с файлом fizzbuzz.js, содержащим первую версию функции (с поддельной реализацией):

function fizzbuzz()
{
    return 'Fizz';
}

Результат? Зеленая полоса (метафорически зеленая; все тесты пройдены)

.
Total 1 tests (Passed: 1; Fails: 0; Errors: 0) (0,00 ms)
  Firefox 4.0 Linux: Run 1 tests (Passed: 1; Fails: 0; Errors 0) (0,00 ms)

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

Продолжается

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

Поскольку мне также нужно было создать объект только в одном месте, я начал использовать setUp для создания осветителей:

TestCase("FizzBuzzTest", {
    setUp : function () {
        this.fizzbuzz = new FizzBuzz({
            3 : 'Fizz',
            5 : 'Buzz',
            7 : 'Bang'
        });
    },
    "test should return the number when passed 1 or 2" : function () {
        assertEquals(1, this.fizzbuzz.accept(1));
        assertEquals(2, this.fizzbuzz.accept(2));
    },
    "test should return Fizz when passed 3 or a multiple" : function () {
        assertEquals("Fizz", this.fizzbuzz.accept(3));
        assertEquals("Fizz", this.fizzbuzz.accept(6));
    },
    "test should return Buzz when passed 5 or a multiple" : function () {
        assertEquals("Buzz", this.fizzbuzz.accept(5));
        assertEquals("Buzz", this.fizzbuzz.accept(10));
    },
    "test should return FizzBuzz when passed a multiple of both 3 and 5" : function () {
        assertEquals("FizzBuzz", this.fizzbuzz.accept(15));
        assertEquals("FizzBuzz", this.fizzbuzz.accept(30));
    },
    "test should return Bang when passed a multiple of 7" : function () {
        assertEquals("Bang", this.fizzbuzz.accept(7));
        assertEquals("Bang", this.fizzbuzz.accept(14));
    },
    "test should return FizzBuzzBang when it is the case" : function () {
        assertEquals("FizzBuzzBang", this.fizzbuzz.accept(3*5*7));
    }
});

Вы можете использовать Тхи с , чтобы доля светильников между нАлАдкОй и различными методами испытаний: тест не отличаться от JUnit и PHPUnit из них.

Как и во всех средах тестирования xUnit, setUp выполняется на новом объекте для каждого теста, чтобы сохранить изоляцию. Мне немного нравится способ, которым в JavaScript вы можете разорвать и собрать объекты: в конце концов, это называется объектно-ориентированным программированием, а не класс-ориентированным программированием.

Я решил использовать небольшой конструктор функций, как вы можете понять из теста:

function FizzBuzz(correspondences) {
    this.correspondences = correspondences;
    this.accept = function (number) {
        var result = '';
        for (var divisor in this.correspondences) {
            if (number % divisor == 0) {
                result = result + this.correspondences[divisor];
            }
        }
        if (result) {
            return result;
        } else {
            return number;
        }
    }
}

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

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