2012-06-10 23 views
15

Tôi đang cố tạo một bộ thử nghiệm độc lập bằng mocha, trong thế giới hoàn hảo sẽ khởi động ứng dụng express.js của tôi, hãy sử dụng zombie để hiển thị một trang, kiểm tra một nhóm của các công cụ và sau đó teardown/giết ứng dụng express.js.Thiết lập/teardown ứng dụng express.js bằng mocha

Có cách nào dễ dàng/tốt nhất để thực hiện việc này không?

NB. Tôi chỉ có thể có máy chủ ứng dụng tốc hành chạy trước khi chạy thử nghiệm, nhưng Yaks là gì nếu bạn không cạo chúng.

+2

đẹp câu hỏi.Bản thân tôi nhìn vào đó một lúc nhưng sau một tuần tôi bỏ cuộc. Tôi tìm thấy zombie thực sự gây phiền nhiễu để làm việc với. Tôi đã đọc rất nhiều về PhantomJS nhưng tôi không thử nó. – Pickels

Trả lời

23

Trước tiên, bạn cần di chuyển thiết lập ứng dụng thực tế của mình thành một mô-đun và nhập ứng dụng đó vào tệp thực sự khởi động ứng dụng của bạn. Bây giờ điều này là riêng biệt, bạn có thể có ứng dụng ở trạng thái hoàn chỉnh của nó trước khi thực sự lắng nghe.

Bạn nên di chuyển thiết lập thực tế của ứng dụng vào một tệp riêng biệt, hãy gọi nó là app.js, có thể gọi lắng nghe từ tệp mà bạn chạy khỏi nút, hãy gọi nó là index.js.

Vì vậy, app.js sẽ trông như thế:

var express = require('express') 
    , routes = require('./routes'); 

var app = module.exports = express.createServer(); 

// Configuration 

app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function(){ 
    app.use(express.errorHandler()); 
}); 

// Routes 

app.get('/', routes.index); 

và index.js sẽ trông như thế:

var app = require('./app'); 

app.listen(3000, function(){ 
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); 
}); 

này seperates tải của ứng dụng của bạn từ thực sự có nó nghe, cho phép bạn tải ứng dụng đó vào các bài kiểm tra đơn vị của bạn.

Trong các bài kiểm tra đơn vị của bạn, bạn sẽ làm điều gì đó trong một phương pháp thiết lập và phương pháp teardown để đưa lên và đưa xuống máy chủ.

Trong thử nghiệm tập tin/app_tests.js:

describe('app', function(){ 
    var app = require('../app'); 
    beforeEach(function(){ 
    app.listen(3000); 
    }); 
    // tests here 
    afterEach(function(){ 
    app.close(); 
    }) 
}); 
+0

Tuyệt vời! Nhưng, trong trường hợp của tôi, tôi có nhiều tệp thử nghiệm và có vẻ như mocha thực thi tất cả các tệp đồng thời, gây ra một số xung đột xấu giữa các tệp thử nghiệm! tôi có thể làm gì ? –

+0

Làm cho mỗi bài kiểm tra lắng nghe trên một cổng khác - chỉ cần chọn một số ngẫu nhiên (đủ cao) –

+0

GIẢI PHÁP VƯỢT TRỘI! Đây là cách đúng để làm điều đó. Một sửa đổi: bạn thực sự nên đóng kết quả của app.listen, không phải bản thân ứng dụng, tức là: (trong beforeEach) "instance = app.listen (3000);" ... và sau đó (trong afterEach) "instance.close()" –

4

Ngoài Oved D câu trả lời.

Mô tả ứng dụng của bạn trong nhanh-app.js hoặc một số tập tin khác:

module.exports = function (o) { 
    o = o || {}; 
    var app = express(); 

    // app.configure 
    // configure routes 
    if (o.someOption) { 
    // some additional test code 
    } 

    return app; 
} 

mô tả các bài kiểm tra trong thử nghiệm/01-some.js:

var expressApp = require('../express-app'); 
describe('some', function() { 

    // just describe needed vars 
    var app, server, port; 

    // describe setup 
    before(function (next) { 
    // create app when 
    app = expressApp({routes: /api\/some\/.*/ /* put here some test options ...*/}); 
    // creating listener with random port 
    server = app.listen(function() { 
     // store port when it ready 
     port = server.address().port; 
     // and go to tests 
     next(); 
    }); 
    }); 

    // tests 
    it('should return valid result', function (done) { 
    // do a simple request to /api/some 
    http.request({ 
     host: 'localhost', 
     port: port, 
     path: '/api/some' 
    }, function (res) { 
     if (res.err) throw new Error(res.err); 
     done(); 
    }); 
    }); 

    // teardown 
    after(function() { 
    // stop listening that port 
    server.close(); 
    }); 

}); 

Xong. ;-)

Bây giờ bạn có thể tạo bất kỳ số lượng kiểm tra nào như vậy. Đề xuất bạn chỉ bật các url và dịch vụ cần thiết trong các thử nghiệm có xác định nó bằng cách chuyển các tham số đến mô-đun express-app.js.


Cập nhật:

Không chắc thế nào nó hoạt động trong mocha nhưng tốt hơn để di chuyển beforeafter cuộc gọi đến init.js và tải nó với mocha --require init.js.

file nên trông như thế:

// use it in your mocha tests 
global.setupEnv = function setupEnv (o, before, after) { 

    // just describe needed vars 
    var env = Object.create(null); 

    // setup 
    before(function (next) { 
     // create app 
     env.app = expressApp(o); 
     // creating listener with random port 
     env.server = env.app.listen(function() { 
      // store port when it ready 
      port = env.server.address().port; 
      env.app.log('Listening on ', env.port); 
      // and go to tests 
      next(); 
     }); 
    }); 

    // teardown 
    after(function() { 
     // stop listening that port 
     env.server.close(); 
    }); 

    return env; 
} 

Và trong các thử nghiệm của bạn:

// requiring dependencies 
var request = require('request'); 

describe('api', function() { 

    // describe setup 
    var env = global.setupEnv({ 
      routes: 'api/some' 
     }, before, after); 

    // tests 
    it('should pass', function (done) { 
     request('http://localhost:' + env.port, function (error, response, body) { 
      done(); 
     }); 
    }); 

}); 
Các vấn đề liên quan