На современном этапе тестирование занимает очень важное положение в программировании любых продуктов. Веб программирование на яваскрипт не является исключением. В этой статье коснемся такого часного случая, как тестирование модулей RequireJS в связке с Symfony2.
Данная статья является логическим продолжением предыдущей, по-этому чтение рекомендую начинать с первой статьи в этой серии «Оптимизация модулей RequireJS в Symfony2», чтобы четче понимать то, что здесь происходит.
Итак, чтобы иметь возможность тестировать те модули, которые мы создаем на яваскрипте с помощью RequireJS, воспользуемся такой распространенной библиотекой для тестирования яваскриптов, как Qunit. Для этого, как пишут на оффсайте необходимо создать небольшую html страницу, на которой будут отображаться проводимые тесты. Поскольку мы имеем дело с Symfony2, нам потребуется сделать простейший контроллер, прописать к нему роут и подцепить вьюшку. В зависимости от конкретного случая, это можно с делать в отдельном бандле, или в каком-либо из уже имеющихся. Чтобы не нагромождать статью лишним кодом, предположим, что существует WebBundle в котором мы это и сделаем.
Контроллер будет выглядеть очень просто:
Создадим элементарную вьюшку для отображения результаов тестов, как рекомендуют в документации:
Пропишем роут к нашему контроллеру:
Таким образом страница для отображения результатов тестов создана. Самое время приступить к написанию файлов для самого тестирования.
Как может выглядеть упомянутый в нашей вьюхе test.js
Для того, чтобы это запустилось необходимо доработать конфигурацию HearsayRequireJSBundle, оговоренную в предыдущей статье, она примет вид (изменения выделены):
И, соответственно, установить библиотеку QUnit, на которую мы ссылаемся в QUnit.location:
В кульминации пишем наши первые тесты:
Напишем модель, которая отвечала бы нашим тестам:
Теперь, если мы обратимся по адресу http://example.com/_tests («example.com» стоит заменить на свой девелоперский хост), то сможем увидеть примерно следующее:
Для лучшего понимания структуры и базовой подготовки нашего проекта советую прочесть предыдущую статью.
В результате нехитрой проделанной работы мы получили возможность тестировать RequireJS модули нашего яваскрипт приложения в контексте фреймворка Symfony2, как в «дев», так и в «прод» окружении. Хочу отметить, что это лишь один из вариантов возможных подходов к тестированию JS проекта, который совершенно не претендует на звание оптимального для различных ситуаций.
P.S.. В нашей школе вот-вот стартует пятимесячный курс обучения от автора статьи «Хочу стать Junior PHP Developer!» и «Symfony 2. Гибкая разработка». Чтобы записаться пишите на info@digitov.com
P.P.S. Чтобы получать наши новые статьи раньше других или просто не пропустить новые публикации — подписывайтесь на нас в Facebook, VK и Twitter.
Авторы:
Сергей Харланчук, Senior PHP Developer, Компания «SECL GROUP» / «Internet Sales Technologies»
Никита Семенов, президент, Компания «SECL GROUP» / «Internet Sales Technologies»
Данная статья является логическим продолжением предыдущей, по-этому чтение рекомендую начинать с первой статьи в этой серии «Оптимизация модулей RequireJS в Symfony2», чтобы четче понимать то, что здесь происходит.
Итак, чтобы иметь возможность тестировать те модули, которые мы создаем на яваскрипте с помощью RequireJS, воспользуемся такой распространенной библиотекой для тестирования яваскриптов, как Qunit. Для этого, как пишут на оффсайте необходимо создать небольшую html страницу, на которой будут отображаться проводимые тесты. Поскольку мы имеем дело с Symfony2, нам потребуется сделать простейший контроллер, прописать к нему роут и подцепить вьюшку. В зависимости от конкретного случая, это можно с делать в отдельном бандле, или в каком-либо из уже имеющихся. Чтобы не нагромождать статью лишним кодом, предположим, что существует WebBundle в котором мы это и сделаем.
Контроллер будет выглядеть очень просто:
#src/Acme/WebBundle/Controller/TestController.php
<?php
namespace Acme\WebBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class TestController extends Controller
{
public function testAction()
{
return $this->render('AcmeWebBundle:Test:layout.html.twig');
}
}
?>
Создадим элементарную вьюшку для отображения результаов тестов, как рекомендуют в документации:
#src/Acme/WebBundle/Resources/views/Test/layout.html.twig
<!DOCTYPE html>
<html>
<head>
<title>{% block sylius_title %}QUnit tests{% endblock %}</title>
<meta charset="UTF-8">
<!-- Подключаем таблицу стилей для QUnit -->
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.15.0.css"/>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<!-- Подключаем и инициализируем RequireJS с test.js -->
{% javascripts '@AcmeWebBundle/Resources/assets/js/test.js' filter='requirejs' %}
{{ require_js_initialize({ 'main' : asset_url }) }}
{% endjavascripts %}
</body>
</html>
Пропишем роут к нашему контроллеру:
#src/Acme/WebBundle/Resources/config/routing.yml
_tests:
pattern: '/_tests'
defaults: { _controller: AcmeWebBundle:Test:test }
Таким образом страница для отображения результатов тестов создана. Самое время приступить к написанию файлов для самого тестирования.
Как может выглядеть упомянутый в нашей вьюхе test.js
#src/Acme/WebBundle/Resources/assets/js/test.js
(function () {
"use strict";
// Отключаем автозагрузку в конфиге Qunit, чтобы не было ошибок, типа
// «Called start() while already started (QUnit.config.semaphore was 0 already)»
QUnit.config.autoload = false;
QUnit.config.autostart = false;
//require the unit tests.
require(
["QUnit", "tests/user/user", "tests/user/user2"],
function (QUnit, user) {
// Запускаем тесты
user.run();
user2.run();
// Стартуем QUnit.
QUnit.load();
QUnit.start();
}
);
}());
Для того, чтобы это запустилось необходимо доработать конфигурацию HearsayRequireJSBundle, оговоренную в предыдущей статье, она примет вид (изменения выделены):
# app/config/config.yml
hearsay_require_js:
require_js_src: //cdnjs.cloudflare.com/ajax/libs/require.js/2.1.14/require.min.js
initialize_template: HearsayRequireJSBundle::initialize.html.twig
#папка в которую будут собираться наши, не полностью обработанные, скрипты в «дев» версии в каталоге «web».
base_url: js
#путь к папке со скриптами в бандле
base_dir: %kernel.root_dir%/../src/Acme/DemoBundle/Resources/assets/js # Required
#пути к основным модулям и скриптам для requirejs.config()
#для внешних библиотек не забываем указывать «external: true»
paths:
main:
location: @AcmeDemoBundle/Resources/assets/js/main
jquery:
location: //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min
external: true
underscore:
location: //cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min
external: true
backbone:
location: //cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min
external: true
text:
location: @AcmeDemoBundle/Resources/assets/js/vendor/text
bootstrap:
location: //maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min
external: true
test:
location: @AcmeWebBundle/Resources/assets/js/test
QUnit:
location: %kernel.root_dir%/../node_modules/qunitjs/qunit/qunit
#конфиг shim соответственно
shim:
bootstrap:
deps: [jquery]
QUnit:
deps: [jquery]
exports: "QUnit"
test:
deps: [QUnit]
exports: "test"
И, соответственно, установить библиотеку QUnit, на которую мы ссылаемся в QUnit.location:
npm install qunit
В кульминации пишем наши первые тесты:
#src/Acme/WebBundle/Resources/assets/js/tests/user/user.js
define(
["QUnit", "bundles/user/models/user"],
function (QUnit, User) {
"use strict";
var run = function () {
QUnit.module("Тест для Backbone модели пользователя");
QUnit.test("Проверка на корректность дефолтных значений", function () {
// Количество ожидаемых проверок
QUnit.expect(3);
var user = new User();
// Проверка дефолтных значений модели пользователя
QUnit.equal(user.get("name"), "User name", "Дефолтное имя соответствует 'User name'");
QUnit.equal(user.get("email"), "example@example.com", "Дефолтнsый Email соответствует 'example@example.com'");
QUnit.equal(user.get("telephone"), "111-11-11", "Дефолтнsый телефон соответствует '111-11-11'");
});
return {run: run}
}
);
#src/Acme/WebBundle/Resources/assets/js/tests/user/user2.js
define(
["QUnit", "bundles/user/models/user"],
function (QUnit, User) {
"use strict";
var run = function () {
QUnit.module("Тест2 для Backbone модели пользователя");
QUnit.test("Может быть создан объект пользователя и изменены значения по дефолту", function () {
QUnit.expect(3);
// Создаем объект User с определенными недефолтными значениями
var user = new User({
name: "Vasily Pupkin",
email: "vasily@pupkin.com",
telephone: "333-22-11"
});
// Проверяем правильность сохраненных значений
QUnit.equal(user.get("name"), "Vasily Pupkin", "Name Correct!");
QUnit.equal(user.get("email"), "vasily@pupkin.com", "Email Correct!");
QUnit.equal(user.get("telephone"), "333-22-11", "Telephone Correct!");
});
};
return {run: run}
}
);
Напишем модель, которая отвечала бы нашим тестам:
#src/Acme/WebBundle/Resources/assets/js/bundles/user/models/user.js
define(["backbone"], function (Backbone) {
"use strict";
return Backbone.Model.extend({
defaults: {
name: "User name",
email: "example@example.com",
telephone: "111-11-11"
}
});
});
Теперь, если мы обратимся по адресу http://example.com/_tests («example.com» стоит заменить на свой девелоперский хост), то сможем увидеть примерно следующее:
Для лучшего понимания структуры и базовой подготовки нашего проекта советую прочесть предыдущую статью.
В результате нехитрой проделанной работы мы получили возможность тестировать RequireJS модули нашего яваскрипт приложения в контексте фреймворка Symfony2, как в «дев», так и в «прод» окружении. Хочу отметить, что это лишь один из вариантов возможных подходов к тестированию JS проекта, который совершенно не претендует на звание оптимального для различных ситуаций.
P.S.. В нашей школе вот-вот стартует пятимесячный курс обучения от автора статьи «Хочу стать Junior PHP Developer!» и «Symfony 2. Гибкая разработка». Чтобы записаться пишите на info@digitov.com
P.P.S. Чтобы получать наши новые статьи раньше других или просто не пропустить новые публикации — подписывайтесь на нас в Facebook, VK и Twitter.
Авторы:
Сергей Харланчук, Senior PHP Developer, Компания «SECL GROUP» / «Internet Sales Technologies»
Никита Семенов, президент, Компания «SECL GROUP» / «Internet Sales Technologies»
borNfree
Спасибо за статью. А как вы эти тесты запускаете, например, на CI сервере? PhantomJS?
SECL Автор
Да, часто именно так.