2017-10-21 146 views
0

如果我有一組URL來訪問:執行多個摩卡測試

let tests = [ 
    { status: 200, mediaType: 'text/html', req: { method: 'GET', uri: 'http://stackoverflow.com/' } }, 
    { status: 200, mediaType: 'text/html', req: { method: 'GET', uri: 'http://stackoverflow.com999/' } }, 
    { status: 200, mediaType: 'text/html', req: { method: 'GET999', uri: 'http://stackoverflow.com/' } }, 
] 

和一組測試對每個執行:

it('should have status ' + test.status,() => { 
    expect(test.response.statusCode).to.equal(test.status) 
}) 
it('should have content type ' + test.mediaType,() => { 
    let s = test.response.headers['content-type'] 
    let mediaType = s.indexOf(';') === -1 ? s : s.substr(0, s.indexOf(';')) 
    expect(mediaType).to.equal(test.mediaType) 
}) 
it('should have a body',() => { 
    expect(test.body).to.not.equal('') 
}) 

我怎樣才能在每套測試中只執行一次昂貴的操作?另外,如果URL不加載,我不想運行測試。

回答

0

mocha Working With Promises documentation有一個例子,其中每個測試都等待一個beforeEach承諾在執行之前完成。如果你需要一個beforeEach反正,你可以保存爲beforeEach這個承諾,你可以讓他們都等待一個承諾:

let P = null 
beforeEach(function() { 
    if (!P) P = new Promise(...) 
    return P 
}) 

但更可能的是,你只需要使用一個before

beforeEach(function() { 
    return new Promise(...) 
}) 

對於這個問題的完整列表:

let expect = require('chai').expect 
let request = require('request') 

let tests = [ 
    { status: 200, mediaType: 'text/html', req: { method: 'GET', uri: 'http://localhost/' } }, 
    { status: 200, mediaType: 'text/html', req: { method: 'GET', uri: 'http://localhost999/' } }, 
    { status: 200, mediaType: 'text/html', req: { method: 'GET999', uri: 'http://localhost/' } }, 
] 

tests.forEach(function (test) { 
    describe(test.req.method + ' ' + test.req.uri, function() { 
    before('should load', function() { 
     return new Promise(function (resolve, reject) { 
     request(test.req, function (error, response, body) { 
      if (error) { 
      reject(test.rejection = error) 
      } else { 
      test.response = response 
      test.body = response 
      resolve() 
      } 
     }) 
     }) 
    }); 

    it('should have status ' + test.status,() => { 
     expect(test.response.statusCode).to.equal(test.status) 
    }) 
    it('should have content type ' + test.mediaType,() => { 
     let s = test.response.headers['content-type'] 
     let mediaType = s.indexOf(';') === -1 ? s : s.substr(0, s.indexOf(';')) 
     expect(mediaType).to.equal(test.mediaType) 
    }) 
    it('should have a body',() => { 
     expect(test.body).to.not.equal('') 
    }) 
    }) 
}) 

這給了你漂亮流利的輸出:

GET http://stackoverflow.com/ 
    ✓ should have status 200 
    ✓ should have content type text/html 
    ✓ should have a body 

    GET http://stackoverflow.com999/ 
    1) "before each" hook: should load for "should have status 200" 

    GET999 http://stackoverflow.com/ 
    ✓ should have status 200 
    ✓ should have content type text/html 
    ✓ should have a body 

如果你改變的例子使用計算器的本地主機這一翻譯,你可以看訪問日誌,以驗證每個URL被加載一次:

127.0.0.1 - - [21/Oct/2017:06:52:10 -0400] "GET/HTTP/1.1" 200 12482 "-" "-" 
127.0.0.1 - - [21/Oct/2017:06:52:10 -0400] "GET999/HTTP/1.1" 501 485 "-" "-" 

注意,最後的操作,GET999 http://stackoverflow.com/給出了一個200在stackoverflow上(通過清漆緩存)和apache上的501:

2) GET999 http://localhost/ 
     should have status 200: 

     AssertionError: expected 501 to equal 200 
     + expected - actual 

     -501 
     +200 
+1

爲什麼不直接使用'before'? – shawon191

+0

這確實比較好。我用'之前'更新了答案。 TX! – ericP