Jest: global avant tout

Créé le 15 juin 2017  ·  36Commentaires  ·  Source: facebook/jest

y a-t-il un moyen pour un avant-tout mondial ?

Je peux définir beforeAll dans chaque fichier de test, mais cela exécutera le beforeAll une fois pour chaque fichier de test.

y a-t-il un avant-tout global qui sera exécuté une fois et se terminera avant le début du premier test ?

Commentaire le plus utile

+1 pour la configuration globale. Comme d'autres utilisateurs, j'aimerais configurer et supprimer l'application/la base de données une seule fois.

Tous les 36 commentaires

Avez-vous vu setupFiles ?

Pour référence, mon projet utilise setupFiles comme ceci :

package.json

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

./private/mocks/runtime.js

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

FYI Stack Overflow pourrait être un meilleur endroit pour ce genre de question. (question sur l'utilisation au lieu d'un rapport de bogue / demande de fonctionnalité).

De plus, je me suis désabonné de ce problème, donc je ne recevrai aucune notification si vous répondez.

J'utilise create-react-app.
et setupFiles s'exécutent à nouveau pour chaque fichier de test.

donner une réponse qui n'est pas correcte et fermer un problème après. Bravo!

@cpojer @ashtonsix Je ne pense pas que cela devrait être fermé et la réponse n'est pas correcte, les deux setupFiles ou setupTestFrameworkScriptFile s'exécutent pour chaque suite de tests, donc il n'y a pas de "global" avantTous où nous pouvons définir pense comme nettoyer une base de données de test avant de tester sur

Vous pouvez avoir un pretest dans package.json ?

@ Negan1911 - peut-être, mais il est difficile de dire ce que signifie le PO. Vous pourriez envisager de créer un deuxième problème si vous pensez qu'il s'agit d'une fonctionnalité utile et que vous souhaitez apporter plus de clarté à cette demande de fonctionnalité ?

@cpojer @ashtonsix Si je comprends bien, il n'est actuellement pas possible d'avoir une configuration et un démontage globaux comme discuté ici dans Mocha .
Le cas d'utilisation que j'ai (et probablement l'OP) est que je veux exécuter un serveur et seulement alors tous mes tests d' intégration (et probablement après que tous aient exécuté la base de données de test).
Avez-vous des conseils ou des bonnes pratiques pour le faire?
Ce que j'ai trouvé, c'est que les gens disent surtout de démarrer un serveur et de le fermer pour chaque suite de tests en "local" beforeAll/afterAll, par exemple ici par @kentcdodds , mais cela implique beaucoup de duplication, non ?

+1 pour avoir une configuration globale, dans mon cas d'utilisation, je veux également exécuter un serveur proxy

@ashtonsix pour ce que ça vaut, l'OP était clair à mon avis. J'aimerais que ce sujet soit rouvert.

Vous pouvez créer un jest-environment personnalisé, voir jest-environment-node ou jest-environment-jsdom et le sous-classer. Cela devrait vous permettre de configurer l'environnement comme vous le souhaitez. Nous avons également discuté de l'ajout d'un crochet asynchrone pour cela, et je suis heureux d'accepter les relations publiques pour cela.

+1 Je voulais essayer la plaisanterie venant de moka et j'ai été impressionné par la facilité de jest-codemods et les docs, jusqu'à ce que je sois coincé avec ce même problème.

Chaque premier describe de chaque fichier séparé prenait étonnamment longtemps à s'exécuter. Il s'avère que la configuration était - comme expliqué dans les commentaires précédents - exécutée une fois par fichier, ce qui entraînait des tonnes d'opérations fastidieuses telles que DROP DATABASE , CREATE DATABASE , etc.

Malheureusement, il n'y a pas de solution de contournement dans la documentation (qui m'a amené ici), sauf pour exécuter node setup.js && jest , ce qui n'est pas idéal.

+1 pour la configuration globale. Comme d'autres utilisateurs, j'aimerais configurer et supprimer l'application/la base de données une seule fois.

+1

Corrigé dans # 4506

Il existe les options de plaisanterie suivantes globalSetup et globalTeardown . https://facebook.github.io/jest/docs/en/configuration.html#globalsetup -string

J'ai essayé d'utiliser globalSetup , mais je continue à avoir l'erreur suivante... Je pense que cette option pourrait faire l'affaire @shai32. Cependant, je n'arrive pas à le faire fonctionner 🤣 ...

"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

Il n'a pas encore été publié. Jest 22 arrive tous les jours maintenant 🙂

Corrigé dans # 4506

Je sais que c'est lié là-dedans, mais pour tous ceux qui cherchent : https://github.com/facebook/jest/pull/4716

@btav ça fait 2 bugs 😓

  1. vous devez utiliser le chemin absolu pour l'instant, ou (""../../../~ root ~")
  2. les avertissements de validation sont des faux positifs

voir ici
aussi #5093

les bogues devraient être corrigés avec #5095 #5096

Cela peut-il être utilisé pour définir une variable globale ? J'ai essayé, mais ça ne marche pas... est-ce intentionnel ?

Mon cas d'utilisation est que j'ai une fonction de journal personnalisée que je souhaite définir globalement. J'ai essayé _setup.test.js , mais mes variables globales ne sont pas transférées.

@zwhitchcox utilise l'option de configuration setupFiles : https://facebook.github.io/jest/docs/en/configuration.html#setupfiles -array

Parfois, il peut être utile de partager une variable globale configurée via une fonction asynchrone. Par exemple, il serait utile de configurer le navigateur marionnettiste une fois dans globalSetup, puis de générer une nouvelle page dans chaque test / suite de tests.

