come correggere gli avvisi 404 per le immagini durante il test dell'unità karma


84

Sto testando una delle mie direttive (angularjs) usando grunt / karma / phantomjs / jasmine. I miei test funzionano bene

describe('bar foo', function () {
    beforeEach(inject(function ($rootScope, $compile) {
        elm = angular.element('<img bar-foo src="img1.png"/>');
        scope = $rootScope.$new();
        $compile(elm)();
        scope.$digest();
    }));
    ....
});

ma ho questi 404

WARN [web-server]: 404: /img1.png
WARN [web-server]: 404: /img2.png
...

Sebbene non facciano nulla, aggiungono rumore all'output del registro. C'è un modo per risolvere questo problema ? (senza cambiare il livello del karma ovviamente, perché voglio vederli)


Persiste in un browser diverso? So che ci sono alcuni problemi noti con errori 404 per questi tipi di chiamate in FF.
Nicholas Hazel,

deve essere phantomjs. Ho controllato Chrome che mostra anche il 404. Nota che sono avvertimenti, non errori!
Jeanluca Scaljeri

L'uso di ng-src aiuta?
Eitan Peer

bella prova, ma ha lo stesso risultato
Jeanluca Scaljeri

Risposte:


109

Questo perché devi configurare il karma per caricarlo e poi servirli quando richiesto;)

Nel tuo file karma.conf.js dovresti già avere file e / o pattern definiti come:

// list of files / patterns to load in the browser
files : [
  {pattern: 'app/lib/angular.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/angular-*.js', watched: true, included: true, served: true},
  {pattern: 'app/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'app/js/**/*.js', watched: true, included: true, served: true},
  // add the line below with the correct path pattern for your case
  {pattern: 'path/to/**/*.png', watched: false, included: false, served: true},
  // important: notice that "included" must be false to avoid errors
  // otherwise Karma will include them as scripts
  {pattern: 'test/lib/**/*.js', watched: true, included: true, served: true},
  {pattern: 'test/unit/**/*.js', watched: true, included: true, served: true},
],

// list of files to exclude
exclude: [

],

// ...

Puoi dare un'occhiata qui per maggiori informazioni :)

EDIT: se utilizzi un server web nodejs per eseguire la tua app, puoi aggiungerlo a karma.conf.js:

proxies: {
  '/path/to/img/': 'http://localhost:8000/path/to/img/'
},

EDIT2: se non si utilizza o si desidera utilizzare un altro server è possibile definire un proxy locale ma poiché Karma non fornisce l'accesso alla porta in uso, dinamicamente, se il karma inizia su una porta diversa da 9876 (impostazione predefinita), sarà prendi quei fastidiosi 404 ...

proxies =  {
  '/images/': '/base/images/'
};

Problema correlato: https://github.com/karma-runner/karma/issues/872


4
Nel mio caso queste immagini non esistono. La soluzione che fornisci presuppone che i file esistano, giusto?
Jeanluca Scaljeri

Sì, naturalmente! Penso di aver capito male, ha senso avere errori 404 per file non esistenti, giusto? Vorresti nascondere gli avvisi relativi alle immagini? Senza modificare il livello di log, non vedo alcuna soluzione, inoltre, che nasconderebbe altri avvisi, il che sarebbe rischioso. Perché non creare file .png vuoti nella cartella "test / img", ad esempio? :)
glepretre

Per qualche motivo non riesco a farlo funzionare. Qual è esattamente la relazione tra l'URL utilizzato nell'HTML e il pattern in karma.conf.js? Ad esempio, se ho un'immagine in test / assets / img.png , quale dovrebbe essere l'URL?
Jeanluca Scaljeri

