Статьи

Разработка через тестирование с помощью Meteor

Если вы недавно следили за технологической сценой, Meteor не будет для вас чем-то новым. Мы слышим много хороших новостей о Метеоре каждую неделю.

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

Метеор больше не игрушка

Хотя Meteor еще молод, многие люди стремятся создавать приложения для массового производства. Это потому, что это решает реальную проблему и позволяет разработчикам сосредоточиться на логике приложения, а не беспокоиться о том, как управлять связью между сервером и клиентом.

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

Как должна выглядеть система метеоритных испытаний?

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

Meteor — все о реальном времени и о том, как мы можем обмениваться данными между клиентами (браузерами). Таким образом, среда тестирования должна быть способна писать тестовые случаи с участием нескольких клиентов.

И самое главное, это должно быть весело.

Представляем Laika — тестовый фреймворк для метеора

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

Веб-сайт: http://arunoda.github.io/laika/

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

Laika - Тестовый фреймворк для Meteor

Настройка системы

Лайка делает магию за сценой для вас. Поэтому в вашей системе должны быть доступны сторонние инструменты.

  • установить nodejs — Laika работает поверх nodejs
  • установить phantomjs — Лайка использует фантомы для создания клиентов
  • установить mongodb — Laika нужна внешняя база данных mongodb для каждого теста

Дополнительно,

  • вам нужно запустить mongodb во время теста
  • используйте эту команду для запуска mongodb с некоторыми оптимизациями для Laika

mongod --smallfiles --noprealloc --nojournal

Наконец, установите Laika с помощью sudo npm install -g laika .

Руководство по началу работы

Мы проверим коллекцию Метеор в двух сценариях.

  1. Вставка документа с клиента и просмотр его с сервера
  2. Вставка документа из клиента в тест, другой клиент получил его правильно

Давайте создадим наше приложение Meteor

Нам нужно приложение Meteor для тестирования. Давайте создадим это.

  • создать приложение метеор с meteor create hello-laika
  • cd в hello-laika

Затем создайте файл с именем collections.js со следующим содержимым:

Posts = new Meteor.Collection('posts');

Это приложение доступно на GitHub .

папка tests

Все файлы тестов Laika должны находиться в папке tests в вашем приложении Meteor. tests — это специальная папка, в которой файлы в ней не будут включены ни в клиент, ни в сервер. Это правило самого Метеора.

Давайте напишем наш первый тест

Создайте файл с именем posts.js в нашей папке tests со следующим содержимым: (нет никаких ограничений для имени файла, вы можете назвать его как угодно ( .js ), как вам нравится)

 var assert = require('assert'); suite('Posts', function() { ltest('using both client and the server', function(done, server, client) { server.eval(function() { Posts.find().observe({ added: addedNewPost }); function addedNewPost(post) { emit('post', post); } }) server.once('post', function(post) { assert.equal(post.title, 'hello title'); done(); }); client.eval(function() { Posts.insert({title: 'hello title'}); }); }); }) 

Это написано в nodejs и все встроенные модули узлов могут использоваться в тестах. И если вы знакомы с написанием тестов с mocha , это все должно быть знакомо.

Здесь мы наблюдаем коллекцию Post для новых документов на сервере. И мы вставляем документ с помощью клиента, который вызвал наше наблюдение.

Давайте рассмотрим код.

  • В первой строке мы загружаем модуль nodejs assert для выполнения утверждений
  • Затем мы создаем набор тестов под названием «Должности»
  • внутри нашего набора мы можем создать наш тест (используя метод ltest ) с именем и обратным вызовом
  • в обратном вызове мы принимаем, что сервер и клиент использовались для оценки кода внутри сервера и клиента
  • server.eval() позволяет нам оценивать код внутри сервера
  • Вы можете отправить некоторые результаты обратно для тестирования с помощью server.once emit() и перехватить их с помощью server.once или server.on
  • client.eval() ведет себя таким же образом, но оценивает код внутри клиента
  • остальная часть кода говорит сама за себя

Запустить тест

После того, как вы создали тесты,

  • перейти в папку проекта
  • запустить лайку

Вы увидите что-то вроде ниже. Если вы получили ошибку, дважды проверьте ваш тестовый код.
лайка результат теста

Создайте наш второй тест

Создайте следующий тест внутри своего набора тестов.

 ltest('using two client', function(done, server, c1, c2) { c1.eval(function() { Posts.find().observe({ added: addedNewPost }); function addedNewPost(post) { emit('post', post); } emit('done'); }) c1.once('post', function(post) { assert.equal(post.title, 'from c2'); done(); }) c1.once('done', function() { c2.eval(insertPost); }); function insertPost() { Posts.insert({title: 'from c2'}); } }); 

