Jest: global vorAll

Erstellt am 15. Juni 2017  ·  36Kommentare  ·  Quelle: facebook/jest

Gibt es eine Möglichkeit für ein globales BeforeAll?

Ich kann beforeAll in jeder Testdatei definieren, aber das wird beforeAll einmal für jede Testdatei ausführen.

Gibt es ein globales BeforeAll, das einmal ausgeführt wird und vor dem ersten Teststart endet?

Hilfreichster Kommentar

+1 für globales Setup. Wie andere Benutzer möchte ich die App/DB nur einmal einrichten und herunterfahren.

Alle 36 Kommentare

Hast du setupFiles gesehen?

Als Referenz verwendet mein Projekt setupFiles wie folgt:

package.json

{
  "jest": {
    "setupFiles": [
      "./private/mocks/runtime.js"
    ]
  }
}

./private/mocks/runtime.js

global.__meteor_runtime_config__ = {ROOT_URL: 'localhost'};

FYI Stack Overflow könnte ein besserer Ort für diese Art von Frage sein. (Frage zur Verwendung anstelle eines Fehlerberichts / Funktionswunschs).

Außerdem habe ich mich von dieser Ausgabe abgemeldet und erhalte daher keine Benachrichtigungen, wenn Sie antworten.

Ich verwende create-react-app.
und setupFiles werden für jede Testdatei erneut ausgeführt.

eine Antwort geben, die nicht korrekt ist, und ein Problem danach schließen. Bravo!

@cpojer @ashtonsix Ich denke nicht, dass dies geschlossen werden sollte und die Antwort nicht korrekt ist, sowohl setupFiles als auch setupTestFrameworkScriptFile läuft für jede Testsuite, daher gibt es kein "globales" beforeAll wo wir einstellen können, wie das Reinigen einer Testdatenbank vor dem Testen

Sie können ein pretest in package.json haben?

@ Negan1911 - vielleicht, aber es ist schwer zu sagen, was im OP gemeint ist. Sie könnten in Betracht ziehen, ein zweites Problem zu erstellen, wenn Sie der Meinung sind, dass es sich um eine nützliche Funktion handelt und Sie mehr Klarheit in diese Funktionsanfrage bringen möchten?

@cpojer @ashtonsix Wenn ich es richtig verstehe, ist es derzeit nicht möglich, ein globales Setup und Teardown zu haben, wie es hier in Mocha besprochen wird.
Der Anwendungsfall, den ich (und wahrscheinlich das OP) habe, ist, dass ich einen Server ausführen möchte und erst dann alle meine Integrationstests (und wahrscheinlich, nachdem alle ausgeführt wurden, die Test-DB löschen).
Habt ihr Tipps oder Best Practices dafür?
Was ich gefunden habe, sind Leute, die meistens sagen, dass sie einen Server starten und ihn für jede Testsuite in "local" beforeAll/afterAll schließen sollen, zB hier von @kentcdodds , aber impliziert eine Menge Duplizierung, nein?

+1 zu einem globalen Setup, in meinem Anwendungsfall möchte ich auch einen Proxy-Server ausführen

@ashtonsix für das, was es wert ist, das OP war meiner Meinung nach klar. Ich möchte, dass dieses Thema wieder geöffnet wird.

Sie können ein benutzerdefiniertes jest-environment erstellen, siehe jest-environment-node oder jest-environment-jsdom und davon eine Unterklasse erstellen. Es sollte Ihnen ermöglichen, die Umgebung so einzurichten, wie Sie es möchten. Wir haben darüber gesprochen, auch dafür einen asynchronen Hook hinzuzufügen, und ich nehme gerne PRs dafür an.

+1 Wollte einen Scherz aus Mokka ausprobieren und war beeindruckt von der Leichtigkeit von jest-codemods und den Dokumenten, bis ich mit demselben Problem feststeckte.

Die Ausführung jedes ersten describe jeder einzelnen Datei dauerte überraschend lange. Es stellte sich heraus, dass das Setup - wie in früheren Kommentaren erläutert - einmal pro Datei ausgeführt wurde, was zu Tonnen unnötiger zeitaufwändiger Operationen wie DROP DATABASE , CREATE DATABASE und mehr führte.

Leider gibt es in den Dokumenten (die mich wiederum hierher gebracht haben) keine Problemumgehung, außer node setup.js && jest auszuführen, was nicht ideal ist.

+1 für globales Setup. Wie andere Benutzer möchte ich die App/DB nur einmal einrichten und herunterfahren.

+1

Behoben in #4506

Es gibt die folgenden Scherzoptionen globalSetup und globalTeardown . https://facebook.github.io/jest/docs/en/configuration.html#globalsetup -string

Ich habe versucht, globalSetup zu verwenden, erhalte jedoch weiterhin den folgenden Fehler. Ich denke, diese Option könnte den Trick @shai32 ausführen. Allerdings bekomme ich es einfach nicht hin 🤣 ...

"jest": "^21.2.1"
 "jest": {
    "globalSetup": "./jest-config.js"
  }



md5-d3a1dcf99642fcf0b9c99c838aadb689



