Pergunta

I have an express server which I am testing using vows. I want to run the server from within the vows test suite, so that I dont need to have it running in the background in order for the test suite to work, then I can just create a cake task which runs the server and tests it in isolation.

In server.coffee I have created the (express) server, configured it, set up routes and called app.listen(port) like this:

# Express - setup
express = require 'express'
app = module.exports = express.createServer()

# Express - configure and set up routes
app.configure ->
   app.set 'views', etc....
   ....

# Express - start
app.listen 3030

In my simple routes-test.js I have :

vows    = require('vows'),
assert  = require('assert'),
server  = require('../app/server/server');

// Create a Test Suite
vows.describe('routes').addBatch({
    'GET /'     : respondsWith(200),
    'GET /401'  : respondsWith(401),
    'GET /403'  : respondsWith(403),
    'GET /404'  : respondsWith(404),
    'GET /500'  : respondsWith(500),
    'GET /501'  : respondsWith(501)
}).export(module);

where respondsWith(code) is similar in functionality to the one in the vows doc...

When I require server in the above test, it automatically begins running the server and the tests run and pass, which is great, but I dont feel like I am doing it the 'right' way.

I dont have much control over when the server begins, and what happens if I want to configure the server to point to a 'test' environment rather than the default one, or change the default logging level for when im testing?

PS I am going to convert my vows to Coffeescript but for now its all in js as im in learning mode from the docs!

Foi útil?

Solução

That is an interesting question because exactly last night I did what you want to do. I have a little CoffeScript Node.js app which happened to be written like the one you showed. Then, I refactored it, creating the following app.coffee:

# ... Imports
app = express.createServer()

# Create a helper function
exports.start = (options={port:3000, logfile:undefined})->
  # A function defined in another module which configures the app
  conf.configure app, options 
  app.get '/', index.get
  # ... Other routes
  console.log 'Starting...'
  app.listen options.port

Now I have an index.coffee (equivalent to your server.coffee) as simple as:

require('./app').start port:3000

Then, I wrote some tests using Jasmine-node and Zombie.js. The test framework is different but the principle is the same:

app = require('../../app')
# ...

# To avoid annoying logging during tests
logfile = require('fs').createWriteStream 'extravagant-zombie.log'

# Use the helper function to start the app
app.start port: 3000, logfile: logfile

describe "GET '/'", ->
  it "should have no blog if no one was registered", ->
    zombie.visit 'http://localhost:3000', (err, browser, status) ->
      expect(browser.text 'title').toEqual 'My Title'
      asyncSpecDone()
    asyncSpecWait()

The point is: what I did and I would suggest is to create a function in a module which starts the server. Then, call this function wherever you want. I do not know if it is "good design", but it works and seems readable and practical to me.

Also, I suspect there is no "good design" in Node.js and CoffeScript yet. Those are brand new, very innovative technologies. Of course, we can "feel something is wrong" - like this situation, where two different people didn't like the design and changed it. We can feel the "wrong way", but it does not mean there is a "right way" already. Summing up, I believe we will have to invent some "right ways" in your development :)

(But it is good to ask about good ways of doing things, too. Maybe someone has a good idea and the public discussion will be helpful for other developers.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top