Jest: global antes de todos

Criado em 15 jun. 2017  ·  36Comentários  ·  Fonte: facebook/jest

existe alguma maneira para um global beforeAll?

Eu posso definir beforeAll em cada arquivo de teste, mas isso executará o beforeAll uma vez para cada arquivo de teste.

existe algum beforeAll global que será executado uma vez e terminará antes do início do primeiro teste?

Comentários muito úteis

+1 para configuração global. Como outros usuários, gostaria de configurar e desmontar o aplicativo/DB apenas uma vez.

Todos 36 comentários

Você já viu setupFiles ?

Para referência, meu projeto usa setupFiles assim:

package.json

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

./private/mocks/runtime.js

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

FYI Stack Overflow pode ser um lugar melhor para esse tipo de pergunta. (pergunta sobre o uso em vez de um relatório de bug / solicitação de recurso).

Também cancelei a inscrição deste problema, portanto, não receberei nenhuma notificação se você responder.

Estou usando create-react-app.
e setupFiles são executados novamente para cada arquivo de teste.

dando uma resposta que não está correta e fechando um problema depois disso. bravo!

@cpojer @ashtonsix Eu não acho que isso deva ser fechado e a resposta não esteja correta, tanto setupFiles quanto setupTestFrameworkScriptFile são executados para cada suíte de teste, portanto, não há um "global" beforeAll onde podemos definir pensa como limpar um banco de dados de teste antes de testar

Você pode ter um pretest em package.json?

@ Negan1911 - talvez, mas é difícil dizer o que significa no OP. Você pode considerar a criação de um segundo problema se achar que é um recurso útil e quiser trazer mais clareza a essa solicitação de recurso?

@cpojer @ashtonsix Se bem entendi, atualmente não é possível ter configuração global e desmontagem como discutido aqui no Mocha .
O caso de uso que eu (e provavelmente o OP) tenho é que eu quero executar um servidor e só então todos os meus testes de integração (e provavelmente depois que todos eles tiverem executado, solte o banco de dados de teste).
Você tem algum conselho ou boas práticas para fazer isso?
O que eu descobri é que as pessoas dizem principalmente para inicializar um servidor e fechá-lo para cada suíte de teste em "local" beforeAll/afterAll, por exemplo, aqui por @kentcdodds , mas implica muita duplicação, não?

+1 em ter uma configuração global, no meu caso de uso também quero executar um servidor proxy

@ashtonsix pelo que vale, o OP foi claro na minha opinião. Gostaria que esta questão fosse reaberta.

Você pode criar um jest-environment personalizado, ver jest-environment-node ou jest-environment-jsdom e subclassificá-lo. Ele deve permitir que você configure o ambiente da maneira que desejar. Discutimos a adição de um gancho assíncrono para isso também, e estou feliz em aceitar PRs para isso.

+1 Queria experimentar o jest vindo do mocha e fiquei impressionado com a facilidade de jest-codemods e os documentos, até que fiquei preso com esse mesmo problema.

Cada primeiro describe de cada arquivo separado estava demorando surpreendentemente para ser executado. Acontece que a configuração foi - como explicado pelos comentários anteriores - executada uma vez por arquivo, resultando em toneladas de operações desnecessárias e demoradas, como DROP DATABASE , CREATE DATABASE e muito mais.

Infelizmente, não há solução alternativa nos documentos (que por sua vez me trouxe aqui), exceto para executar node setup.js && jest que não é o ideal.

+1 para configuração global. Como outros usuários, gostaria de configurar e desmontar o aplicativo/DB apenas uma vez.

+1

Corrigido em #4506

Existem as seguintes opções de brincadeira globalSetup e globalTeardown . https://facebook.github.io/jest/docs/en/configuration.html#globalsetup -string

Eu tentei usar globalSetup , mas continuo recebendo o seguinte erro .. Acho que essa opção pode fazer o truque @shai32. No entanto, não consigo fazê-lo funcionar 🤣 ...

"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

Ainda não foi lançado. Jest 22 chegando qualquer dia agora 🙂

Corrigido em #4506

Eu sei que está vinculado, mas para quem procura: https://github.com/facebook/jest/pull/4716

@btav são 2 bugs 😓

  1. você tem que usar o caminho absoluto por enquanto, ou (""../../../~ root ~")
  2. os avisos de validação são falsos positivos

veja aqui
também #5093

bugs devem ser corrigidos com #5095 #5096

Isso pode ser usado para definir uma variável global? Eu tentei, mas não funciona .... isso é por design?

Meu caso de uso é que tenho uma função de log personalizada que desejo definir globalmente. Eu tentei _setup.test.js , mas minhas variáveis ​​globais não são transferidas.

@zwhitchcox use a opção de configuração setupFiles: https://facebook.github.io/jest/docs/en/configuration.html#setupfiles -array

Às vezes, pode ser útil compartilhar uma variável global configurada por meio de uma função assíncrona. Por exemplo, seria útil configurar o navegador do manipulador de marionetes uma vez em globalSetup e, em seguida, gerar uma nova página em cada teste/conjunto de testes.

@tdenovan Isso é exatamente o que estou tentando fazer agora. Mas não parece funcionar. Eu já fiz isso em mocha antes e foi fácil, mas com brincadeira acho que preciso descobrir outras maneiras.
Esta é a minha configuração jest

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

Mas não consigo acessar o bot nos meus casos de teste.

GGWP! Acabei de resolver.

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

e alguém está se perguntando o que é 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();
  },
});

