# servertest
**Repository Path**: mirrors_yorkie/servertest
## Basic Information
- **Project Name**: servertest
- **Description**: A simple HTTP server testing tool
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-11-23
- **Last Updated**: 2026-05-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# servertest
**A simple HTTP server testing tool**
[](https://nodei.co/npm/servertest/)
[](https://nodei.co/npm/servertest/)
## Why?
**servertest** exists because [supertest](https://github.com/visionmedia/supertest) does way too much and gets in the way when you need to do anything novel (the typical "framework" problem).
**servertest** doesn't do any assertions for you, you simply hand it an HTTP server and it manages the start / stop lifecycle and makes a request for you, passing you back the results. **servertest** is built on **[hyperquest](https://github.com/substack/hyperquest)** as an HTTP client and supports the same options as hyperquest and will stream if you need to (in and/or out).
## Examples
```js
var server = http.createServer(function (req, res) {
res.end('OK')
})
test('simple web server', function (t) {
servertest(server, '/', { encoding: 'utf8' }, function (err, res) {
t.ifError(err, 'no error')
t.equal(res.statusCode, 200, 'correct statusCode')
t.equal(res.body, 'OK', 'correct body content')
t.end()
})
})
```
Even JSON encoding can be handled for you:
```js
var server = http.createServer(function (req, res) {
res.end(JSON.stringify({ ok: 'mate' }))
})
test('json web server', function (t) {
servertest(server, '/', { encoding: 'json' }, function (err, res) {
t.ifError(err, 'no error')
t.equal(res.statusCode, 200, 'correct statusCode')
t.deepEqual(res.body, { ok: 'mate' }, 'correct body content')
t.end()
})
})
```
And of course it's streams all the way:
```js
// uppercasing server, post it a string and it'll return
// an uppercased version of it
var server = http.createServer(function (req, res) {
req.pipe(through2(function (chunk, enc, callback) {
callback(null, chunk.toString().toUpperCase())
})).pipe(res)
})
test('duplex uppercasing server', function (t) {
// servertest is a duplex stream when posting data
var serverStream = servertest(server, '/', { method: 'POST' })
// pipe data to the POST request
fs.createReadStream(__filename).pipe(serverStream)
// pipe data from the response
serverStream.pipe(bl(function (err, data) {
t.ifError(err, 'no error')
var expected = fs.readFileSync(__filename, 'utf8').toUpperCase()
t.equal(data.toString(), expected, 'uppercased data')
t.end()
}))
})
```
Of course this assumes that you have easy access to your `http.Server` object in your tests. Normally you will want to expose it on your server directly on your main server start script and not perform the `listen()` yourself if it's not being run as the "main":
**index.js**
```js
module.exports = function () {
return http.createServer(handler)
}
if (require.main === module) {
module.exports().listen(port, function (err) {
console.log('Server started on port %d', port)
})
}
```
Then you can do this:
**test.js**
```js
var server = require('./index')
test('test server', function (t) {
servertest(server(), '/path/to/test', function (err, data) {
// ...
})
})
```
Or you could reuse the same `server` object but that's probably not so savoury for testing.
## API
### servertest(server, uri, options, callback)
Full arguments form, taking an `http.Server` instance (or similar object that performs a `listen()`), the `uri` to append to `http://localhost` and the random port number assigned on the `listen()`, the `options` object which is mostly passed on to [hyperquest](https://github.com/substack/hyperquest). The `callback` function will receive either an `Error` as the first argument or a special `response` object that contains data about the response, see below
### servertest(server, uri, callback)
The `options` argument is optional, default options will be used for hyperquest, including assuming this is a GET request.
### var stream = servertest(server, uri, { method: 'POST' }, callback)
A common POST request form whereby you have a WritableStream you can write data to (either via a `pipe()` or simply `write()` and `end()`).
### var stream = servertest(server, uri, { method: 'POST' })
Don't use a `callback` function to receive the data. Instead, the `stream` is a DuplexStream which has some metadata on the `stream` object (including the `request` object direct from hyperquest) and you will need to `pipe()` it to a WritableStream (or `read()` or `on('data')`, whatever you prefer).
### options
- 'encoding': the only option **servertest** currently cares about. If you provide `'utf8'` the `callback` will receive a `String` rather than a `Buffer`. If you provide `'json'` the data received from the server will be passed through `JSON.parse()` and any exceptions will be returned as the `Error` argument to the `callback`.
**[hyperquest](https://github.com/substack/hyperquest)** uses the following options:
- 'method': request method, defaults to `'GET'`
- 'headers': an `Object` (`{}`) defining headers to set on the request
- 'auth': if HTTP authentication is required, must be of the form `'user:pass'`
Plus a bunch more for HTTPS.
### response
The `callback` receives a special `response` object containing data from the server. It will have the following properties:
- 'headers': an `Object` containing a mapping of the header keys and values received from the server
- 'statusCode': the status code of the response from the server
- 'body': the response body. By default it will be a `Buffer`. If you use `'utf8'` as the `'encoding'` you'll get a `String` and if you use `'json'` as the `'encoding'` you'll get whatever `JSON.parse()` gives you for the response string.
## License
**servertest** is Copyright (c) 2014 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.