Здесь мы наблюдаем коллекцию у одного клиента, а другие клиенты вставляют документ. Давайте рассмотрим это.

  • Теперь у нас есть 2 клиента (c1 и c2) вместо одного в предыдущем тесте
  • Вы можете указать любое количество клиентов, как указано выше, и laika может создать клиентов для вас
  • если вы посмотрите сначала на c1.eval() , то есть два c1.eval() .
  • мы можем emit() с сервера / клиента в любое время до теста
  • они могут быть .on() через .on() или .once()

Реальный вариант использования

Теперь вы видели, как использовать лайку. Но Лайка может сделать больше. Он может очень быстро протестировать функции, специфичные для метеоров. Некоторые из них:

  • Метеоритные методы
  • Публикации / Подписка
  • права доступа
  • Аутентификация
  • авторизация

Несколько примеров можно найти здесь — http://arunoda.github.io/laika/examples.html

Как Лайка работает внутри

Как разработчики, нам всегда интересно, как работают внутренние устройства. Итак, в этом разделе вы увидите, как работает Лайка.

Лайка делает изолированное тестирование

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

По этой причине ваши тесты будут работать немного медленнее.

Сервер и тестовая связь через TCP

В вашем тестовом примере вы можете просто оценить код Meteor внутри сервера, но внутренне Laika может выполнить для вас некоторую тяжелую работу. Когда вы начинаете тестирование, Laika внедряет некоторый серверный код в ваше приложение Meteor. Затем он запускает TCP-сервер и Laika подключается к нему.

Как только вы .eval() метод .eval() , Laika отправит его на сервер через TCP-соединение. Если какой-либо результат доступен (вызов .emit() на сервере), он также отправляет обратно на сервер через то же соединение.

Лайка очищает введенный код из вашего приложения в конце.

Клиент и сервер общаются через PhantomJS

Точно так же, как сервер, Лайка творит магию для вас под капотом. Для каждого клиента, которого вы запрашиваете, Laika создает клиента с использованием PhantomJS, и на нем будет оцениваться код. PhantomJS — это браузер webkit без пользовательского интерфейса, поэтому мы проводим реальное тестирование клиентов здесь.

Лайка использует мокко

Основная цель Laika — стать средой тестирования метеоров, ориентируясь на ее уникальные требования, а не создавать другую среду тестирования JavaScript. mocha — действительно хорошая и широко используемая среда тестирования JavaScript / NodeJS, и мы используем ее для внутреннего использования. Так что большинство опций, доступных в мокко, также доступно в лайке.

Смотрите параметры командной строки laika

Обработка ошибок

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

Лайка - Сообщение об ошибке

К сожалению, Laika не может показать вам, какой номер строки вызвал ошибку, но он покажет вам, в каком тесте она произошла, и контекст.

Синтаксис Сахар

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

Но если вы хотите отправить один результат и тест зависит от этого результата, стиль EventEmitter может быть головной болью. Иногда вы тоже попадаете в ад- колбэк.

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

Давайте посмотрим на это в действии

В стиле EventEmitter

 ltest('with eventEmitter style', function(done, server, client) { server.eval(function() { //assumes we do some real async work setTimeout(function() { emit('some-data', {data: 'data'}); }, 100); }); server.on('some-data', function(data) { client.eval(function(data) { //do something with the data emit('result', true); }, data); }); client.on('result', function(result) { assert.ok(result); done(); }); }); ### With .evalSync() synchronously ltest('wiht .evalSync()', function(done, server, client) { var data = server.evalSync(function() { setTimeout(function() { emit('return', {data: 'data'}); }, 100); }); var result = client.evalSync(function(data) { //do something with the data emit('return', true); }, data); assert.ok(result); done(); }) 

Вы можете увидеть разницу. Вы должны использовать специальный emit('return', {some: 'data'}) чтобы отправить выполнение обратно в тест. Также возможно использовать другие события emit() но они должны произойти после emit('return') .

Но .evalSync() работает только на основной тестовый обратный вызов

Это верно, evalSync() работает только внутри основного тестового обратного вызова. Если вы попытаетесь вызвать его из вложенного обратного вызова, он потерпит неудачу. Посмотрите на следующий пример, и он потерпит неудачу.

 ltest('failing .evalSync()', function(done, server, client) { server.eval(function() { emit('some-event'); }); server.on('some-event', function() { var result = client.evalSync(function() { emit('return', true); }); assert.ok(result, true); done(); }); }) 

Laika evalSync () внутри вложенного обратного вызова

Лайка — проект

Laika выпущена под лицензией OpenSource MIT, и вы можете использовать ее для любых целей. Это очень ценно, если вы можете упомянуть Лайку в блоге или в твиттере.

Проект размещен на github — Laika Testing Framework для Meteor .

Laika — это новый фреймворк, выпущенный в середине мая 2013 года. Он хорошо протестирован, но могут быть некоторые крайние случаи. Если у вас плохое время с Laika или есть что сказать, воспользуйтесь нашим трекером проблем на github или свяжитесь со мной через @arunoda .

Так. Чего же ты ждешь? Проверьте свой проект Meteor с Laika и отправьте его сегодня.