@tdenovan C'est exactement ce que j'essaie de faire en ce moment. Mais cela ne semble pas fonctionner. Je l'ai déjà fait dans du moka et c'était un jeu d'enfant, mais en plaisantant, je pense que je dois trouver d'autres moyens.
C'est ma config de plaisanterie

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

Mais je ne peux pas accéder au bot dans mes cas de test.

BELLE PARTIE, BIEN JOUÉ! Je viens de le résoudre.

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

et tout le monde se demande ce qu'est un bot,

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

Il y a un guide pour marionnettiste sur le site : https://facebook.github.io/jest/docs/en/puppeteer.html

Oui, mais cela suggère que la définition d'un global dans la méthode asynchrone globalSetup est possible, ce qui, d'après ce qui précède, ne semble pas être b

@SimenB ahh .. mec ... J'essayais de comprendre cela et j'ai également été dans les docs de plaisanterie pendant assez longtemps et je n'ai jamais remarqué cette section. Perte de mon temps.

J'ai un problème où les objets globaux que j'ai définis dans globalSetup ne sont pas disponibles s'il y a plusieurs suites de tests exécutées en parallèle (c'est par défaut). En exécutant un seul test de suite, les objets sont disponibles ou si je définis --runInBand pour exécuter des tests en série. Comment puis-je accéder aux variables que j'ai définies dans globalSetup si les tests s'exécutent en parallèle ?
J'ai essayé l'exemple utilisé ci-dessus (en utilisant l'objet processus) et j'ai également essayé la version où j'utilise un TestEnvironment personnalisé mais sans succès :

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;

Cela permet d'obtenir le allThemesCss de globalSetup.js et de s'assurer qu'il est transmis aux suites de tests.

@ovidiu-lapadus J'ai pu faire fonctionner globalSetup en utilisant process au lieu de global. Cela fonctionne avec et sans --runInBand . Par exemple

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

Et pour l'équipe de blagues, je ne sais pas pourquoi global s ne sont pas définis dans les tests ( babel-jest 22.2.2 ), mais définis dans le globalTeardown.js . C'est peut-être un bug. Pour l'instant, je vais juste utiliser process . Acclamations!

Merci @cellis tu m'as sauvé la journée ! Je me suis cogné la tête contre un mur en essayant de comprendre pourquoi global.FOO ne fonctionnait pas. process.FOO fait l'affaire :-)

@kalutheo Il y a quelques mises en garde à l'utilisation de process.FOO. Tout d'abord, je ne pense pas que vous puissiez faire des variables profondément imbriquées sur process ou process.env. J'ai trouvé un moyen encore meilleur de faire fonctionner les globals, mais j'attendais de le poster. Ce que j'ai fait, c'est utiliser le package jest-environment pour créer mon propre dbEnvironment . Là-dedans, je vérifie que les bases de données globales sont définies et si ce n'est pas le cas, je les redéfinis. L'environnement de base de données n'est exécuté que pour les tests db, j'ai une autre configuration pour les tests frontaux uniquement. De cette façon, je ne perds pas de temps à exécuter des tests db pour chaque changement d'interface. Deuxièmement, j'ai un moyen de configurer plusieurs bases de données "réplicas" qui sont toujours chaudes - vous n'avez pas besoin de les migrer ou de les vider à chaque exécution de plaisanterie, car je les migre avec la base de données dev (vous pouvez voir des aperçus de ceci dans l'essentiel que j'ai partagé), ce qui permet aux tests de s'exécuter encore plus rapidement. J'ai configuré un pool de ces répliques afin d'obtenir un parellélisme maximal dans les tests. C'est un peu documenté dans la documentation de plaisanterie, mais pas assez bien expliqué. Quoi qu'il en soit, voici l'essentiel : https://gist.github.com/cellis/08cc332dacf9a548005e8cf35d4b16e2

@ovidiu-lapadus En y regardant de plus près, je pense que votre problème est peut-être que vous avez appelé super.setup() avant d'assigner vos globales. Veuillez consulter l'essentiel que j'ai posté ci-dessus pour une solution de travail.

@cellis merci pour ces précieuses informations. Je vais essayer avec un environnement personnalisé comme vous l'avez décrit

Les gars, globalSetup n'est-il pas censé inclure ici toutes les tâches de soulèvement comme babel-polyfill , combiner avec chai , exiger jest-extended ?
Il semble que globalSetup fonctionne bien différemment de setupTestFrameworkScriptFile et ce qui a fonctionné là-bas ne fonctionne pas dans globalSetup .
Je sais que chaque cas de test de plaisanterie est exécuté dans son environnement snadboxed, mais ne pas faire les choses dans setupTestFrameworkScriptFile rend le test très lent.

Moka : 9s
Blague : 60s, en mode montre : 170s-200s

?

Utiliser process est un hack qui va probablement casser (c'est un bogue).

Vous voulez probablement suivre #7184

Ce n'est pas global beforeAll() tout comme demandé sur la question, mais avec cela, vous évitez facilement la duplication de code. Vous pouvez créer un environnement de nœud, qui sera configuré pour tous vos fichiers de tests : https://stackoverflow.com/a/61260044/4934640


Mettre à jour

Je viens de découvrir que je peux définir une variable d'environnement sur globalSetup , ce qui signifie que je peux partager l'adresse du serveur entre les cas de test/suites/fichiers : https://github.com/facebook/jest/issues/7184# issuecomment -612003555

Cette page vous a été utile?
0 / 5 - 0 notes