Test Driven Development with Meteor

Share this article

If you’ve followed the tech scene recently, Meteor won’t be anything new to you. We hear lots of good news about Meteor every week. If you haven’t  heard of it before, Meteor is a revolutionary JavaScript framework that allows you to create realtime single page web applications very quickly. It’s an OpenSource project, but unlike other projects, it has serious funding to keep up the rapid development.

Meteor is not a toy anymore

Although Meteor is still young, many people are keen to build high volume production apps with it. This is because it solves a real problem and allows developers to focus on the application logic rather than worrying about how to manage communications between the server and the client. Here, we’re talking about production quality applications, not prototypes anymore. So before we ship a single line of code, we need to test it. Unfortunately, Meteor doesn’t have an official testing framework – yet. But they do have a testing framework called tinytest, to test Meteor packages – but not the whole app.

What should a meteor testing framework look like?

When you are developing a Meteor application, you write both the server and client code together and they are tightly interconnected. So, we should be able to write test cases involving both the client and the server. Meteor is all about realtime and how we can share data between clients (browsers). So a testing framework should be capable of writing test cases involving multiple clients. And most of all, it should be fun.

Introducing Laika – a testing framework for meteor

Laika is a feature rich testing framework for meteor that satisfies all the above requirements. Laika is not the first, nor the only testing framework, but it is the easiest to use and well documented. Website: http://arunoda.github.io/laika/ With Laika, you can write tests targeting both the server and client. And it can work with multiple clients. Laika runs tests against your actual application, not with some mocks or stubs, so it makes your tests more accurate. Laika - Testing Framework for Meteor

Setting up the system

Laika does some magics behind the scene for you. So it needs some third party tools to be available on your system.
  • install nodejs – Laika runs on top of nodejs
  • install phantomjs – Laika uses phantomjs to create clients
  • install mongodb – Laika needs an external mongodb database for each test
Additionally,
  • you need to run mongodb while running the test
  • use this command to start mongodb with some optimizations for Laika
mongod --smallfiles --noprealloc --nojournal Finally, install Laika with sudo npm install -g laika.

Getting Started Guide

We’ll test a Meteor Collection in two scenarios.
  1. Inserting a document from a client and observe it from the server
  2. Inserting a document from a client an test another client got it correctly

Let’s create our Meteor app

We need a Meteor application to test. Let’s create it.
  • create a meteor app with meteor create hello-laika
  • cd into hello-laika
Then create a file named collections.js with the following content: Posts = new Meteor.Collection('posts'); This app is available on github.

tests folder

All the Laika tests files should reside under the tests folder in your Meteor app. tests is a special folder in that the files in it won’t be included in either client or server. This is a rule of Meteor itself.

Let’s write our first test

Create a file named posts.js
under our tests folder with the following content: (there is no restriction for the filename, you can name it whatever (.js) you like)
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'});
        });
      });
    })
This is written in nodejs and all the built-in node modules can be used in the tests. And if you are familiar with writing tests with mocha, this should all be familiar. Here, we are observing the Post collection for new documents in the server. And we insert a document using a client, which triggered our observation. Let’s review the code.
  • first line we are loading nodejs assert module to do assertions
  • then we create a test suite named ‘Posts’
  • inside our suite, we can create our test (using ltest method) with a name and a callback
  • in callback we accept server and client were used to evaluate code inside the server and client
  • server.eval() method allows us to evaluate code inside the server
  • you can send some results back to test with emit() and catch it with server.once or server.on
  • client.eval() behaves in the same way but evaluates the code inside the client
  • the rest of the code is self explanatory

Run the test

After you’ve created tests,
  • go to project folder
  • run Laika
You’ll see something like below. If you get an error, double check your test code. laika test result

Create our second test

Create the following test inside your test suite Posts.
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'});
      }
    });
Here, we are observing a collection in one client and another clients insert a document. Let’s review it.
  • Now we have 2 clients (c1 and c2) instead of one in the previous test
  • You can specify any number of clients as above and laika can create clients for you
  • if you look at first c1.eval(), there are two emit() calls.
  • we can emit() from the server/client any time to the test
  • they can be caught via .on() or .once()

Real life use case

Now you have seen how to use Laika. But Laika can do more. It can test Meteor-specific functionalities very quickly. Some of them are:
  • Meteor methods
  • Publications/Subscriptions
  • Permissions
  • Authentication
  • Authorization
A few examples can be found here – http://arunoda.github.io/laika/examples.html

How Laika works internally

As developers, we are always curious about how internals work. So in this section you’ll see how Laika works internally.

Laika does isolated testing

Laika runs a separate app with a clean db for each test you write. Each test is isolated from another so you don’t need to worry about cleaning states of your app and the database. For this reason, your tests will run bit slower.

Server and test communicate via TCP

In your test case, you can simply evaluate Meteor code inside the server, but internally Laika can do some hard work for you. When you start testing, Laika injects some server-side code into your Meteor app. Then it starts a TCP server and Laika connects to it. Once you call .eval() method, Laika will send it to the server via TCP connection. If any result available (calling .emit() in server), it also sends back to the server via the same connection. Laika cleans injected code from your app at the end.

Client and server communicate via PhantomJS

Just like the server, Laika does some magic for you under the hood. For every client you request, Laika creates a client using PhantomJS and code will be evaluated on it. PhantomJS is webkit browser without a UI, so we do real client testing here.

