в начало заметок о компонентах

текущая версия vs. v1



Компоненты можно тестировать в консоли, как обычные node.js модули. К сожалению, к текущей версии в этом случае есть проблемы с использованием зависимостей, например, завязаных на DOM. То есть если я тестирую компоненту к консоли, запуская, скажем node node mocha ..., я не могу просто сделать require другой компоненты, завязаной на DOM. В любом случае в консоли require подхватит модуль node.js, а не компоненту. А в модуле domify node.js нет объекта document. В будущих версиях билдера компонент ситуация изменится. См. https://github.com/component/component/issues/41. Пока что для тестирования этих компонент в консоли можно использовать phantom.



В текущей версии приходится использовать (причем в теле компоненты, но только для целей тестирования) что-то вроде (см. component/router):

try {
  var Route = require('route-component');
} catch (err) {
  var Route = require('route');
}


Я на этом останавливаться не буду, подождем v1. В данном посте сначала посмотрим, как устроено юнит-тестирование компонент на низком уровне, т.е. вручную, потом я напишу об автоматизации этого процесса. О интегральном тестировании js-приложений тоже написано много, я на этом также останавливаться не буду.

Простые же компоненты, не имеющие отличий (кроме обертки) от параллельного node-модуля, такие как, например component/indexof, component/each, использовать как зависимости можно уже прямо сейчас, mocha-тесты в консоли будут работать.

Код примера доступен по адресу https://github.com/mbykov/component-testing-example. Клонируйте и посмотрите его.

юнит vs. интегральные тесты



Что такое интегральный тест понятно — мы тестируем само приложение, в боевой позиции (если отвлечься от stubs & mocks). Мы используем Cucumber, Selenium, Capybara и смотрим, чтобы отклик приложения как целого соответствовал ожиданиям. Юнит-тест — это тест отдельного метода в компоненте. Вызывается только данный метод, и если затрагивается что-то еще, то это плохо. Такое вот доморощенное определение. Компоненты, однако, именно так и проектируются. В них есть внутренние функции, недоступные снаружи, и они, естественно, недоступны и для тестирования. И экспортируемые методы, которые мы вполне способны вызвать откуда угодно.

test/test.js



Создадим простейшую компоненту для консольного теста. Пусть нам нужно узнать, скажем, следующую букву. Мы забыли, что идет вслед за в — г или д. Или, скажем, вслед за ξ — η или λ? (Этот «игрушечный» метод годится только для символов без акцентов).

Пусть в компоненте у нас будут два метода, sym для преобразования символа, и word — для слова. В нем воспользуемся готовой компонентой component/map для удобства.

в компоненте должно быть всего лишь

var map = require('map-component');

module.exports = nextSym;

function nextSym() {
    if (!(this instanceof nextSym)) return new nextSym();
    return this;
}


и два метода,

nextSym.prototype.sym = function(sym){
    return String.fromCharCode(sym.charCodeAt(0)+1);
}

nextSym.prototype.word = function(word){
    var self = this;
    var arr = word.split('');
    var res = map(arr, function(sym) {
        return self.sym(sym);
    })
    return res.join('');
}


строка if (!(this instanceof example)) return new example() является магическим заклинанием, означающим, что нам не нужно будет писать оператор new при вызове компоненты.

$ make


package.json, mocha & should



будем использовать фреймворк mocha (кофе мокко) того же автора, TJ Holowaychuk и Should Assertion Library.

Теперь мы используем, по-сути, не компоненты, а node.js, так что создадим файл package.json

$ npm init


в файле package.json укажем необходимые нам зависимости

   "version": "0.0.1",
    "dependencies": {
        "map-component": "*"
    },
    "devDependencies": {
        "mocha": "*",
        "should": "*"
    },


map-component необходима как пример зависимости для работы компоненты, а mocha и should — для выполнения тестов.

$ npm install


makefile & test.js



чтобы не вызывать тесты в консоли руками, в фале Makefile запишем пункт test;

test:
    @./node_modules/.bin/mocha \
        --require should \
        --reporter spec


mocha по умолчанию ищет тесты в директории test. Создадим файл test.js

var nextSym = require('..')();

describe('component console example', function(){
    describe('symbol', function() {
        it('б before а', function() {
            var next = nextSym.sym('а');
            next.should.be.equal('б');
        })
    })
    describe('word', function() {
        it('shifted qwerty  is rxfsuz', function() {
             var shifted= nextSym.word('qwerty');
            shifted.should.be.equal('rxfsuz');
        })
    })
})


выполняем тест

  component console example
    symbol
      ✓ б before а
    word
      ✓ shifted qwerty  is rxfsuz


  2 passing (19ms)


Однако компоненты предназначены для работы в браузере. Так что и тестирование в консоли — скорее исключение. Тестирование должно производиться в браузере, и быть удобным. См. след. разделы.

продолжение следует