Há um guia para marionetista no site: https://facebook.github.io/jest/docs/en/puppeteer.html

Sim, mas isso sugere que é possível definir um global no método assíncrono globalSetup, o que, de acordo com o acima, não parece ser b

@SimenB ahh .. cara ... Eu estava tentando descobrir isso e também estava nos documentos de brincadeira por um bom tempo e nunca notei essa seção. Desperdício do meu tempo.

Eu tenho um problema em que os objetos globais que defini em globalSetup não estão disponíveis se houver vários conjuntos de testes executados em paralelo (isso é por padrão). Executando um único teste de suíte, os objetos estão disponíveis ou se eu definir --runInBand para executar testes em série. Como posso obter acesso às variáveis ​​que defini em globalSetup se os testes forem executados em paralelo?
Tentei o exemplo usado acima (usando process object) e também tentei a versão em que estou usando um TestEnvironment personalizado, mas sem sorte:

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;

Isso está obtendo o allThemesCss do globalSetup.js e certificando-se de que ele esteja passando para as suítes de teste.

@ovidiu-lapadus Consegui fazer o globalSetup funcionar usando process em vez de global. Funciona com e sem --runInBand . Por exemplo

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

E para a equipe jest, não sei por que global s são indefinidos em testes ( babel-jest 22.2.2 ), mas definidos no globalTeardown.js . Talvez seja um bug. Por enquanto vou usar apenas process . Saúde!

Obrigado @cellis você salvou meu dia! Eu tenho batido minha cabeça contra uma parede tentando entender porque global.FOO não estava funcionando. process.FOO faz o truque :-)

@kalutheo Há algumas ressalvas ao usar o process.FOO. Primeiro, não acho que você possa fazer variáveis ​​profundamente aninhadas em process ou process.env. Eu descobri uma maneira ainda melhor de fazer os globais funcionarem, mas eu estava esperando para publicá-la. O que eu fiz foi usar o pacote jest-environment para criar meu próprio dbEnvironment . Lá, eu verifico se os dbs globais estão definidos e, se não, eu os redefino. O ambiente de banco de dados é executado apenas para testes de banco de dados, tenho outra configuração para testes apenas de frontend. Dessa forma, não perco tempo executando testes de banco de dados para cada mudança de frontend. Em segundo lugar, eu tenho uma maneira de configurar vários dbs de "réplica" que estão sempre quentes - você não precisa migrar ou despejá-los em cada execução do jest, pois eu os migro junto com o dev db (você pode ver vislumbres de isso na essência que compartilhei ), o que permite que os testes sejam executados ainda mais rápido. Configurei um pool dessas réplicas para obter o máximo de paralelismo nos testes. É meio que documentado na documentação do jest, mas não explicado bem o suficiente. De qualquer forma, aqui está a essência: https://gist.github.com/cellis/08cc332dacf9a548005e8cf35d4b16e2

@ovidiu-lapadus Após uma inspeção mais detalhada, acho que talvez seu problema seja que você chamou super.setup() antes de atribuir seus globais. Por favor, veja a essência que postei acima para uma solução de trabalho.

@cellis obrigado por essas informações valiosas. Vou tentar com um ambiente personalizado como você descreveu

Pessoal, globalSetup não deveria incluir aqui todas as tarefas pesadas como babel-polyfill , combinar com chai , exigir jest-extended ?
Parece que globalSetup funciona de maneira muito diferente de setupTestFrameworkScriptFile e o que funcionou lá não funciona em globalSetup .
Eu sei, que todo caso de teste jest é executado em seu ambiente snadboxed, mas não fazer as coisas em setupTestFrameworkScriptFile faz com que o teste seja muito lento.

Mocha: 9s
Jest: 60s, no modo de relógio: 170s-200s

?

Usar process é um hack que provavelmente vai quebrar (é um bug).

Você provavelmente quer seguir #7184

Este não é um beforeAll() global, conforme solicitado na pergunta, mas com isso, você evita facilmente a duplicação de código. Você pode criar um ambiente de nó, que será configurado para todos os seus arquivos de teste: https://stackoverflow.com/a/61260044/4934640


Atualizar

Acabei de descobrir que posso definir uma variável de ambiente em globalSetup , o que significa que posso compartilhar o endereço do servidor entre os cases/suites/files de testes: https://github.com/facebook/jest/issues/7184# emitir comentário

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

ianp picture ianp  ·  3Comentários

gustavjf picture gustavjf  ·  3Comentários

mmcgahan picture mmcgahan  ·  3Comentários

jardakotesovec picture jardakotesovec  ·  3Comentários

rosiakr picture rosiakr  ·  3Comentários