Companheiro de teste de desempenho para reagir e reagir nativo.
Leia os documentos
reassure-tests.sh
).gitignore
reassure-tests.sh
)measureRenders
MeasureRendersOptions
measureFunction
MeasureFunctionOptions
Tipoconfigure
funçãoresetToDefaults
funçãoVocê deseja que seu aplicativo nativo do React tenha um bom desempenho e rápido o tempo todo. Como parte desse objetivo, você perfura o aplicativo, observa padrões de renderização, aplica memórias nos lugares certos, etc. Mas é tudo manual e muito fácil de introduzir involuntariamente regressões de desempenho que só seriam pegos durante o controle de qualidade ou pior, por seus usuários .
A tranquilidade permite automatizar testes de regressão de desempenho de aplicativos nativos no React no CI ou em uma máquina local. Da mesma forma, você escreve seus testes de integração e unidade que verificam automaticamente que seu aplicativo ainda está funcionando corretamente , pode escrever testes de desempenho que verifiquem se seu aplicativo ainda está funcionando com atualização .
Você pode pensar nisso como uma biblioteca de testes de desempenho do React. De fato, a tranquilização foi projetada para reutilizar o máximo possível de testes e configuração da biblioteca de testes nativos do React.
Tranquilizar as obras medindo as características de renderização - duração e contagem - do cenário de teste que você fornece e comparando isso com a versão estável. Ele repete o cenário várias vezes para reduzir o impacto de variações aleatórias nos tempos de renderização causados pelo ambiente de tempo de execução. Em seguida, aplica análises estatísticas para determinar se as alterações do código são estatisticamente significativas. Como resultado, ele gera um relatório legível por humanos resumindo os resultados e o exibe no IC ou como um comentário para sua solicitação de tração.
Além de medir os tempos de renderização do componente, ele também pode medir a execução de funções regulares de JavaScript.
Para instalar tranquilizar, execute o seguinte comando em sua pasta de aplicativos:
Usando fios
yarn add --dev reassure
Usando NPM
npm install --save-dev reassure
Você também precisará de uma configuração de Jest Work, bem como uma das bibliotecas de testes nativos de reação ou biblioteca de testes de reação.
Consulte o Guia de Instalação.
Você pode verificar nossos projetos de exemplo:
A tranquilidade tentará detectar qual biblioteca de testes você instalou. Se a biblioteca de testes nativos reagir e a biblioteca de testes de reação estiver presente, ela o avisará sobre isso e dará precedência para reagir a biblioteca de testes nativos. Você pode especificar explicitamente a biblioteca de testes a ser usada usando a opção configure
:
configure ( { testingLibrary : 'react-native' } ) ;
// or
configure ( { testingLibrary : 'react' } ) ;
Você deve defini -lo no seu arquivo de configuração do JEST e substituí -lo em arquivos de teste específicos, se necessário.
Agora que a biblioteca está instalada, você pode escrever seu primeiro cenário de teste em um arquivo com .perf-test.js
/ .perf-test.tsx
Extension:
// ComponentUnderTest.perf-test.tsx
import { measureRenders } from 'reassure' ;
import { ComponentUnderTest } from './ComponentUnderTest' ;
test ( 'Simple test' , async ( ) => {
await measureRenders ( < ComponentUnderTest / >);
} ) ;
Este teste medirá os tempos de renderização do ComponentUnderTest
durante os efeitos de montagem e sincronização resultantes.
NOTA : A tranquilização corresponderá automaticamente aos nomes de arquivos de teste usando a opção
--testMatch
da JEST com valor"**/__perf__/**/*.[jt]s?(x)", "**/*.(perf|perf-test).[jt]s?(x)"
. No entanto, se você quiser passar por uma opção personalizada--testMatch
ou--testRegex
, poderá adicioná -la ao scriptreassure measure
para passar seu próprio glob. Mais sobre--testMatch
e--testRegex
em documentos de Jest
Se o seu componente contiver alguma lógica assíncrona ou você quiser testar alguma interação, você deve passar a opção scenario
:
import { measureRenders } from 'reassure' ;
import { screen , fireEvent } from '@testing-library/react-native' ;
import { ComponentUnderTest } from './ComponentUnderTest' ;
test ( 'Test with scenario' , async ( ) => {
const scenario = async ( ) => {
fireEvent . press ( screen . getByText ( 'Go' ) ) ;
await screen . findByText ( 'Done' ) ;
} ;
await measureRenders ( < ComponentUnderTest / >, { scenario });
} ) ;
O corpo da função de scenario
está usando métodos familiares de biblioteca de testes nativos do React.
No caso de usar uma versão da biblioteca de testes nativos do React inferior a V10.1.0, onde o auxiliar screen
não está disponível, a função scenario
fornece como seu primeiro argumento:
import { measureRenders } from 'reassure' ;
import { fireEvent } from '@testing-library/react-native' ;
test ( 'Test with scenario' , async ( ) => {
const scenario = async ( screen ) => {
fireEvent . press ( screen . getByText ( 'Go' ) ) ;
await screen . findByText ( 'Done' ) ;
} ;
await measureRenders ( < ComponentUnderTest / >, { scenario });
} ) ;
Se o seu teste contiver alguma alteração assíncrona, você precisará garantir que o cenário aguarde que essas alterações acordem, por exemplo, usando as consultas findBy
, waitFor
ou waitForElementToBeRemoved
Funções do RNTL.
Para medir o seu primeiro desempenho de teste, você precisa executar o seguinte comando no terminal:
yarn reassure
Este comando executará seus testes várias vezes usando o JEST, coletando estatísticas de desempenho e as gravará no arquivo .reassure/current.perf
. Para verificar sua configuração, verifique se o arquivo de saída existe após a execução do comando pela primeira vez.
NOTA: Você pode adicionar
.reassure/
PASTER ao seu arquivo.gitignore
para evitar cometer seus resultados acidentalmente.
A CLI tranquiliza automaticamente tentará detectar seu nome de ramificação do código -fonte e cometer hash quando estiver usando o Git. Você pode substituir essas opções, por exemplo, se estiver usando um sistema de controle de versão diferente:
yarn reassure --branch [branch name] --commit-hash [commit hash]
Para detectar alterações de desempenho, você deve medir o desempenho de duas versões do seu código atual (seu código modificado) e linha de base (seu ponto de referência, por exemplo, ramificação main
). Para medir o desempenho em duas ramificações, você deve alternar ramos no Git ou clonar duas cópias do seu repositório.
Queremos automatizar essa tarefa para executar no CI. Para fazer isso, você precisará criar um script de teste de desempenho. Você deve salvá-lo em seu repositório, por exemplo, como reassure-tests.sh
.
Uma versão simples desse script, usando uma abordagem de mudança de ramificação, é a seguinte:
#! /usr/bin/env bash
set -e
BASELINE_BRANCH= ${GITHUB_BASE_REF := " main " }
# Required for `git switch` on CI
git fetch origin
# Gather baseline perf measurements
git switch " $BASELINE_BRANCH "
yarn install
yarn reassure --baseline
# Gather current perf measurements & compare results
git switch --detach -
yarn install
yarn reassure
Para tornar a configuração da integração do IC e todos os pré -requisitos mais convenientes, preparamos um comando da CLI para gerar todos os modelos necessários para você começar.
Basta correr:
yarn reassure init
Isso gerará a seguinte estrutura de arquivo
├── <ROOT>
│ ├── reassure-tests.sh
│ ├── dangerfile.ts/js (or dangerfile.reassure.ts/js if dangerfile.ts/js already present)
│ └── .gitignore
reassure-tests.sh
)Script básico, permitindo que você tranquilize o IC. Mais sobre a importância e a estrutura deste arquivo na seção a seguir.
Se o seu projeto já contiver um dangerfile.ts/js
, a CLI não o substituirá de forma alguma. Em vez disso, ele gerará um arquivo dangerfile.reassure.ts/js
, permitindo comparar e atualizar o seu próprio conforme sua conveniência.
.gitignore
Se o arquivo .gitignore
estiver presente e não mencionarem a reassure
, o script anexará o .reassure/
diretório até o fim.
reassure-tests.sh
) Para detectar alterações de desempenho, você deve medir o desempenho de duas versões do seu código atual (seu código modificado) e linha de base (seu ponto de referência, por exemplo, ramificação main
). Para medir o desempenho em duas ramificações, você deve alternar ramos no Git ou clonar duas cópias do seu repositório.
Queremos automatizar essa tarefa para executar no CI. Para fazer isso, você precisará criar um script de teste de desempenho. Você deve salvá-lo em seu repositório, por exemplo, como reassure-tests.sh
.
Uma versão simples desse script, usando uma abordagem de mudança de ramificação, é a seguinte:
#! /usr/bin/env bash
set -e
BASELINE_BRANCH= ${GITHUB_BASE_REF := " main " }
# Required for `git switch` on CI
git fetch origin
# Gather baseline perf measurements
git switch " $BASELINE_BRANCH "
yarn install
yarn reassure --baseline
# Gather current perf measurements & compare results
git switch --detach -
yarn install
yarn reassure
Como uma etapa de configuração final, você deve configurar seu CI para executar o script de teste de desempenho e produzir o resultado. Para apresentar a saída no momento, integramos o Danger JS, que suporta todas as principais ferramentas de IC.
Você precisará de uma configuração JS de perigo em funcionamento.
Em seguida, adicione o plugin JS de perigo tranquilizada ao seu Dangerfile:
// /<project_root>/dangerfile.reassure.ts (generated by the init script)
import path from 'path' ;
import { dangerReassure } from 'reassure' ;
dangerReassure ( {
inputFilePath : path . join ( __dirname , '.reassure/output.md' ) ,
} ) ;
Se você ainda não possui um DangerFile ( dangerfile.js
ou dangerfile.ts
), você pode usar o gerado pelo script reassure init
sem fazer alterações adicionais.
Ele também está em nosso exemplo de arquivo de arquivo.
Por fim, execute o script de teste de desempenho e o perigo em sua configuração de CI:
- name : Run performance testing script
run : ./reassure-tests.sh
- name : Run Danger.js
run : yarn danger ci
env :
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
Você também pode verificar nosso exemplo de fluxo de trabalho do GitHub.
O exemplo acima é baseado em ações do GitHub, mas deve ser semelhante a outros arquivos de configuração de CI e deve servir apenas como referência nesses casos.
Nota : Seu teste de desempenho será executado muito mais do que os testes regulares de integração. É porque executamos cada cenário de teste várias vezes (por padrão, 10) e repetimos isso para duas ramificações do seu código. Portanto, cada teste será executado 20 vezes por padrão. A menos que você aumente esse número ainda mais.
Medimos os tempos de renderização do componente com precisão de microssegundos durante as medições de desempenho usando React.Profiler
. Isso significa que o mesmo código será executado mais rápido ou mais lento, dependendo da máquina. Por esse motivo, as medições de linha de base e corrente precisam ser executadas na mesma máquina. De maneira ideal, eles devem ser executados um após o outro.
Além disso, seu agente de CI precisa ter um desempenho estável para obter resultados significativos. Não importa se o seu agente é rápido ou lento, desde que seja consistente em seu desempenho. É por isso que o agente não deve ser usado durante os testes de desempenho para qualquer outro trabalho que possa impactar os tempos de renderização de medição.
Para ajudá-lo a avaliar a estabilidade da sua máquina, você pode usar o comando reassure check-stability
. Ele executa as medições de desempenho duas vezes para o código atual; portanto, as medidas de linha de base e atuais se referem ao mesmo código. Nesse caso, as alterações esperadas são 0% (sem alteração). O grau de alterações aleatórias de desempenho refletirá a estabilidade da sua máquina. Este comando pode ser executado tanto nas máquinas CI quanto em locais.
Normalmente, as alterações aleatórias devem estar abaixo de 5%. Os resultados de 10% e mais são considerados muito altos, o que significa que você deve trabalhar para ajustar a estabilidade da sua máquina.
NOTA : Como um truque de último recurso, você pode aumentar a opção
run
do valor padrão de 10 a 20, 50 ou até 100 para todos ou alguns de seus testes, com base na suposição de que mais testes de teste serão divulgados. Isso, no entanto, fará com que seus testes funcionem ainda mais.
Você pode se referir ao nosso exemplo de fluxo de trabalho do GitHub.
Olhando para o exemplo, você pode notar que os cenários de teste podem ser atribuídos a determinadas categorias:
measureRenders
Wrapper personalizado para a função RNTL render
responsável por renderizar a tela passada dentro de um componente React.Profiler
, medindo seu desempenho e escrevendo resultados no arquivo de saída. Você pode usar o objeto options
opcionais que permite personalizar aspectos do teste
async function measureRenders (
ui : React . ReactElement ,
options ?: MeasureRendersOptions ,
) : Promise < MeasureResults > {
MeasureRendersOptions
interface MeasureRendersOptions {
runs ?: number ;
warmupRuns ?: number ;
wrapper ?: React . ComponentType < { children : ReactElement } > ;
scenario ?: ( view ?: RenderResult ) => Promise < any > ;
writeFile ?: boolean ;
}
runs
: número de corridas por série para o teste específicowarmupRuns
: Número de execuções de aquecimento adicionais que serão feitas e descartadas antes das execuções reais (padrão 1).wrapper
: React Component, como um Provider
, com o qual a ui
será embrulhada. Nota: a duração da renderização do wrapper
é excluída dos resultados; Somente o componente embrulhado é medido.scenario
: uma função assíncrona personalizada, que define a interação do usuário na interface do usuário, utilizando funções RNTL ou RTLwriteFile
: (padrão true
) deve gravar saída no arquivo. measureFunction
Permite envolver qualquer função síncrona, meça seus tempos de execução e escreva resultados no arquivo de saída. Você pode usar options
opcionais para personalizar aspectos do teste. Nota: a contagem de execução sempre será uma.
async function measureFunction (
fn : ( ) => void ,
options ?: MeasureFunctionOptions
) : Promise < MeasureResults > {
MeasureFunctionOptions
Tipo interface MeasureFunctionOptions {
runs ?: number ;
warmupRuns ?: number ;
}
runs
: número de corridas por série para o teste específicowarmupRuns
: Número de execuções de aquecimento adicionais que serão feitas e descartadas antes das execuções reais. A configuração padrão que será usada pelo script de medição. Esse objeto de configuração pode ser substituído pelo uso da função configure
.
type Config = {
runs ?: number ;
warmupRuns ?: number ;
outputFile ?: string ;
verbose ?: boolean ;
testingLibrary ?:
| 'react-native'
| 'react'
| { render : ( component : React . ReactElement < any > ) => any ; cleanup : ( ) => any } ;
} ;
const defaultConfig : Config = {
runs : 10 ,
warmupRuns : 1 ,
outputFile : '.reassure/current.perf' ,
verbose : false ,
testingLibrary : undefined , // Will try auto-detect first RNTL, then RTL
} ;
runs
: o número de execuções repetidas em uma série por teste (permite maior precisão agregando mais dados). Deve ser tratado com cuidado.
warmupRuns
: o número de execuções de aquecimento adicionais que serão feitas e descartadas antes das execuções reais. outputFile
: O nome do arquivo Os registros serão salvos para verbose
: Torne a garantia do registro 'react-native'
, por exemplo 'react'
para fins de depuração testingLibrary
: onde procurar funções de render
e cleanup
, valores suportados Funções de render
e cleanup
configure
função function configure ( customConfig : Partial < Config > ) : void ;
A função configure
pode substituir os parâmetros de configuração padrão.
resetToDefaults
função resetToDefaults ( ) : void
Redefina a configuração atual para o objeto defaultConfig
original
Você pode usar variáveis ambientais disponíveis para alterar as configurações do corredor de teste.
TEST_RUNNER_PATH
: um caminho alternativo para o seu corredor de teste. Padrão para 'node_modules/.bin/jest'
ou no Windows 'node_modules/jest/bin/jest'
TEST_RUNNER_ARGS
: um conjunto de argumentos alimentados ao corredor. Padrão para '--runInBand --testMatch "**/__perf__/**/*.[jt]s?(x)", "**/*.(perf|perf-test).[jt]s?(x)"'
Exemplo:
TEST_RUNNER_PATH=myOwnPath/jest/bin yarn reassure
Consulte o guia contribuinte para aprender a contribuir para o repositório e o fluxo de trabalho de desenvolvimento.
Mit
A garantia é um projeto de código aberto e sempre permanecerá livre para usar. O projeto foi desenvolvido em estreita parceria com a Entein e foi originalmente seu projeto interno. Graças à vontade deles de desenvolver o ecossistema nativo React & React, decidimos torná -lo de código aberto. Se você acha legal, por favor, estrela?
O CallStack é um grupo de especialistas nativos de reação e reagem. Se você precisar de ajuda com isso ou quiser dizer oi, entre em contato conosco em [email protected]!
Gosta do projeto? ⚛️ Junte -se à equipe de callStack que faz coisas incríveis para clientes e dirige, reaja de código aberto nativo!