Вопрос

У меня есть https-сервер, работающий с помощью express, который я тестирую с помощью mocha и supertest.

Моя проблема в том, что если я запускаю только тест - все в порядке.Если я пытаюсь запустить gruntfile с test, а затем запустить express - я вижу много ошибок EADDRINUSE, даже если в тестовых файлах я делаю after() с помощью app.close().То же самое относится и к задаче просмотра в тестах.

Вот мой примерный тест:

/* 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();
            });
        });
    });

}());

Я знаю, что эти тесты далеки от совершенства.Я только начинаю свое приключение с правильного тестирования программного обеспечения.

Все эти "уже используемые порты" очевидны, и ни один из них...дайте любой ответ.все тесты работают нормально, сервер работает нормально, но стандартный вывод - это безумие.Такое поведение далеко от идеального и, вероятно, чревато потенциальными проблемами и нестабильностью.

Мой вопрос в том, как от этого избавиться?

Мои идеи таковы:

  • создайте выделенный сервер для тестирования только на другом порту.К сожалению, я понятия не имею, как это реализовать.

  • сделайте некоторое условие для суперагента, чтобы запустить сервер, если он не запущен, или просто...в противном случае передать это суперагенту?

  • используйте что-то еще, затем суперагент (например, запрос, но я не уверен, будут ли работать все файлы cookie и node_tls_reject_unauthorized.

Как Вы можете видеть, я с трудом разбираюсь в этой теме, у меня больше вопросов, чем ответов, и недостаточно опыта, чтобы знать, на что обратить внимание.

Я искренне признателен за любую помощь.

Редактировать:

Я нашел, что я могу сделать:

before(function(done) {
    app.listen(3001, function() { done(); });
});

который запускает тест на другом порту, но...весь файл server.js загружается в любом случае, поэтому он тоже запускается в любом случае.Затем, при запуске его вместе с запущенным сервером, возникает очевидный EADDRINUSE.

Это было полезно?

Решение

При использовании 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
        });
    });
});

Это просто в иллюстративных целях, где время и способ создания экземпляра приложения будут зависеть от вашего тестового контекста.Важно отметить, что вы должны иметь возможность создавать свежие, чистые, независимые и изолированные экземпляры сервера для ваших тестовых случаев.Это абсолютно необходимо, если вы используете программу тестирования, которая выполняет тесты параллельно или в случайном порядке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top