So beheben Sie 404 Warnungen für Bilder während des Karma-Unit-Tests


83

Ich teste eine meiner Anweisungen (anglejs) mit grunt / karma / phantomjs / jasmine. Meine Tests laufen gut

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();
    }));
    ....
});

aber ich bekomme diese 404s

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

Obwohl sie nichts tun, fügen sie der Protokollausgabe Rauschen hinzu. Gibt es eine Möglichkeit, dies zu beheben? (ohne natürlich Karmas LogLevel zu ändern, weil ich sie sehen möchte)


Bleibt es in einem anderen Browser bestehen? Ich weiß, dass es einige bekannte Probleme mit 404-Fehlern für diese Art von Anrufen in FF gibt.
Nicholas Hazel

es müssen phantomjs sein. Ich habe Chrome überprüft, das auch den 404 zeigt. Beachten Sie, dass es sich um Warnungen handelt, nicht um Fehler!
Jeanluca Scaljeri

Hilft die Verwendung von ng-src?
Eitan Peer

netter Versuch, hat aber das gleiche Ergebnis
Jeanluca Scaljeri

Antworten:


109

Das liegt daran, dass Sie Karma konfigurieren müssen, um es zu laden, und es dann auf Anfrage bedienen müssen;)

In Ihrer Datei karma.conf.js sollten Sie bereits Dateien und / oder Muster definiert haben wie:

// 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: [

],

// ...

Sie können einen Blick hier nach weiteren Informationen :)

BEARBEITEN: Wenn Sie einen NodeJS-Webserver zum Ausführen Ihrer App verwenden, können Sie dies zu karma.conf.js hinzufügen:

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

EDIT2: Wenn Sie keinen anderen Server verwenden oder verwenden möchten, können Sie einen lokalen Proxy definieren. Da Karma jedoch keinen dynamischen Zugriff auf den verwendeten Port bietet, werden Sie dies weiterhin tun, wenn Karma an einem anderen Port als 9876 (Standard) startet Holen Sie sich diese nervigen 404 ...

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

Verwandte Ausgabe: https://github.com/karma-runner/karma/issues/872


4
In meinem Fall existieren diese Bilder nicht. Die von Ihnen bereitgestellte Lösung setzt voraus, dass die Dateien vorhanden sind, oder?
Jeanluca Scaljeri

Ja natürlich! Ich glaube, ich habe es falsch verstanden. Es ist sinnvoll, 404-Fehler für nicht vorhandene Dateien zu haben, oder? Sie möchten Warnungen zu Bildern ausblenden? Ohne die Protokollstufe zu ändern, sehe ich außerdem keine Lösung, die andere Warnungen verbergen würde, die riskant wären. Warum nicht zum Beispiel leere .png-Dateien im Ordner "test / img" erstellen? :)
glepretre

Aus irgendeinem Grund kann ich es nicht zum Laufen bringen. Welche genaue Beziehung besteht zwischen der im HTML verwendeten URL und dem Muster in karma.conf.js? Wenn ich beispielsweise ein Bild in test / assets / img.png habe , wie sollte die URL lauten?
Jeanluca Scaljeri

1
Ich entschuldige mich, diese Lösung sollte funktionieren, aber ich habe auch immer wieder 404 Fehler erhalten. Ich glaube, dies hängt mit einer mangelnden Implementierung in Karma zusammen, und ich bin überrascht, dass wir die einzigen sind, die dies erreichen. Ich habe einen (etwas hackigen) Weg gefunden, um dies zum Laufen zu bringen, aber Sie müssen parallel zu Karma einen anderen (Web-) Server betreiben. Ich werde meine Antwort bearbeiten. ;)
glepretre

3
In Reaktion auf EDIT2 können Sie, wenn Sie Karma auf einem benutzerdefinierten Port ausführen, die 404s vermeiden, indem Sie eine Verknüpfung mit dem vollständigen URI des Karma-Servers herstellen: (vorausgesetzt port: 9999)proxies = { '/images/': 'http://localhost:9999/base/images/' };
Josh

