грунт тестирования API с супертеста, экспресс и кофе мокко
У меня есть https-сервер под управлением express, который я тестирую с помощью mocha и supertest.
Моя проблема в том, что если я выполняю только тест - это нормально. Если я пытаюсь запустить gruntfile с тестом, а затем запустить express - я вижу много ошибок EADDRINUSE, даже если в тестовых файлах я делаю после() с приложением.закрывать(). То же самое относится к задаче наблюдения на тестах.
Вот мой тест exapmle:
/* jshint node: true*/
/*global describe, it, after*/
(function() {
'use strict';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var request = require('supertest');
var app = require('../server.js').app;
var expect = require('chai').expect;
var Cookies;
after(function(done) {
app.close();
setTimeout(function(){done();}, 1500);
});
describe('/login', function() {
it('should auth the user', function(done) {
request(app)
.post('/login')
.send({login: "test", password: 'test'})
.expect(302)
.end(function(err, res) {
expect(err).to.be.equal(null);
expect(res.text).to.be.equal("Moved Temporarily. Redirecting to /");
Cookies = res.headers['set-cookie'].pop().split(';')[0];
done();
});
});
});
// testing API for serving session data for angualar factory
describe('/api/session', function() {
it('should return session data in JSON', function(done) {
var req = request(app).get('/api/session');
req.cookies = Cookies;
req.set('Accept','application/json')
.end(function(err, res) {
expect(err).to.be.equal(null);
expect(res.body).to.have.property("_id");
done();
});
});
});
}());
Я знаю, что эти тесты далеки от совершенства. Я только начинаю свое приключение с подходящим программным обеспечением тестирование.
Все эти "порт уже используется" очевидны, и ни один из них... дайте любой вопрос. все тесты работают нормально, сервер работает нормально, но stdout-это безумие. Такое поведение далеко от идеала и, вероятно, полно потенциальных проблем и проблем нестабильности.
Мой вопрос - как от него избавиться?
Мои идеи таковы:
-
Создайте выделенный сервер для тестирования только на другом порту. К сожалению, я должен подсказать, как реализовать этот.
-
Сделайте некоторые условия для суперагента, чтобы запустить сервер, если он не работает, или просто... иначе передать его суперагенту?
-
Используйте что-то другое, тогда суперагент (например, запрос, но я не уверен, что все куки и node_tls_reject_unauthorized будут работать.
Я очень признателен за любые помощь.
Правка:
Я нашел, что могу сделать:
before(function(done) {
app.listen(3001, function() { done(); });
});
Который запускает тест на другом порту, но... весь сервер.js все равно загружен,так что он тоже запускается. Затем, при запуске его вместе с запущенным сервером, есть очевидное EADDRINUSE.
1 ответ:
При использовании
superagent
, вы всегда должны передать ему Экспресс-приложение, которое было настроено (зарегистрированное промежуточное ПО, маршрутизированные контроллеры и т. д.)--но не инициализируется как HTTP-сервер. Он сделает это для вас и будет откладывать, черезhttp.createServer
, к ОС, чтобы выбрать доступный порт.Если в данный момент модуль
server.js
уже предоставляет статический экземпляр полноценного HTTP-сервера, то это, скорее всего, является источником ваших проблем. В любом случае, попробуйте извлечь конфигурация приложения / загрузка из фактического экземпляра сервера выглядит следующим образом:// server.js var express = require('express'); var middleware = require('./middleware'); var controllers = require('./controllers'); // Configures the Express application instance. exports.setup = function (app) { app.use(middleware.foo); app.get('/bar', controllers.bar); app.locals.baz = 'quux'; } // You might shoot yourself in the foot if parts of your application depend // on a static reference at `server.app`. exports.app = setup(express()); exports.app.listen(3000);
Затем, в ваших тестах, вы можете сделать что-то вроде:
// tests.js var express = require('express'); var server = require('./server'); describe('Server tests', function () { // Create a fresh server instance prior to each test beforeEach(function createNewSever() { this.app = server.setup(express()); }); describe('Foo', function () { it('barrs', function () { request(this.app) // initializes a server instance on port A // ... supertests }); it('bazzes', function () { request(this.app) // initializes a server instance on port B // ... more supertests }); }); });
Это просто для иллюстрации, где время / способ создания экземпляра приложения будет зависеть от контекста теста. Важно отметить, что вы должны иметь возможность создавать свежие, чистые, независимые и изолированные экземпляры сервера для ваших тестовых случаев. Это абсолютная необходимость. следует ли использовать тестовый раннер, который выполняет тесты параллельно или в случайном порядке.