17 private links
HTTP assertions made easy via superagent.
The motivation with this module is to provide a high-level abstraction for testing HTTP, while still allowing you to drop down to the lower-level API provided by superagent.
This guide is intended to catch you up with the most important reasoning, terms, tools, and approaches to JavaScript testing in 2018.
HTTPie—aitch-tee-tee-pie—is a command line HTTP client with an intuitive UI, JSON support, syntax highlighting, wget-like downloads, plugins, and more.
HTTPie consists of a single http command designed for painless debugging and interaction with HTTP servers, RESTful APIs, and web services:
- Sensible defaults
- Expressive and intuitive command syntax
- Colorized and formatted terminal output
- Built-in JSON support
- Persistent sessions
- Forms and file uploads
- HTTPS, proxies, and authentication support
- Support for arbitrary request data and headers
- Wget-like downloads
- Extensions
- Linux, macOS, and Windows support
Dev-test pipeline automation, 100,000+ free apps, public and private registries
As others have recommended in comments, it looks like the canonical way to test Express controllers is through supertest.
An example test might look like this:
describe('GET /users', function(){
it('respond with json', function(done){
request(app)
.get('/users')
.set('Accept', 'application/json')
.expect(200)
.end(function(err, res){
if (err) return done(err);
done()
});
})
});
Upside: you can test your entire stack in one go.
Downside: it feels and acts a bit like integration testing.
A Test-Anything-Protocol library for Node.js
We’ve all been there: that bit of JavaScript functionality that started out as just a handful of lines grows to a dozen, then two dozen, then more. Along the way, a function picks up a few more arguments; a conditional picks up a few more conditions. And then one day, the bug report comes in: something’s broken, and it’s up to us to untangle the mess.
Use promises
The Promise API is a new feature of ECMAScript 6, but it has good browser support already. There are also many libraries which implement the standard Promises API and provide additional methods to ease the use and composition of asynchronous functions (e.g. bluebird).
Promises are containers for future values. When the promise receives the value (it is resolved) or when it is cancelled (rejected), it notifies all of its "listeners" who want to access this value.
The advantage over plain callbacks is that they allow you do decouple your code and they are easier to compose.
Here is a simple example of using a promise:
function delay() {
// `delay` returns a promise
return new Promise(function(resolve, reject) {
// Only `delay` is able to resolve or reject the promise
setTimeout(function() {
resolve(42); // After 3 seconds, resolve the promise with value 42
}, 3000);
});
}
delay().then(function(v) { // `delay` returns a promise
console.log(v); // Log the value once it is resolved
}).catch(function(v) {
// Or do something else if it is rejected
// (it would not happen in this example, since `reject` is not called).
});
Applied to our Ajax call we could use promises like this:
function ajax(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(this.responseText);
};
xhr.onerror = reject;
xhr.open('GET', url);
xhr.send();
});
}
ajax("/echo/json").then(function(result) {
// Code depending on result
}).catch(function() {
// An error occurred
});
Describing all the advantages that promises offer is beyond the scope of this answer, but if you write new code, you should seriously consider them. They provide a great abstraction and separation of your code.
More information about promises: HTML5 rocks - JavaScript Promises
Functions should always have a return value. Not just "get"-like functions, but also (perhaps even more important) the "set"-like functions. Scripts may not use this return value in many cases (ie. it's out of their scope to do anything about it), but in more advanced structures or test suites, the return value of a "set" function is very important (ie. "don't load X if Y was not set", or "Did the function correctly refuse to do X in scenario Y").
Unit testing in Javascript can be tedious and painful, but Testem makes it so easy that you will actually want to write tests.
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
shove - Prove-like Test Tool for Shell Scripts
Le Validateur unifié du W3C
w3c/web-platform-tests: Test Suites for Web Platform specifications—including WHATWG, W3C and others
The Web Platform Tests Project is a W3C-coordinated attempt to build a cross-browser testsuite for the Web-platform stack. However, for mainly historic reasons, the CSS WG testsuite is in a separate repository, csswg-test. Writing tests in a way that allows them to be run in all browsers gives browser projects confidence that they are shipping software that is compatible with other implementations, and that later implementations will be compatible with their implementations. This in turn gives Web authors/developers confidence that they can actually rely on the Web platform to deliver on the promise of working across browsers and devices without needing extra layers of abstraction to paper over the gaps left by specification editors and implementors.