18

Das verwirrende Puzzleteil war für mich der virtuelle Basisordner. Wenn Sie nicht wissen, dass dies in den Asset-Pfaden Ihrer Geräte enthalten sein muss, ist das Debuggen schwierig.

Gemäß Konfigurationsdokumentation

Standardmäßig werden alle Assets unter http: // localhost: [PORT] / base / bereitgestellt.

Hinweis: Dies gilt möglicherweise nicht für andere Versionen - ich bin auf 0.12.14 und es hat bei mir funktioniert, aber die 0.10-Dokumente erwähnen es nicht.

Nach Angabe des Dateimusters:

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

Ich könnte dies in meinem Gerät verwenden:

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

Und ich brauchte den Proxy zu diesem Zeitpunkt nicht.


Das ist der Drahtreifen. Die Top-Antwort erklärt dies aber sehr kurz - danke für die Erweiterung.
jlb

10

Sie können generische Middleware in Ihrer karma.conf.js erstellen - etwas übertrieben, aber die Arbeit für mich erledigt

Definieren Sie zuerst Dummy-1px-Bilder (ich habe base64 verwendet):

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'
  }
};

Definieren Sie dann die Middleware-Funktion:

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

Wenden Sie Middleware in Ihrem Karma Conf an

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

Haben Sie es jemals zu einem tatsächlichen Paket gemacht? Ich würde gerne nur npm installieren
Akxe

Wenn Sie alle Bildanforderungen unterdrücken möchten, überprüfen Sie einfach, req.headers.acceptob sie enthalten sind, imageund geben Sie gegebenenfalls 204 zurück.
Cleong

9

Basierend auf der Antwort von @ glepretre habe ich eine leere PNG-Datei erstellt und diese zur Konfiguration hinzugefügt, um 404-Warnungen auszublenden:

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

3

karma.conf.jsStellen Sie zur Behebung sicher, dass Sie mit Ihren Proxys auf die bereitgestellte Datei verweisen:

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

Obwohl es ein alter Thread ist, habe ich ein paar Stunden gebraucht, um mein Bild tatsächlich aus dem Karma zu bringen, um die 404 zu eliminieren. Die Kommentare waren einfach nicht gründlich genug. Ich glaube, ich kann die Lösung mit diesem Screenshot klären. Im Wesentlichen fehlten vielen Kommentaren die Tatsache, dass der Proxy-Wert mit "/ base" beginnen muss , obwohl sich base weder in einem meiner Ordnerpfade noch in meinen Anforderungen befindet.

("Basis" ohne den Schrägstrich führte dazu, dass Karma eine 400 BAD REQUEST zurückgab)

Nachdem ich ng test ausgeführt habe , kann ich "./src/assets/favicon.png" erfolgreich über die URL http: // localhost: 9876 / test / dummy.png bereitstellen

In meinem Projekt verwende ich die folgenden npm-Paketversionen:

  • Karma v4.3.0
  • Jasmin-Kern v3.2.1
  • Karma-Jasmin v1.1.2
  • @ angle / cli v8.3.5
  • eckig v8.2.7

VSCode-Projektstruktur mit den Assets-Standorten von karma.conf.js


Diese Erkenntnis war für mich besonders hilfreich, um zu verstehen, dass es (aus Karmas Sicht) einen Unterschied gibt, Dateien innerhalb des Basisbereichs und außerhalb des Basisbereichs (was letztendlich mein Problem war) bereitzustellen , was mich dann zu github.com/karma führte -Runner / Karma / Issues / 2703 . Vielen Dank für diese Klarstellung.
dpmott

2

Wenn Sie irgendwo in Ihrer Konfigurationsdatei einen Stammpfad haben, können Sie auch Folgendes verwenden:

proxies: {
  '/bower_components/': config.root + '/client/bower_components/'
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.