● Validation Warning:

  Unknown option "globalSetup" with value "./jest-setup.js" was found.
  This is probably a typing mistake. Fixing it will remove this message.

  Configuration Documentation:
  https://facebook.github.io/jest/docs/configuration.html

Es wurde noch nicht veröffentlicht. Scherz 22 kommen jetzt jeden Tag 🙂

Behoben in #4506

Ich weiß, dass es darin verlinkt ist, aber für alle, die suchen: https://github.com/facebook/jest/pull/4716

@btav das sind 2 Bugs 😓

  1. Sie müssen jetzt den absoluten Pfad verwenden, oder ("../../../~ root ~")
  2. Die Validierungswarnungen sind falsch positiv

siehe hier
auch #5093

Fehler sollten mit #5095 #5096 behoben werden

Kann dies verwendet werden, um eine globale Variable zu setzen? Ich habe es versucht, aber es funktioniert nicht ... ist das beabsichtigt?

Mein Anwendungsfall ist, dass ich eine benutzerdefinierte Protokollfunktion habe, die ich global festlegen möchte. Ich habe _setup.test.js versucht, aber meine globalen Variablen werden nicht übertragen.

@zwhitchcox verwende die setupFiles-Konfigurationsoption: https://facebook.github.io/jest/docs/en/configuration.html#setupfiles -array

Manchmal kann es nützlich sein, eine globale Variable zu teilen, die über eine asynchrone Funktion eingerichtet wird. Beispielsweise wäre es sinnvoll, den Puppeteer-Browser einmal in globalSetup einzurichten und dann in jedem Test / jeder Testsuite eine neue Seite zu erstellen.

@tdenovan Genau das versuche ich gerade zu tun. Aber es scheint nicht zu funktionieren. Ich habe das schon einmal in Mokka gemacht und es war ein Kinderspiel, aber im Scherz denke ich, ich muss andere Wege finden.
Das ist meine Scherzkonfiguration

"jest": {
    "verbose": true,
    "testEnvironment": "node",
    "globalSetup": "<rootDir>/scripts/testSetup.js",
    "globalTeardown": "<rootDir>/scripts/testTeardown.js"
  },
// globalSetup.js
module.exports = async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  bot = Bot(browser, page);
  await bot.goto(bot.baseUrl);
  global.bot = bot;
}

Aber ich kann in meinen Testfällen nicht auf den Bot zugreifen.

GUTES SPIEL, GUT GESPIELT! Habe es gerade gelöst.

"e2e": "jest --testRegex '.*.e2e.js'"
// globalTeardown.js
module.exports = async () => {
  if (process.testSetup) {
    process.testSetup.bot.close();
  }
}

 process.testSetup = { bot };
// and then im my tests
const { bot } = process.testSetup;

und irgendjemand fragt sich, was Bot ist,

const Bot = (browser, page) => ({
  browser: browser,
  page: page,
  baseUrl: 'http://localhost:4000',
  user: {
    name: faker.name.findName(),
    email: faker.internet.email(),
    password: 'Test<strong i="13">@123</strong>',
  },
  oldUser: {
    email: '[email protected]',
    password: 'Test<strong i="14">@123</strong>',
  },
  clearSession: async () => {
    await page.evaluate(() => sessionStorage.clear());
  },
  goto: async (url) => {
    await page.goto(url);
  },
  clickButton: async (id) => {
    await page.waitForSelector(id);
    await page.click(id);
  },
  checkText: async (expect, id, text) => {
    await page.waitForSelector(id);
    const elText = await page.$eval(id, el => el.innerHTML);
    expect(elText).toContain(text);
  },
  type: async (id, text) => {
    await page.waitForSelector(id);
    await page.$eval(id, el => el.value = '');
    await page.type(id, text);
  },
  wait: async () => {
    await page.waitForNavigation();
  },
  close: () => {
    browser.close();
  },
});

Es gibt eine Anleitung für Puppenspieler auf der Website: https://facebook.github.io/jest/docs/en/puppeteer.html

Ja, aber das deutet darauf hin, dass das Festlegen eines globalen in der asynchronen Methode globalSetup möglich ist, was nach dem oben Gesagten nicht b zu sein scheint

@SimenB ahh .. Mann ... Ich habe versucht, das herauszufinden und war auch ziemlich lange in den Scherzdokumenten und habe diesen Abschnitt nie bemerkt. Zeitverschwendung.

Ich habe ein Problem, bei dem die globalen Objekte, die ich in globalSetup festgelegt habe, nicht verfügbar sind, wenn mehrere Testsuiten parallel ausgeführt werden (dies ist standardmäßig der Fall). Wenn ich einen einzelnen Suite-Test ausführe, sind die Objekte verfügbar oder wenn ich --runInBand setze, um Tests seriell auszuführen. Wie bekomme ich Zugriff auf die Variablen, die ich in globalSetup gesetzt habe, wenn Tests parallel laufen?
Ich habe das oben verwendete Beispiel ausprobiert (unter Verwendung des Prozessobjekts) und ich habe auch die Version ausprobiert, in der ich eine benutzerdefinierte Testumgebung verwende, aber ohne Erfolg:

