Socket.io, пожалуй, одна из самых крутых вещей, появившихся в мире JavaScript за последние годы. В заключение! Это то, что позволяет веб-разработчикам создавать приложения в реальном времени, не задумываясь о веб-сокетах, длительных опросах и других хакерских атаках, которые необходимо использовать.
Идея довольно проста: сервер может генерировать событие, а клиент его принимает . Обратное также происходит. Обратные вызовы через барьер сервер-клиент также работают. Socket.io заботится о том, чтобы решить, какой из хаков в реальном времени следует использовать, чтобы волшебство произошло.
Дело в том, что взаимодействие клиента и сервера делает приложения socket.io немного сложными для тестирования.
Хороший способ, который я нашел, — это сочетание Mocha , Chai и socket.io-client .
Сначала что-то для тестирования
Давайте возьмем для примера очень простой эхо-сервер. Я использовал Express, чтобы было легче играть в консоли Chrome. Вот соответствующая часть app.js .
var server = exports.server = http.createServer(app).listen(app.get('port'), function(){ console.log("Express server listening on port " + app.get('port')); }); var io = require('socket.io').listen(server); io.set("log level", 0);
// the important parts of echo server io.sockets.on("connection", function (socket) { socket.on("echo", function (msg, callback) { callback = callback || function () {}; socket.emit("echo", msg); callback(null, "Done."); }); });
После того, как я не забыл загрузить /socket.io/socket.io.js на страницу индекса, я теперь могу запустить сервер, указать свой браузер на http: // localhost: 3000 и поиграть в консоли следующим образом:
> var socket = io.connect("http://localhost:3000") undefined > socket.on("echo", function (msg) { console.log(msg); }) SocketNamespace > socket.emit("echo", "Hello World") SocketNamespace Hello World
Автоматизация теста
Ввод команд в консоли, даже нажатие на веб-страницу — довольно трудный и скучный процесс. Самый простой способ, который я нашел, это автоматизировать с помощью Mocha и socket.io-client.
Первое, что нам нужно, — это требовать всего и убедиться, что сервер socket.io работает.
var chai = require('chai'), mocha = require('mocha'), should = chai.should(); var io = require('socket.io-client'); describe("echo", function () { var server, options ={ transports: ['websocket'], 'force new connection': true }; beforeEach(function (done) { // start the server server = require('../app').server; done(); });
Смотри, просто
Теперь перейдем к интересной части, собственно тесту, удостоверяющему, что наш сервер действительно повторяет то, что мы просим.
it("echos message", function (done) { var client = io.connect("http://localhost:3000", options); client.once("connect", function () { client.once("echo", function (message) { message.should.equal("Hello World"); client.disconnect(); done(); }); client.emit("echo", "Hello World"); }); });
Идея этого теста проста:
- Подключите клиент к серверу
- Когда соединение установлено, прослушайте эхо- событие с сервера
- Выдать эхо- событие на сервер
- Сервер отвечает и запускает нашего слушателя
- Слушатель проверяет правильность ответа
- Отключает клиента
Отключение клиентов после тестов очень важно . Как я обнаружил, отсутствие разъединения может привести к тому, что сокет накапливает прослушиватели событий , которые в свою очередь могут запускать совершенно другие тесты, чем вы ожидаете. Это также приводит к тестам, которые проходят 70% времени, но не дают результатов случайным образом.
В итоге наши усилия вознаграждаются счастливой нянькой кошкой.
PS: вы можете увидеть весь код на github .