Rectangle 27 24

Integration Tests with Node and PhantomJS

In your question you were talking about the situation when you have both client-side tests and server-side tests running with mocks. I assume that for some reason you can't get both test sets running with the same mocks. Otherwise, if you changed the mocks on client-side your server-side tests would fail because they would get the broken mock data.

What you need are the integration tests so when you run some client-side code in your headless browser your server-side code would also run. Moreover, simply running your server-side and client-side code is not enough, you also want to be able to put assertions on both sides, don't you?

Most of the examples of integration tests that I found online either use Selenium or Zombie.js. The former is a big Java-based framework to drive real browsers while the later is a simple wrapper around jsdom. I assume you're hesitant to use either of those and would prefer PhantomJS. The tricky part, of course, is to get that running from your Node app. And I got just that.

Unfortunately, both projects seem abandoned by their authors and other community members fork them and adapt to their needs. That means that both projects got forked numerous times and all forks are barely running. The API is almost non-existent. I got my tests running with one of the phantom forks (Thank you, Seb Vincent). Here's a simple app:

'use strict';
var express = require('express');

var app = express();

app.APP = {}; // we'll use it to check the state of the server in our tests

app.configure(function () {
    app.use(express.static(__dirname + '/public'));
});

app.get('/user/:name', function (req, res) {
    var data = app.APP.data = {
        name: req.params.name,
        secret: req.query.secret
    };
    res.send(data);
});

module.exports = app;

    app.listen(3000);
})();

It listens for request to /user and returns path parameter name and query parameter secret. Here's the page where I call the server:

window.APP = {};

(function () {
    'use strict';

    var name = 'Alex', secret ='Secret';
    var xhr = new XMLHttpRequest();
    xhr.open('get', '/user/' + name + '?secret=' + secret);
    xhr.onload = function (e) {
        APP.result = JSON.parse(xhr.responseText);
    };
    xhr.send();
})();

And here's a simple test:

describe('Simple user lookup', function () {
    'use strict';

    var browser, server;

    before(function (done) {
        // get our browser and server up and running
        phantom.create(function (ph) {
            ph.createPage(function (tab) {
                browser = tab;
                server = require('../app');
                server.listen(3000, function () {
                    done();
                });
            });
        });
    });

    it('should return data back', function (done) {
        browser.open('http://localhost:3000/app.html', function (status) {

            setTimeout(function () {
                browser.evaluate(function inBrowser() {
                    // this will be executed on a client-side
                    return window.APP.result;
                }, function fromBrowser(result) {
                    // server-side asserts
                    expect(server.APP.data.name).to.equal('Alex');
                    expect(server.APP.data.secret).to.equal('Secret');
                    // client-side asserts
                    expect(result.name).to.equal('Alex');
                    expect(result.secret).to.equal('Secret');
                    done();
                });
            }, 1000); // give time for xhr to run

        });
    });
});

As you can see I have to poll the server inside the timeout. That's because all the phantom bindings are incomplete and too limiting. As you can see I'm able to check both client state and server state in a single test.

Run your tests with Mocha: mocha -t 2s You'll probably need to increase the default timeout setting for more evolved tests to run.

So, as you can see the whole thing is doable.

Hey, thanks! (1) I prefer PhantomJS because both Selenium and ZombieJS are slow (2) While APP is great for tests, the node server will be crushed in production from memory leaks. (3) It's also bad practice to add variables just so your code will be tested. (4) Looks great. As anticipated, it's buggy, hacky, slow and a lot of work. 'doable' is the keyword indeed :)

javascript - Full Integration Testing for NodeJS and the Client Side w...

javascript unit-testing node.js coffeescript gruntjs
Rectangle 27 70

Karma is not only for unit tests

UPDATE. Here is a simple package I've created to add minimal Karma setup to any project with one single command npm install min-karma.

I'd like to clarify some possible misconceptions about Karma and Protractor. Karma FAQ actually does refer to Adapter for Angular's Scenario Runner, which, however, seems to be abandoned, with Protractor being recommended instead.

These can be all your source files, some of them, some of them plus some additional files or files irrelevant to your project, only providing some extra configuration - you name it! You can have multiple karma config files for different purposes, which you can run in parallel or one-by-one. Each karma process launches its own set of browsers (these are currently available).

This feature of Karma to run only a set of files is what makes it perfect for fast tests running in background upon each source file edit, and get immediate feedback, which is brilliant! The only negative is the "noisy" error reporting that will hopefully improve!

Unit test is for a single unit of your source code. In Angular's case a typical unit is Angular Component (Service, Factory, Provider, Controller, Filter, Directive etc). Remember to keep your Controllers thin, so too many unit tests for latters is a red flag.

