从vows进行测试启动服务器的正确方法是什么?

10
我有一个使用vows进行测试的express服务器。我希望在vows测试套件内运行该服务器,这样我就不需要在后台运行它以使测试套件正常工作,然后我只需创建一个蛋糕任务来运行服务器并在隔离环境中对其进行测试。 在`server.coffee`中,我创建了一个(express)服务器,进行了配置,设置了路由,并像这样调用app.listen(port):
# 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

在我的简单的 routes-test.js 中,我有:

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

respondsWith(code)功能类似于vows文档中的那个...

当我在上面的测试中require服务器时,它会自动开始运行服务器并运行和通过测试,这很好,但我不觉得我是在以“正确”的方式进行。

我无法控制服务器何时开始工作,如果我想将服务器配置为指向“测试”环境而不是默认环境,或者更改默认日志记录级别以进行测试,该怎么办?

PS:我将把我的vows转换为Coffeescript,但现在它们全部都是js,因为我正在阅读文档学习!


1
你可能想要看一下Pact——它是用于使用Vows测试HTTP服务器的。 - Skilldrick
谢谢Skilldrick,我会去看看Pact! - cjroebuck
1个回答

2

这是一个有趣的问题,因为就在昨天晚上我做了你想做的事情。我有一个小的CoffeScript Node.js应用程序,恰好像你展示的那个一样编写。然后,我进行了重构,创建了以下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

现在我有一个像这样简单的index.coffee文件(相当于你的server.coffee),它的内容如下:
require('./app').start port:3000

接下来,我使用Jasmine-nodeZombie.js编写了一些测试。测试框架不同,但原理相同:

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

重点是:我做的和建议的是在一个模块中创建一个启动服务器的函数,在需要的地方调用这个函数。我不知道这是否是“良好的设计”,但对我来说,它能够工作并且看起来易读和实用。
此外,我怀疑在 Node.js 和 CoffeScript 中还没有“良好的设计”。这些都是全新的、非常创新的技术。当然,我们可以“感觉到有些不对劲”——比如在这种情况下,两个不同的人不喜欢设计并进行了更改。我们可以感觉到“错误的方式”,但这并不意味着已经有“正确的方式”。总结一下,我认为在你的开发中我们将不得不发明一些“正确的方式”:)
(但是问一下如何做好事情也是好的。也许有人有好主意,公共讨论会对其他开发者有所帮助。)

1
非常感谢,你说得对,使用这种技术没有“正确”的做法,但我知道肯定有一种“更好”的方式。不幸的是,目前网络上还没有关于这个特定问题的清晰示例,至少我找不到。 - cjroebuck
我了解你的情况,我也经常遇到同样的问题。幸运的是,你现在的问题已经在网上提供了一个例子 :) - brandizzi
如果您的服务器使用了cluster.fork(),那么这种方法将无法正常工作。因为会有多个服务器同时运行。 - haijin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接