Ответ 1
Я не знаю о Yeoman. Я еще не пробовал - но я все оставил головоломку. Полагаю, вы поймете остальное.
Зачем делать интеграционные тесты?
В вашем вопросе вы говорили о ситуации, когда у вас есть как клиентские тесты, так и серверные тесты, выполняемые с помощью mocks. Я предполагаю, что по какой-то причине вы не можете заставить оба набора тестов работать с одними и теми же макетами. В противном случае, если вы изменили макеты на стороне клиента, ваши тесты на стороне сервера потерпят неудачу, потому что они получат сломанные данные.
Что вам нужно, так это интеграционные тесты, поэтому, когда вы запускаете какой-то код на стороне клиента в своем браузере без браузера, ваш серверный код также будет работать. Более того, просто запустить ваш серверный и клиентский код недостаточно, вы также хотите иметь возможность устанавливать утверждения с обеих сторон, не так ли?
Интеграционные тесты с Node и PhantomJS
В большинстве примеров интеграционных тестов, которые я нашел в Интернете, используйте Selenium или Zombie.js. Первая - это большая платформа на основе Java для управления настоящими браузерами, а позднее - простая оболочка jsdom. Я предполагаю, что вы не решаетесь использовать любой из них и предпочтете PhantomJS. Трудная часть, конечно же, заключается в том, чтобы запустить это из вашего приложения Node. И я получил именно это.
Существует два модуля Node для подключения PhantomJS:
К сожалению, оба проекта кажутся заброшенными их авторами и другими членами сообщества, чтобы развить их и адаптироваться к их потребностям. Это означает, что оба проекта разворачивались много раз, и все вилки почти не работают. API почти не существует. Я провел тесты с одной из вилок phantom (Спасибо, Seb Vincent). Здесь простое приложение:
'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);
})();
Он прослушивает запрос /user
и возвращает параметр пути name
и параметр запроса secret
. Здесь страница, на которой я вызываю сервер:
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();
})();
И вот простой тест:
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
});
});
});
Как вы можете видеть, я должен опросить сервер в таймаут. Это потому, что все привязки phantom являются неполными и слишком ограниченными. Как вы можете видеть, я могу проверить состояние клиента и состояние сервера в одном тесте.
Запустите ваши тесты с помощью Mocha: mocha -t 2s
Вам, вероятно, потребуется увеличить значение тайм-аута по умолчанию для более развитых тестов для запуска.
Итак, как вы можете видеть, все это выполнимо. Здесь репо с полным примером. p >