In a unit test, every other units of code, on which this unit depends (so-called unit's dependencies) should not be tested at the same time. Instead they should be "mocked", e.g. replaced by something simple like dummy instances. Angular provides great mock environment support. Ideally you want to see all those mocks directly inside your tests, so you never need to wonder where all those dependencies come from.

Karma is just as useful for Integration Tests, where a group of source code units is tested together, with only some of their dependencies being mocked. It is important to remember that any dependency is by default provided from your source code modules (as long as those modules either injected directly in your tests, or they are dependencies of other modules injected (in which case you don't need to inject them, but no harm to do so). The mocked dependencies will override the provided ones.

Running Fast and Frequent is the main feature of Karma. This means you want to avoid any server requests, any database queries, anything that can take longer than fractions of seconds. (Otherwise it will NOT be fast!) Those long processes are ones you want to mock. This also explains why it is a bad practice to put raw low level services like $http directly inside your controllers or any complicated business logic units. By wrapping those low level outside communication services into smaller dedicated services, you make it much easier to "mock them away".

What Karma does not do is running your site as it is, which is what End-to-End (E2E) testing is. In principle, you could use Angular's internal methods to recreate the site or its pieces. Which, for small pieces, can be useful, and a fast way e.g. to test directives.

It is, however, not recommended way to throw complicated code inside your tests. The more you do it, the more chance is that you make errors in that code instead of what you are actually testing.

That is why I personally dislike the often mentioned complicated way of testing methods using low level methods like $http. It works cleaner to isolate any reference to low level methods into dedicated methods of your own, whose single responsibility is to make http requests. These dedicated methods should be able to work with real backend, not a fake one! Which you can easily test - manually or even perfectly fine with Karma running with another special config, as long as you don't mix that config with the one usually used to run Karma regular and fast. Now, having your dedicated small services tested, you can safely and easily mock them to test your other logic and put these tests into your regular Karma setup.

To summarize. Use Karma to run any set of JavaScript files. It is (should be) fast. You don't see your complete app, so can't test the final result effectively and reliably. Would I run it with Protractor? Why would I? Running Protractor would slow down my tests, defeating the purpose of Karma. It is easy to run Protractor separately.

an end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

So Protractor does exactly what Karma doesn't - run your real final application. This reveals its both power and limitations:

Running complete application is the only reliable final test that your application works as expected. You can write up complete user story scenarios and put them into your tests!

But it is harder to track errors without isolating individual units of your source code. This is why you still need Karma to test your JavaScript code first.

Now would I want to run Protractor with Karma? I surely can run them in separate terminal windows, in parallel. I could, in principle, have them share test files if I need to, but normally I'd rather not. Why? Because I want to keep my tests small with single dedicated purpose.

The only exception would be a file defining testing macros useful for both runners. This, however, would not be a test file but a macro definition file.

Other than that, I like a clear separation between my tests. Those to be run frequently and fast, and those for the complete app. That makes a clear separation between when using Karma and when Protractor.

If I want unit testing as well as e2e testing then i have to configure karma environment for unit testing and protractor for ui testing or e2e testing ?

@SunilGarg Yes, if want to use both, but as I wrote, Karma is not only for unit testing.

javascript - Can Protractor and Karma be used together? - Stack Overfl...

javascript angularjs testing protractor karma-runner
Rectangle 27 33

I created an open source project called Chutzpah which is a test runner for JavaScript unit tests. Chutzpah enables you to run JavaScript unit tests from the command line and from inside of Visual Studio. It also supports running in the TeamCity continuous integration server.

I just started using Chutzpah to run Jasmine tests inside visual studio - it's nicely integrated: right click in the test file and chose 'run js tests' or 'run JS tests in browser'. I run the same jasmine tests using JSTestDriver. I prefer Chutzpah because I specify which files I depend upon being loaded at the top of the test file. For JSTestDriver I need a separate config file.

JavaScript unit test tools for TDD - Stack Overflow

javascript unit-testing tdd
Rectangle 27 33

I created an open source project called Chutzpah which is a test runner for JavaScript unit tests. Chutzpah enables you to run JavaScript unit tests from the command line and from inside of Visual Studio. It also supports running in the TeamCity continuous integration server.

I just started using Chutzpah to run Jasmine tests inside visual studio - it's nicely integrated: right click in the test file and chose 'run js tests' or 'run JS tests in browser'. I run the same jasmine tests using JSTestDriver. I prefer Chutzpah because I specify which files I depend upon being loaded at the top of the test file. For JSTestDriver I need a separate config file.

JavaScript unit test tools for TDD - Stack Overflow

javascript unit-testing tdd
Rectangle 27 2

This will mock what you'd get from requiring text!foo/x.html. Plugins are not special, you just need to mock the entire path, including the plugin name.

var requirejs = require("requirejs");
var assert = require("assert");

requirejs.config({
    baseUrl: __dirname,
    packages: [
        {
            name: "squire",
            location: "node_modules/squirejs",
            main: "src/Squire"
        }
    ]
});

var x;
before(function (done) {
    requirejs(["squire"], function (Squire) {
        var injector = new Squire();

        injector.mock("text!foo/x.html", "foo").require(["text!foo/x.html"],
                                                   function (_x) {
            x = _x;
            done();
        });
    });
});

it("foo", function () {
    assert.equal(x, "foo");
});

The problem you run into with the example code you added to your question is that you use the global require instead of using a require passed by your loader. You should add require as a dependency:

define(['require', ....], function (require, ....) {

The require module is special and reserved by RequireJS. It returns a reference to the require function. You must use it, for instance, when you use RequireJS's contexts so that a module loaded in a specific context uses a require function that is bound to that context. SquireJS also needs you to do this so that it can trap your calls to require. The global require bypasses SquireJS.

Tried that, not working since the plugin is used with require() and not define(). Please see this example fiddle: runnable.com/VUBoI0ex6v9Gs-BJ/

Take a look at the runnable I posted. Your code works perfectly of course, but the use-case I have is slightly different. The runnable shows the difference.

You, my friend, are awesome! Thanks a million, I completely missed the part about passing require in RequireJs docs

javascript - How can I mock RequireJs loader plugin responses in unit ...

javascript unit-testing mocking requirejs squirejs
Rectangle 27 8

There are a number of issues preventing your tests from passing.

Accordion.toggle in your test is a property of the Accordion class, and this.toggle in your code is a property of a instance of the Accordion class - so in this case you are comparing two different things. To access the 'instance' method in your test you could replace Accordion.toggle with Accordion.prototype.toggle. Which would work if it were not for this.toggle = this.toggle.bind(this); in your constructor. Which leads us to the second point.

When you call .bind() on a function it creates a new function at runtime - so you can't compare it to the original Accordion.prototype.toggle. The only way to work around this is to pull the "bound" function out of the result from render:

let toggle = result.props.children[0].props.onClick;

assert.deepEqual(result.props.children, [
  <a onClick={toggle}>This is a summary</a>,
  <p style={{display: 'none'}}>This is some details</p>
]);
result.props.onClick()
result.props.children[0].props.onClick();

There is a bug in React that requires a global "document" variable to be declared when calling setState with shallow rendering - how to work around this in every circumstance is beyond the scope of this question, but a quick work around to get your tests passing is to add global.document = {}; right before you call the onClick method. In other words where your original test had:

result.props.onClick();
global.document = {};
result.props.children[0].props.onClick();

See the section "Fixing Broken setState()" on this page and this react issue.

javascript - React Testing: Event handlers in React Shallow Rendering ...

javascript unit-testing testing reactjs mocha
Rectangle 27 8

Works for me with the following settings.

// package.json

"jest": {
  "scriptPreprocessor": "preprocessor.js",
  "unmockedModulePathPatterns": [
    "react"
  ],
  "setupEnvScriptFile": "before_test.js"
}

// preprocessor.js

var ReactTools = require('react-tools');

module.exports = {
    process: function(src) {
        return ReactTools.transform(src);
    }
};

// before_test.js

React = require("react"); // Global React object

Thanks a bunch!

I found that I had to clear the haste cache to get this to work. rm -rf node_modules/.haste_cache

The setupEnvScriptFile configuration option has been deprecated for a while. Jest 15 removes it completely and replaces it with setupFiles. This option expects an array of file paths that are loaded in order before a test file is executed. facebook.github.io/jest/blog/2016/09/01/

javascript - Jest/React - How to use global object in unit tests? - St...

javascript unit-testing reactjs jestjs
Rectangle 27 3

mocks is just a folder to put your code in to keep your project organized and the code in tests short and to the point. By keeping all your mocks in one place, it is easier to reuse them in tests... copying them from one test to another would be bad practice from a DRY perspective.

So, for example, you might have a service called 'Foo'

app/service/foo.js

Then you might create a mock of that service, called 'FooMock'

test/mocks/service/foo.js

And then you would create tests and inject whatever mocks you need, as is shown in gerasulus's answer.

javascript - using the mock folder for karma test in yeoman angularjs ...

javascript unit-testing angularjs yeoman karma-runner
Rectangle 27 26

1 - Don't mock the service and use $httpBackend to setup expectations ...

As someone had mentioned in a deleted answer, success and error are syntactic sugar added by $http so they aren't there when you create your own promise. You have two options:

The idea is to let your myService act like it normally would without knowing it's being tested. $httpBackend will let you set up expectations and responses, and flush them so you can complete your tests synchronously. $http won't be any wiser and the promise it returns will look and function like a real one. This option is good if you have simple tests with few HTTP expectations.

If the thing you're testing has complicated dependencies and all the set-up is a headache, you may still want to mock the services and the calls themselves as you have attempted. The difference is that you'll want to fully mock promise. The downside of this can be creating all the possible mock promises, however you could make that easier by creating your own function for creating these objects.

The reason this works is because we pretend that it resolves by invoking the handlers provided by success, error, or then immediately, causing it to complete synchronously.

'use strict';

describe('SimpleControllerTests', function () {

    var scope;
    var expectedResponse = { name: 'this is a mocked response' };
    var $controller, _mockMyService, _mockPromise = null;

    beforeEach(module('myApp'));

    beforeEach(inject(function(_$rootScope_, _$controller_){ 
        $controller = _$controller_;
        scope = _$rootScope_;

        _mockMyService = {
            get: function() {
               return _mockPromise;
            }
        };
    }));

    describe('should load data successfully', function() {

        beforeEach(function() {

          _mockPromise = {
             then: function(successFn) {
               successFn(expectedResponse);
             },
             success: function(fn) {
               fn(expectedResponse);
             }
          };

           $controller('SimpleController', { $scope: scope, myService: _mockMyService });
        });

        it('using loadData()', function() {
          scope.loadData();
          expect(scope.data).toEqual(expectedResponse);
        });

        it('using loadData2()', function () {
          scope.loadData2();
          expect(scope.data).toEqual(expectedResponse);
        });
    });

    describe('should fail to load data', function() {
        beforeEach(function() {
          _mockPromise = {
            then: function(successFn, errorFn) {
              errorFn();
            },
            error: function(fn) {
              fn();
            }
          };

          $controller('SimpleController', { $scope: scope, myService: _mockMyService });
        });

        it('using loadData()', function() {
          scope.loadData();
          expect(scope.error).toEqual("ERROR");
        });

        it('using loadData2()', function () {
          scope.loadData2();
          expect(scope.error).toEqual("ERROR");
        });
    });           
});

I rarely go for option 2, even in big applications.

For what it's worth, your loadData and loadData2 http handlers have an error. They reference response.data but the handlers will be called with the parsed response data directly, not the response object (so it should be data instead of response.data).

Thanks for the answer, how would I test the error condition though? I'm starting to think using success and error explicitly outside the controller is really a bad idea. I'm thinking the controller code should be then(function(..success code here..), function(..error code here...) . Then I can simulate success \ error from the test using resolve() and reject() on the promise..

That's why option #2 sucks. If you want an error condition, move the $httpBackend setup and controller init into the body of the fact, or put it in it's own describe block that has the varied beforeEach. I'll update my example with success and fail.

OK, updated. Sorry if there are typos or small errors, I had to rush because a meeting just got called :p

Thanks a lot for the detailed answer, this really got me thinking and I've decided that success and error have no place in my controller. Points to you though, you provided a perfectly workable solution. That dependency on the actual service implementation is something I'd rather avoid. Maybe I'm being too idealistic :)

At the end of the day, whatever you're comfortable with. But the way I've always looked at it, when dealing with external data, I'm testing a controller I want to make sure it's calling the service(s) to load or submit the data using the correct parameters when it's supposed to, and it's doing the right thing with the potential responses. Doing so by controlling it in one simple spot, $httpBackend, is the closest to the real thing while remaining practical and easy to implement in my tests. Again, it depends on what the service does, but truly and necessarily complicated services are rare.

javascript - Test a controller with success() and error () - Stack Ove...

javascript angularjs unit-testing jasmine
Rectangle 27 2

https://github.com/facebook/react/blob/3dc10749080a460e48bee46d769763ec7191ac76/src/test/phantomjs-shims.js
karma.config.js
files
'scripts/phantomjs-shims.js',

javascript - React components not works in RequireJS+Jasmine unit test...

javascript unit-testing reactjs requirejs karma-jasmine
Rectangle 27 155

I'm not sure why the way you did it doesn't work, but I usually do it with the spyOn function. Something like this:

describe('Testing remote call returning promise', function() {
  var myService;

  beforeEach(module('app.myService'));

  beforeEach(inject( function(_myService_, myOtherService, $q){
    myService = _myService_;
    spyOn(myOtherService, "makeRemoteCallReturningPromise").and.callFake(function() {
        var deferred = $q.defer();
        deferred.resolve('Remote call result');
        return deferred.promise;
    });
  }

  it('can do remote call', inject(function() {
    myService.makeRemoteCall()
      .then(function() {
        console.log('Success');
      });    
  }));

Also remember that you will need to make a $digest call for the then function to be called. See the Testing section of the $q documentation.

After looking closer at what you're doing, I think I see the problem in your code. In the beforeEach, you're setting myOtherServiceMock to a whole new object. The $provide will never see this reference. You just need to update the existing reference:

beforeEach(inject( function(_myService_, $q){
    myService = _myService_;
    myOtherServiceMock.makeRemoteCallReturningPromise = function() {
        var deferred = $q.defer();
        deferred.resolve('Remote call result');
        return deferred.promise;   
    };
  }

And you killed me yesterday by not showing up in results. Beautiful display of andCallFake(). Thank you.

andCallFake
andReturnValue(deferred.promise)
and.returnValue(deferred.promise)
deferred
spyOn

How would you call $digest in this case when you don't have access to the scope?

@JimAho Typically you just inject $rootScope and call $digest on that.

@dnc253 Yes thanks! I just found that out on this page: docs.angularjs.org/api/ng/service/$q. I totally had missed the integration of $q with the angular scoping mechanisms.

javascript - How do I mock a service that returns promise in Angularjs...

javascript angularjs unit-testing mocking jasmine
Rectangle 27 1426

Karma is a JavaScript test-runner built with Node.js and meant for unit testing.

The Protractor is for end-to-end testing and uses Selenium Web Driver to drive tests.

Both have been made by the Angular team. You can use any assertion-library you want with either.

  • Option to run server/clients on development computer or separately

A JavaScript test-runner built with Node.js. Very modular and flexible. It comes with its own assertion library, but you can add your own if you like. The assertions library is decoupled, so you can also use it with other test-runners. Instead of using assert(!...) or expect(...).not..., it uses refute(...) which is a nice twist imho.

A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), qunit style static HTML page testing, testing in headless browsers (phantomjs, jsdom, ...), and more. Take a look at the overview!

A Node.js testing toolkit. You get the same test case library, assertion library, etc. This is also great for hybrid browser and Node.js code. Write your test case with Buster.JS and run it both in Node.js and in a real browser.

  • Run tests from browser or headless with PhantomJS (soon)
  • Run tests from command line (can be integrated into ant/maven)
  • Write tests xUnit or BDD style
  • Defer tests instead of commenting them out
  • SinonJS built in
  • Reporters (xunit XML, traditional dots, specification, tap, teamcity and more built in)
  • Customize/replace the HTML that is used to run the browser-tests
  • Stil in beta so can be buggy
  • Doesn't group results by os/browser/version like TestSwarm *. It does, however, print out the browser name and version in the test results.
  • No history of previous test results like TestSwarm *
  • Doesn't fully work on windows as of May 2014

* TestSwarm is also a Continuous Integration server, while you need a separate CI server for Buster.js. It does, however, output xUnit XML reports, so it should be easy to integrate with Hudson, Bamboo or other CI servers.

TestSwarm is officially no longer under active development as stated on their GitHub webpage. They recommend Karma, browserstack-runner, or Intern.

The website www.browserswarm.com is dead and there are no recent search results for BrowserSwarm. It appears to have died.

This is a client-side test-runner that might interest developers familiar with Ruby or Ruby on Rails. The syntax is based on RSpec that's used for testing in Rails projects.

Jasmine is a behavior-driven development framework for testing your JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM.

If you have experience with this test-runner, please contribute with more info :)

QUnit focuses on testing JavaScript in the browser while providing as much convenience to the developer as possible. Blurb from the site:

QUnit is a powerful, easy-to-use JavaScript unit test suite. It's used by the jQuery, jQuery UI and jQuery Mobile projects and is capable of testing any generic JavaScript code

QUnit was originally developed by John Resig as part of jQuery. In 2008 it got its own home, name and API documentation, allowing others to use it for their unit testing as well. At the time it still depended on jQuery. A rewrite in 2009 fixed that, now QUnit runs completely standalone. QUnit's assertion methods follow the CommonJS Unit Testing specification, which was to some degree influenced by QUnit.

Another great tool is sinon.js by Christian Johansen, the author of Test-Driven JavaScript Development. Best described by himself:

Standalone test spies, stubs and mocks for JavaScript. No dependencies works with any unit testing framework.

The Intern Web site provides a direct feature comparison to the other testing frameworks on this list. It offers more features out of the box than any other JavaScript-based testing system.

I'm totally unqualified to comment on mocha.js's features, strengths, and weaknesses, but it was just recommended to me by someone I trust in the JS community.

List of features, as reported by its web site:

  • auto-detects and disables coloring for non-ttys
  • optionally run tests that match a regexp
  • auto-exit to prevent "hanging" with an active loop

Yolpo is a tool to visualize the execution of javascript. Javascript API developers are encouraged to write their use cases to show and tell their api. Such use cases forms the basis of regression tests.

Futuristic test runner with built-in support for ES2015. Even though JavaScript is single-threaded, IO in Node.js can happen in parallel due to its async nature. AVA takes advantage of this and runs your tests concurrently, which is especially beneficial for IO heavy tests. In addition, test files are run in parallel as separate processes, giving you even better performance and an isolated environment for each test file.

  • Minimal and fast
  • Write your tests in ES2015

Jasmine can work headless using V8, but you can also use it interactively. While the DOM is not necessary with respect to Jasmine, your codebase might access DOM. With discipline it is possible to eliminate, guard with conditions, or provide mocks for parts of the code that access the DOM and run tests completely apart from HTML fixtures. You can also get command-line support and fixtures using add-ons.

@rehevkor5: Selenium is for integration testing, while the tools here are for unit testing. typemock.com/unit-tests-integration-tests

Almost every single test runner relies on a browser. Wtf, doesn't anyone ever run unit tests only on the server-side????

@Raisen You can plug ES 2015 into most of them with Babel, but AVA by Sindre Sorhus has it built in.

JavaScript unit test tools for TDD - Stack Overflow

javascript unit-testing tdd
Rectangle 27 1423

Karma is a JavaScript test-runner built with Node.js and meant for unit testing.

The Protractor is for end-to-end testing and uses Selenium Web Driver to drive tests.

Both have been made by the Angular team. You can use any assertion-library you want with either.

  • Option to run server/clients on development computer or separately

A JavaScript test-runner built with Node.js. Very modular and flexible. It comes with its own assertion library, but you can add your own if you like. The assertions library is decoupled, so you can also use it with other test-runners. Instead of using assert(!...) or expect(...).not..., it uses refute(...) which is a nice twist imho.

A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), qunit style static HTML page testing, testing in headless browsers (phantomjs, jsdom, ...), and more. Take a look at the overview!

A Node.js testing toolkit. You get the same test case library, assertion library, etc. This is also great for hybrid browser and Node.js code. Write your test case with Buster.JS and run it both in Node.js and in a real browser.

  • Run tests from browser or headless with PhantomJS (soon)
  • Run tests from command line (can be integrated into ant/maven)
  • Write tests xUnit or BDD style
  • Defer tests instead of commenting them out
  • SinonJS built in
  • Reporters (xunit XML, traditional dots, specification, tap, teamcity and more built in)
  • Customize/replace the HTML that is used to run the browser-tests
  • Stil in beta so can be buggy
  • Doesn't group results by os/browser/version like TestSwarm *. It does, however, print out the browser name and version in the test results.
  • No history of previous test results like TestSwarm *
  • Doesn't fully work on windows as of May 2014

* TestSwarm is also a Continuous Integration server, while you need a separate CI server for Buster.js. It does, however, output xUnit XML reports, so it should be easy to integrate with Hudson, Bamboo or other CI servers.

TestSwarm is officially no longer under active development as stated on their GitHub webpage. They recommend Karma, browserstack-runner, or Intern.

The website www.browserswarm.com is dead and there are no recent search results for BrowserSwarm. It appears to have died.

This is a client-side test-runner that might interest developers familiar with Ruby or Ruby on Rails. The syntax is based on RSpec that's used for testing in Rails projects.

Jasmine is a behavior-driven development framework for testing your JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM.

If you have experience with this test-runner, please contribute with more info :)

QUnit focuses on testing JavaScript in the browser while providing as much convenience to the developer as possible. Blurb from the site:

QUnit is a powerful, easy-to-use JavaScript unit test suite. It's used by the jQuery, jQuery UI and jQuery Mobile projects and is capable of testing any generic JavaScript code

QUnit was originally developed by John Resig as part of jQuery. In 2008 it got its own home, name and API documentation, allowing others to use it for their unit testing as well. At the time it still depended on jQuery. A rewrite in 2009 fixed that, now QUnit runs completely standalone. QUnit's assertion methods follow the CommonJS Unit Testing specification, which was to some degree influenced by QUnit.

Another great tool is sinon.js by Christian Johansen, the author of Test-Driven JavaScript Development. Best described by himself:

Standalone test spies, stubs and mocks for JavaScript. No dependencies works with any unit testing framework.

The Intern Web site provides a direct feature comparison to the other testing frameworks on this list. It offers more features out of the box than any other JavaScript-based testing system.

I'm totally unqualified to comment on mocha.js's features, strengths, and weaknesses, but it was just recommended to me by someone I trust in the JS community.

List of features, as reported by its web site:

  • auto-detects and disables coloring for non-ttys
  • optionally run tests that match a regexp
  • auto-exit to prevent "hanging" with an active loop

Yolpo is a tool to visualize the execution of javascript. Javascript API developers are encouraged to write their use cases to show and tell their api. Such use cases forms the basis of regression tests.

Futuristic test runner with built-in support for ES2015. Even though JavaScript is single-threaded, IO in Node.js can happen in parallel due to its async nature. AVA takes advantage of this and runs your tests concurrently, which is especially beneficial for IO heavy tests. In addition, test files are run in parallel as separate processes, giving you even better performance and an isolated environment for each test file.

  • Minimal and fast
  • Write your tests in ES2015

Jasmine can work headless using V8, but you can also use it interactively. While the DOM is not necessary with respect to Jasmine, your codebase might access DOM. With discipline it is possible to eliminate, guard with conditions, or provide mocks for parts of the code that access the DOM and run tests completely apart from HTML fixtures. You can also get command-line support and fixtures using add-ons.

@rehevkor5: Selenium is for integration testing, while the tools here are for unit testing. typemock.com/unit-tests-integration-tests

Almost every single test runner relies on a browser. Wtf, doesn't anyone ever run unit tests only on the server-side????

@Raisen You can plug ES 2015 into most of them with Babel, but AVA by Sindre Sorhus has it built in.

JavaScript unit test tools for TDD - Stack Overflow

javascript unit-testing tdd
Rectangle 27 1

What you have currently written are integration tests which test the interaction between your node server and mongo db database. Although these tests are more time consuming then mocked unit tests they actually provide far more value. Running queries against a stable MongoDB instance is ensures that your queries are running as planned and that your application is responding properly to the results see: How to unit test a method which connects to mongo, without actually connecting to mongo?.

If you wish to test the javascript functions that manipulate the data as opposed to interaction between the server and db. I would suggest that you refactor out this code from the mongodb query logic and unit test it. Alternatively as you are using a class you should be able to overwrite the _db property with a mock db library. Which would just be an object with methods that mimic that of the mongo library you are currently using. Or you could use sinon to stub out those methods and replace them with methods that return a know result see http://sinonjs.org/releases/v1.17.7/stubs/.

var ensureIndex = { ensureIndex: sinon.stub() }
sinon.stub(db, 'collection').returns(ensureIndex)

var blackList; 

describe('Model: Blacklist', () => {

  beforeEach(() => {
    var blackList = new BlacklistModel(db, id, logger);
  })
  it('test' => { 
    blackList.create(data).then(() => {
      // some test here
      db.collection.calledWithMatch('some match')
    })

  })
})

I'm still very confused how to use sinon to stub those methods. Could you write an example for me according to these above codes?

Just wrote an update that you could try

javascript - node.js - Apply sinon on mongodb unit tests - Stack Overf...

javascript node.js mongodb unit-testing sinon
Rectangle 27 2

Marcin Grzywaczewski wrote a great article with a workaround for testing a click handler that works with shallow rendering.

Given a nested element with an onClick prop and a handler with context bound to the component:

render() {
  return (
    <div>
      <a className="link" href="#" onClick={this.handleClick}>
        {this.state.linkText}
      </a>
      <div>extra child to make props.children an array</div>
    </div>
  );
}

handleClick(e) {
  e.preventDefault();
  this.setState({ linkText: 'clicked' });
}

You can manually invoke the function value of the onClick prop, stubbing in the event object:

it('updates link text on click', () => {
  let tree, link, linkText;

  const renderer = TestUtils.createRenderer();
  renderer.render(<MyComponent />);

  tree = renderer.getRenderOutput();
  link = tree.props.children[0];
  linkText = link.props.children;

  // initial state set in constructor
  expect(linkText).to.equal('Click Me');

  // manually invoke onClick handler via props
  link.props.onClick({ preventDefault: () => {} });

  tree = renderer.getRenderOutput();
  link = tree.props.children[0];
  linkText = link.props.children;

  expect(linkText).to.equal('Clicked');
});

javascript - React Testing: Event handlers in React Shallow Rendering ...

javascript unit-testing testing reactjs mocha
Rectangle 27 65

I was using Expresso originally but the fact that it runs tests in parallel caused a few problems. (For example using database fixtures doesn't work well in this situation).

Expresso doesn't force you to run tests in parallel. Feed it the --serial argument and it'll run them all in merry order.

Just downloaded and used nodeunit... does exactly what it says, worked first time ftw!

Nodeunit is a bit strange with requiring every test to call .done() imho.

If I was starting a new project now I'd probably use Mocha as the test framework

Nodeunit requires .done() to accommodate asynchronous testing. I agree it can be a little unwieldy at times, but it has a mighty fine reason for doing it this way.

javascript - Node.js Unit Testing - Stack Overflow

javascript unit-testing node.js
Rectangle 27 64

We can also write jasmine's implementation of returning promise directly by spy.

spyOn(myOtherService, "makeRemoteCallReturningPromise").and.returnValue($q.when({}));

Note to people using Jasmine 2.0, .andReturn() has been replaced by .and.returnValue. So the above example would be: spyOn(myOtherService, "makeRemoteCallReturningPromise").and.returnValue($q.when({})); I just killed a half hour figuring that out.

javascript - How do I mock a service that returns promise in Angularjs...

javascript angularjs unit-testing mocking jasmine
Rectangle 27 98

I've started employing the import * as obj style within my tests, which imports all exports from a module as properties of an object which can then be mocked. I find this to be a lot cleaner than using something like rewire or proxyquire or any similar technique. I've done this most often when needing to mock Redux actions, for example. Here's what I might use for your example above:

import * as network from 'network.js';

describe("widget", function() {
  it("should do stuff", function() {
    let getDataFromServer = spyOn(network, "getDataFromServer").andReturn("mockData")
    let widget = new Widget();
    expect(getDataFromServer).toHaveBeenCalledWith("dataForWidget");
    expect(otherStuff).toHaveHappened();
  });
});
import * as network from './network'
{default: getDataFromServer}

Do you use the import * as obj only in the test or also in your regular code?

I usually use this pattern only in my test- in my app code, I usually use import { thing1, thing2 } from 'thinglib';.

@carpeliam This wont work with the ES6 module spec where the imports are readonly.

Jasmine is complaining [method_name] is not declared writable or has no setter which makes sense since es6 imports are constant. Is there a way to workaround?

@Francisc import (unlike require, which can go anywhere) gets hoisted, so you cant technically import multiple times. Sounds like your spy is being called elsewhere? In order to keep the tests from messing up state (known as test pollution), you can reset your spies in an afterEach (e.g. sinon.sandbox). Jasmine I believe does this automatically.

javascript - How to mock the imports of an ES6 module? - Stack Overflo...

javascript unit-testing mocha ecmascript-6
Rectangle 27 4

Originally made for node.js, deadunit is a javascript unit testing library for node.js and the browser. Some of its unique attributes:

  • Can output test results on the command line (colored or plain-text) or as html
  • It prints out the actual lines of code where your assertions are, so your output makes sense even if you don't spend a lot of time writing test commentary
  • It has a simple count assertion that makes dealing with expected exceptions and asynchronous asserts easy
  • it prints out exception and any attached data they have
  • it'll let you know if your code is hanging (something you don't want, but usually goes unnoticed)
  • Has an event driven API enables streaming test results across a network, or in any way you want.
  • Supports testing with node-fibers

javascript - Node.js Unit Testing - Stack Overflow

javascript unit-testing node.js
Rectangle 27 4

(NOTE: On the 4th and 6th line the function returns resolve and reject...

Using $httpBackend inside a controller is a bad Idea since you are mixing concerns inside your Test. Whether you retrieve data from an Endpoint or not is not a concern of the Controller, is a concern of the DataService you are calling.

You can see this more clearly if you change the Endpoint Url inside the service you will then have to modify both tests: the service Test and the Controller Test.

Also as previously mentioned, the use of success and error are syntactic sugar and we should stick to the use of then and catch. But in reality you may find yourself in the need of testing "legacy" code. So for that I'm using this function:

function generatePromiseMock(resolve, reject) {
    var promise;
    if(resolve) {
        promise = q.when({data: resolve});
    } else if (reject){
        promise = q.reject({data: reject});
    } else {
        throw new Error('You need to provide an argument');
    }
    promise.success = function(fn){
        return q.when(fn(resolve));
    };
    promise.error = function(fn) {
        return q.when(fn(reject));
    };
    return promise;
}

By calling this function you will get a true promise that respond to then and catch methods when you need to and will also work for the success or error callbacks. Note that the success and error returns a promise itself so it will work with chained then methods.

A little late to the party but I wanted to share my solution for this. Feel free to disagree with me :)

javascript - Test a controller with success() and error () - Stack Ove...

javascript angularjs unit-testing jasmine