const PuppeteerJsdomEnvironment = require('jest-puppe-shots/lib/jsdom-environment');

class JestPuppeShotsEnv extends PuppeteerJsdomEnvironment {

  async setup(config) {
    await super.setup(config);
    const { allThemesCss } = global;

    // make the allThemesCss object available in test suites
    Object.assign(this.global, {
      allThemesCss
    });
  }
}

module.exports = JestPuppeShotsEnv;

Dies ruft das allThemesCss aus globalSetup.js ab und stellt sicher, dass es an Testsuiten weitergegeben wird.

@ovidiu-lapadus Ich konnte globalSetup zum Laufen bringen, indem ich process anstelle von global verwendet habe. Es funktioniert mit und ohne --runInBand . Z.B

// globalSetup.js
module.exports = async () => {
  process.FOOT = 'BALL';
};
// globalTeardown.js
module.exports = async () => {
  console.log(process.FOOT) // BALL 
};
// some.test.js
it('expects 1 to be 1', () => {
    expect(1).toBe(1);
     console.log(process.FOOT); // BALL
});

Und für das Jest-Team bin ich mir nicht sicher, warum global s in Tests ( babel-jest 22.2.2 ) undefiniert sind, aber in globalTeardown.js definiert sind. Vielleicht ist es ein Fehler. Im Moment verwende ich einfach process . Prost!

Danke @cellis , du hast meinen Tag gerettet! Ich habe meinen Kopf gegen eine Wand geschlagen und versucht zu verstehen, warum global.FOO nicht funktioniert hat. process.FOO reicht aus :-)

@kalutheo Es gibt ein paar Vorbehalte bei der Verwendung von process.FOO. Erstens glaube ich nicht, dass Sie tief verschachtelte Variablen in process oder process.env ausführen können. Ich habe einen noch besseren Weg gefunden, um Globals zum Laufen zu bringen, aber habe ich darauf gewartet, ihn zu veröffentlichen. Was ich getan habe, ist das Paket jest-environment zu verwenden, um mein eigenes dbEnvironment zu erstellen. Dort überprüfe ich, ob globale Datenbanken definiert werden sollen, und wenn nicht, definiere ich sie neu. Die Datenbankumgebung wird nur für DB-Tests ausgeführt, ich habe eine andere Konfiguration nur für Frontend-Tests. Auf diese Weise verschwende ich keine Zeit damit, db-Tests für jede Frontend-Änderung auszuführen. Zweitens habe ich eine Möglichkeit, mehrere "Replikat"-DBs einzurichten, die immer heiß sind - Sie müssen sie nicht bei jedem Scherzlauf migrieren oder ablegen, da ich sie zusammen mit der Dev-DB migriere (Sie können Einblicke in dies im Wesentlichen habe ich geteilt ), wodurch die Tests noch schneller ausgeführt werden können. Ich richte einen Pool dieser Nachbildungen ein, damit ich in den Tests maximale Parallelität erzielen kann. Es ist irgendwie in der Scherzdokumentation dokumentiert, aber nicht gut genug erklärt. Wie auch immer, hier ist das Wesentliche: https://gist.github.com/cellis/08cc332dacf9a548005e8cf35d4b16e2

@ovidiu-lapadus Bei näherer Betrachtung denke ich, dass Ihr Problem vielleicht darin besteht, dass Sie super.setup() angerufen haben, bevor Sie Ihre Globals zugewiesen haben. Bitte sehen Sie sich den Inhalt an, den ich oben gepostet habe, um eine funktionierende Lösung zu finden.

@cellis Danke für diese wertvollen Informationen. Ich werde es mit einer benutzerdefinierten Umgebung versuchen, wie Sie beschrieben haben

Leute, sollte globalSetup hier nicht alle Hebeaufgaben wie babel-polyfill , kombinieren mit chai , erfordern jest-extended ?
Scheint, dass globalSetup ganz anders funktioniert als setupTestFrameworkScriptFile und was dort funktioniert hat, funktioniert nicht in globalSetup .
Ich weiß, dass jeder Scherz-Testfall in seiner Snadbox-Umgebung ausgeführt wird, aber wenn man die Dinge nicht in setupTestFrameworkScriptFile macht, läuft der Test seeeehr langsam.

Mokka: 9s
Scherz: 60s, im Uhrmodus: 170s-200s

?

Die Verwendung process ist ein Hack, der wahrscheinlich kaputt geht (es ist ein Fehler).

Sie möchten wahrscheinlich #7184 folgen

Dies ist kein globales beforeAll() , wie in der Frage gefragt, aber damit vermeiden Sie auf einfache Weise Codeduplizierung. Sie können eine Knotenumgebung erstellen, die für alle Ihre Testdateien eingerichtet wird: https://stackoverflow.com/a/61260044/4934640


Aktualisieren

Ich finde gerade heraus, dass ich eine Umgebungsvariable auf globalSetup setzen kann, was bedeutet, dass ich die Serveradresse zwischen den Testfällen/Suiten/Dateien teilen kann: https://github.com/facebook/jest/issues/7184# AusgabeKommentar -612003555

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen