Question

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!

Était-ce utile?

La solution

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.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top