1
Mi scuso, questa soluzione dovrebbe funzionare ma ho continuato a ricevere anche errori 404. Credo che questo sia correlato alla mancanza di implementazione in Karma e sono sorpreso che siamo gli unici a ottenerlo. Ho trovato un modo (un po 'complicato) per farlo funzionare, ma dovrai eseguire un altro server (web) in parallelo a Karma. Modificherò la mia risposta. ;)
glepretre

3
In risposta a EDIT2, se esegui karma su una porta personalizzata puoi evitare i 404 collegandoti all'URI completo del server karma: (assumendo port: 9999)proxies = { '/images/': 'http://localhost:9999/base/images/' };
Josh

18

Il pezzo confuso del puzzle per me era la cartella virtuale "base". Se non sai che deve essere incluso nei percorsi delle risorse dei tuoi dispositivi, troverai difficile eseguire il debug.

Secondo la documentazione di configurazione

Per impostazione predefinita, tutti gli asset vengono forniti su http: // localhost: [PORT] / base /

Nota: questo potrebbe non essere vero per altre versioni: sono su 0.12.14 e ha funzionato per me, ma i documenti 0.10 non lo menzionano.

Dopo aver specificato il modello dei file:

{ pattern: 'Test/images/*.gif', watched: false, included: false, served: true, nocache: false },

Potrei usarlo nel mio dispositivo:

<img src="base/Test/images/myimage.gif" />

E a quel punto non avevo bisogno del proxy.


Questo è il fattore decisivo. La risposta principale lo spiega ma molto brevemente: grazie per l'espansione.
jlb

10

Puoi creare middleware generico all'interno del tuo karma.conf.js - un po 'esagerato ma ha fatto il lavoro per me

Per prima cosa definisci immagini fittizie 1px (ho usato base64):

const DUMMIES = {
  png: {
    base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
    type: 'image/png'
  },
  jpg: {
    base64: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigD//2Q==',
    type: 'image/jpeg'
  },
  gif: {
    base64: 'data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=',
    type: 'image/gif'
  }
};

Quindi definire la funzione middleware:

function surpassImage404sMiddleware(req, res, next) {
  const imageExt = req.url.split('.').pop();
  const dummy = DUMMIES[imageExt];

  if (dummy) {
    // Table of files to ignore
    const imgPaths = ['/another-cat-image.png'];
    const isFakeImage = imgPaths.indexOf(req.url) !== -1;

    // URL to ignore
    const isCMSImage = req.url.indexOf('/cms/images/') !== -1;

    if (isFakeImage || isCMSImage) {
      const img = Buffer.from(dummy.base64, 'base64');
      res.writeHead(200, {
        'Content-Type': dummy.type,
        'Content-Length': img.length
      });
      return res.end(img);
    }
  }
  next();
}

Applica il middleware nel tuo karma conf

{
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    middleware: ['surpassImage404sMiddleware'],
    plugins: [
      ...
      {'middleware:surpassImage404sMiddleware': ['value', surpassImage404sMiddleware]}
    ],
    ...
}

L'hai mai trasformato in un vero e proprio pacchetto? Mi piacerebbe installare solo npm
Akxe

Se vuoi sopprimere tutte le richieste di immagini, controlla req.headers.acceptper vedere se contiene imagee restituisci 204 se lo fa.
Cleong

9

Sulla base della risposta di @ glepretre, ho creato un file .png vuoto e l'ho aggiunto alla configurazione per nascondere gli avvisi 404:

proxies: {
  '/img/generic.png': 'test/assets/img/generic.png'
}

3

Per risolvere il problema, karma.conf.jsassicurati di puntare al file servito con i tuoi proxy:

files: [
  { pattern: './src/img/fake.jpg', watched: false, included: false, served: true },
],
proxies: {
  '/image.jpg': '/base/src/img/fake.jpg',
  '/fake-avatar': '/base/src/img/fake.jpg',
  '/folder/0x500.jpg': '/base/src/img/fake.jpg',
  '/undefined': '/base/src/img/fake.jpg'
}

3

Anche se è un vecchio thread, mi ci sono volute un paio d'ore per far sì che la mia immagine venisse effettivamente servita dal karma per eliminare il 404. I commenti non erano abbastanza approfonditi. Credo di poter chiarire la soluzione con questo screenshot. Essenzialmente l'unica cosa che mancava a molti commenti è il fatto che il valore del proxy deve iniziare con "/ base" , anche se base non si trova in nessuno dei miei percorsi di cartella, né nelle mie richieste.

("base" senza il taglio in avanti ha portato il karma a restituire una RICHIESTA DI 400 BAD)

Ora, dopo aver eseguito ng test , posso pubblicare con successo "./src/assets/favicon.png" dall'URL: http: // localhost: 9876 / test / dummy.png

Nel mio progetto sto usando le seguenti versioni del pacchetto npm:

  • karma v4.3.0
  • jasmine-core v3.2.1
  • karma-jasmine v1.1.2
  • @ angular / cli v8.3.5
  • angolare v8.2.7

Struttura del progetto VSCode con posizioni delle risorse karma.conf.js.


Questa intuizione è stata particolarmente utile per me per capire che c'è una differenza (dal punto di vista di Karma) per servire i file all'interno dell'area di base e dall'esterno dell'area di base (che era in definitiva il mio problema), che poi mi ha portato a github.com/karma -runner / karma / issues / 2703 . Quindi, grazie per questo chiarimento.
dpmott

2

Se hai il percorso di root da qualche parte nel tuo file di configurazione puoi anche usare qualcosa del genere:

proxies: {
  '/bower_components/': config.root + '/client/bower_components/'
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.