Laika uses mocha

Laika’s main goal is to be the testing framework for meteor targeting its unique requirements, not to create another JavaScript testing framework. mocha
is a really good and widely used JavaScript/NodeJS testing framework, and we use it internally. So most of the options available in mocha are also available in Laika. See laika command line options

Error Handling

Mistakes are common to human beings, so it is natural to write some tests with errors. It could be on the test itself or code targeted to evaluated on server or client. Laika does handle these errors and report back to you, so you can fix it right away. Laika - Error Reporting Unfortunately, Laika cannot show you which line number caused the error, but it will show you in which test it has occurred and the context.

Syntax Sugar

You’ve seen that Laika uses EventEmitter pattern (or something similar) to communicate between evaluated code and the test. This is really useful if you want to trigger multiple results from the evaluated code. But if you want to send a single result and test depend on that result, EventEmitter style could be a headache. Sometimes, you’ll end up in callback hell too. Laika knows the pain and it has the .evalSync() method which allows you to write synchronous code. .evalSync() is available on the both server and the client. This is possible due to each test being run inside a Fiber. Let’s see it in action

With EventEmitter style

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();
    })
You can see the difference. You must use special emit('return', {some: 'data'}) to send execution back to the test. It is also possible to use other emit() events but they must occur after emit('return').

But .evalSync() only works on the main test callback

That’s right, evalSync() only works inside the main test callback. If you try to invoke it from a nested callback, it gets failed. See the following example, and it gets failed.
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() inside a nested callback

Laika – the project

Laika is released under the OpenSource MIT license and you can use it for any purpose. It is highly appreciated if you can mention Laika in a blog post or in a tweet. The project is hosted on github – Laika Testing Framework for Meteor. Laika is a new framework – released in mid-May 2013. It is well-tested, but there could be some edge cases. If you have a bad time with Laika, or have something to say, use our issue tracker on github or contact me via @arunoda. So. What are you waiting for? Test your Meteor project with Laika and ship it today.

Frequently Asked Questions (FAQs) about Test-Driven Development with Meteor

What is the main advantage of using Meteor for test-driven development?

Meteor is a full-stack JavaScript platform that simplifies the process of building web and mobile applications. It provides real-time updates, meaning that changes made to the database are immediately reflected in the UI. This makes it an excellent choice for test-driven development (TDD), as it allows developers to write tests and see the results in real time. Furthermore, Meteor’s integrated build system and package manager make it easy to manage dependencies and build your application.

How does Meteor compare to other JavaScript frameworks for test-driven development?

Unlike many other JavaScript frameworks, Meteor is a full-stack solution, meaning it can handle everything from the database to the user interface. This makes it a one-stop-shop for developers, reducing the need for multiple tools and technologies. Additionally, Meteor’s real-time capabilities make it particularly well-suited to TDD, as developers can see the results of their tests in real time.

Can I use Meteor with other testing frameworks?

Yes, Meteor is compatible with a variety of testing frameworks. It comes with built-in support for Mocha, a popular JavaScript testing framework, but it can also be used with others like Jasmine or Jest. This flexibility allows developers to choose the testing framework that best suits their needs.

How does Meteor handle data synchronization in real-time applications?

Meteor uses a system called Distributed Data Protocol (DDP) to handle data synchronization. DDP uses WebSockets to establish a persistent connection between the client and the server, allowing for real-time updates. This means that any changes made to the database are immediately reflected in the UI, making Meteor an excellent choice for real-time applications.

What kind of applications can I build with Meteor?

Meteor is a versatile platform that can be used to build a wide range of applications. It’s particularly well-suited to real-time applications, such as chat apps, collaborative tools, and multiplayer games. However, it can also be used to build more traditional web and mobile applications.

How does Meteor support mobile app development?

Meteor comes with built-in support for Cordova, a platform that allows developers to build native mobile apps using HTML, CSS, and JavaScript. This means that you can use the same codebase to build both your web and mobile applications, significantly reducing development time and effort.

Is Meteor suitable for large-scale applications?

Yes, Meteor is capable of handling large-scale applications. It comes with built-in support for MongoDB, a scalable, high-performance database, and it uses a reactive programming model that makes it easy to manage complex data flows. However, like any technology, it’s important to understand its strengths and limitations and to architect your application appropriately.

How secure is Meteor?

Meteor takes security seriously. It comes with built-in protection against common web vulnerabilities like cross-site scripting (XSS) and cross-site request forgery (CSRF). It also provides a secure data layer that uses the publish-subscribe pattern to control what data is sent to the client.

What kind of support is available for Meteor developers?

Meteor has a strong and active community of developers who provide support through forums, blogs, and social media. There are also numerous tutorials, guides, and documentation available online. In addition, Meteor Development Group, the company behind Meteor, offers professional support and consulting services.

How can I get started with Meteor?

Getting started with Meteor is easy. You can download the Meteor command line tool from the official website and use it to create a new project. From there, you can start building your application using Meteor’s built-in tools and packages. There are also numerous tutorials and guides available online to help you get started.

Arunoda SusiripalaArunoda Susiripala
View Author

Arunoda Susiripala is a NodeJS Consultant who is well experienced in Server Side Technologies who is recently fell in love with Meteor.

laikameteor
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week