- Абстрактные знания
- Варианты оформления тестов
- Оформление файла
block.spec.js
- Оформление файла
block.specs/testbundle.bemjson.js
- Оформление элемента
i-bem__test
- Проектные настройки
- Сборка и запуск тетов
- Демонстрация
Тест состоит из двух сущностей: тестовый бандл (раннер) и набор тестов.
Тестовые бандлы оформляются по полной аналогии с примерами, в папке block.specs
.
У каждого тестового бандла может быть свой дополнительный уровень переопределения.
Наборы тестов пишутся в технологии spec.js
.
Набор тестов можно сделать для любой bem-сущности (блок, элемент и т.д.).
Для тестирования используется фреймворк mocha в режиме BDD
.
Для ассертов используется библиотека chai с плагином sinon-chai.
На момент запуска тестов метод chai.should
уже выполнен (http://chaijs.com/guide/styles/).
Для моков используется библиотека sinon.
Условно можно выделить два случая:
- Тесты, не требующие специфичного DOM-дерева, либо создающие его самостоятельно через JS.
- Тесты, требующие специфичное DOM-дерево, созданное на этапе генерации страницы.
Для первого случая подходит простая схема оформления тестов:
common.blocks/block/
├── __elem
│ └── ...
├── block.css
├── block.deps.js
├── block.js
└── block.spec.js
Тесты пишутся в файле block.spec.js
.
В данном случае это тесты для блока, но можно точно также написать их для элемента или модификатора. Этого достаточно, чтобы собрать дефолтный тестовый бандл, в рамках которого будут запущены тесты из этого файла.
Во втором случае нам требуется входное bem-дерево. Для этого по аналогии с примерами, в папке блока создается
директория block.specs
:
common.blocks/block/
├── __elem
│ ├── block__elem.css
│ └── block__elem.title.txt
├── block.specs
│ └── testbundle.bemjson.js
├── block.js
└── block.spec.js
Здесь мы гораздо лучше контролируем процесс. В testbundle.bemjson.js
можно задать bem-дерево
для полноценной страницы, указать тесты каких конкретно блоков запускать.
Для этого конкретного бандла можно задать свой дополнительный уровень переопределения:
common.blocks/block/
├── __elem
│ ├── block__elem.css
│ └── block__elem.title.txt
├── block.specs
│ ├── testbundle.blocks
│ └── myblock
│ └── myblock.spec.js
| └── testbundle.bemjson.js
├── block.js
└── block.spec.js
Важно
Файл testbundle.bemjson.js
должен интерпретироваться как блок в технологии bemjson.js
,
поэтому в имени тестового бандла нельзя использовать нижнее подчеркивание.
Тесты пишутся под фреймворк mocha с использованием библиотеки ассертов chai.
Для запуска тестов используется модульная система. Каждый тест
декларируется под именем spec
, но провайдит undefined
.
Пример:
modules.define('spec', function(provide) {
describe('block', function() {
it('Два умножить на два должно равняться четырем', function() {
(2*2).should.to.equal(4);
});
});
provide();
});
В testbundle.bemjson.js
пишется произвольный BEMJSON, плюс:
- подключение
testbundle.spec.js
(должно идти после подключения обычного js); - нужно задекларировать блок
spec
.
Пример:
({
block : 'page',
head : [
{ elem : 'css', url : '_testbundle.css', ie : false },
{ elem : 'js', url : '_testbundle.spec.js' }
],
content : [
{ block : 'spec' },
{ block : 'header' },
{ block : 'content' },
{ block : 'footer' }
]
})
spec
это специальный блок, который поставляется с библиотекой bem-pr
. Он умеет запускать тесты.
Делает две простые вещи:
- Дает возможность прогнать тесты конкретных блоков;
- Подтягивает за собой тестовый фреймворк (mocha), библиотеку ассертов (chai) и пр.
Есть два способа оформления блока spec
в testbundle.bemjson.js
.
- Запустить все тесты, какие приехали по зависимостям:
{ block : 'spec' }
Запустить тесты конкретных блоков:
{
block : 'spec',
content : [
{ block : 'block' },
{ block : 'block', elem : 'elem' },
{ block : 'another-block' }
...
]
}
В файле .bem/make.js
:
- расширяем класс
SpecNode
В файле .bem/levels/specs-set.js
:
- указываем пути до технологий:
spec.js
spec.js+browser.js+bemhtml
spec.bemjson.js
browser.js
bemhtml
phantomjs
Сначала нужно настроить сборку примеров (и убедиться, что она работает)
За сборку тестовых бандлов отвечает класс SpecNode
. По аналогии с примерами, он расширяет
стандартный класс BundleNode
из bem-tools.
Расширяем этот класс:
- указываем технологии, в которых будет собираться тестовый бандл;
- добавляем уровень переопределения
bem-pr/spec.blocks
(там лежит блокspec
); - указываем web-адрес, который смотрит на корень проекта (опционально);
- указываем название репортера, который будет выводить результаты тестов в консоли (опционально).
MAKE.decl('SpecNode', {
getLevels : function() {
return this.__base()
.concat('<path/to/bem-pr>/spec.blocks');
},
getTechs : function() {
return [
'bemjson.js',
'bemdecl.js',
'deps.js',
'bemhtml',
'spec.js+browser.js+bemhtml',
'css',
'html',
'phantomjs'
];
},
webRoot : 'http://islands-page.dev/',
consoleReporter: 'teamcity'
})
Выше я предполагаю, что полный набор уровней уже указан для класса BundleNode
, поэтому просто
расширяю этот набор уровнем bem-pr/test.blocks
.
webRoot
должен быть таким, чтобы от него можно было отложить путь до тестового бандла,
например http://islands-page.dev/<setName>.specs/block/test-bundle/test-bundle.html
.
webRoot
указывается со слешом на конце.
Возможные значения поля consoleReporter
смотри
в документации к mocha-phantomjs.
По умолчанию используется репортер spec
.
В файле .bem/levels/specs-set.js
должны быть указаны пути до технологий
spec.js+browser.js+bemhtml
, spec.js
, spec.bemjson.js
, phantomjs
, browser.js
и bemhtml
,
которые потребуются при сборке тестов.
// .bem/levels/specs-set.js
exports.getTechs = function() {
return {
'spec.js+browser.js+bemhtml' : PATH.join(PRJ_ROOT, 'bem-pr/bem/techs/spec.js+browser.js+bemhtml'),
'spec.js' : PATH.join(PRJ_ROOT, 'bem-pr/bem/techs/spec.js.js'),
'bemhtml' : PATH.join(PRJ_ROOT, 'bem-core/.bem/techs/bemhtml.js'),
'browser.js' : PATH.join(PRJ_ROOT, 'bem-core/.bem/techs/browser.js.js'),
'spec.bemjson.js' : PATH.join(PRJ_ROOT, 'bem-pr/bem/techs/spec.bemjson.js'),
'phantomjs' : PATH.join(PRJ_ROOT, 'bem-pr/bem/techs/phantomjs.js'),
'bemdecl.js' : 'v2/bemdecl.js',
'deps.js' : 'v2/deps.js',
'js' : 'v2/js-i',
'css' : 'v2/css',
// ...
};
};
Дефолтный тестовый бандл для отдельной БЭМ-сущности, по технологии spec.js:
› bem make <setName>.specs/block/spec-js
› bem make <setName>.specs/block__elem/spec-js
Рукотворный тестовый бандл:
› bem make <setName>.specs/block/testbundle
› bem make <setName>.specs/block__elem/testbundle
Все тестовые бандлы в рамках набора <setName>
:
› bem make <setName>.specs
Если в процесс сборки тестовых бандлов была добавлена технология phantomjs
, то в конце сборки тесты
прогонятся через PhantomJS, вы увидите результаты их выполнения прямо в консоли.
Собранный тестовый бандл можно открыть в браузере, там тоже будут показаны результаты выполнения тестов.
$ git clone git@github.com:mishaberezin/bl-controls
$ cd bl-controls
$ npm install
$ ./node_modules/.bin/bem make bem-pr
$ ./node_modules/.bin/bem make desktop.sets/attach.tests/01-test
$ ./node_modules/.bin/bem make desktop.sets/attach.tests/default