2017-10-21 101 views
0

Si j'ai un ensemble d'URL à visiter:effectuer plusieurs tests de mocha après une seule opération coûteuse (par exemple HTTP GET)

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/' } }, 
] 

et une série de tests à effectuer sur chaque:

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

Comment puis-je effectuer l'opération coûteuse une seule fois par série de tests? De plus, je ne veux pas lancer les tests si l'URL ne se charge pas.

Répondre

0

Le mocha Working With Promises documentation a un exemple avec chacun (d'un, il est vrai) attend de test pour une beforeEach promesse de terminer avant d'exécuter. Si vous avez besoin d'un beforeEach de toute façon, vous pouvez enregistrer cette promesse pour le beforeEach, vous pouvez avoir tous attendre une promesse:

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

mais plus probablement, vous voulez juste utiliser un before:

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

Pour obtenir une liste complète du problème:

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

Cela vous donne une sortie assez courant:

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 

Si vous changez l'exemple d'utiliser localhost intead de stackoverflow, vous pouvez regarder le journal d'accès pour vérifier que chaque URL est chargée une fois:

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 "-" "-" 

Notez que la dernière opération, GET999 http://stackoverflow.com/ donne un 200 sur stackoverflow (via un cache de vernis) et un 501 sur apache:

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

     AssertionError: expected 501 to equal 200 
     + expected - actual 

     -501 
     +200 
+1

Pourquoi ne pas utiliser 'before'? – shawon191

+0

C'est en effet mieux. J'ai mis à jour la réponse en utilisant 'before'. Tx! – ericP