Compañero de prueba de rendimiento para React y React Native.
Leer los documentos
reassure-tests.sh
).gitignore
reassure-tests.sh
)measureRenders
MeasureRendersOptions
measureFunction
MeasureFunctionOptions
configure
la funciónresetToDefaults
Desea que su aplicación React Native funcione bien y rápido en todo momento. Como parte de este objetivo, perfecciona la aplicación, observa patrones de renderizado, aplica la memorización en los lugares correctos, etc. Pero todo es manual y es demasiado fácil introducir intencionalmente regresiones de rendimiento que solo serían atrapadas durante el control de calidad o peor, por sus usuarios, por sus usuarios. .
Preguntar le permite automatizar las pruebas de regresión de rendimiento de la aplicación React Native en CI o una máquina local. De la misma manera, escribe su integración y pruebas unitarias que verifican automáticamente que su aplicación todavía funciona correctamente , puede escribir pruebas de rendimiento que verifiquen que su aplicación todavía funcione perfectamente .
Puede pensarlo como una biblioteca de pruebas de rendimiento React. De hecho, InsoSure está diseñado para reutilizar la mayor parte de las pruebas de la biblioteca de pruebas nativas React y la configuración posible.
Asegure los trabajos midiendo las características de renderizado - duración y recuento - del escenario de prueba que proporciona y comparó eso con la versión estable. Repita el escenario varias veces para reducir el impacto de las variaciones aleatorias en los tiempos de renderizado causados por el entorno de tiempo de ejecución. Luego, aplica un análisis estadístico para determinar si los cambios en el código son estadísticamente significativos. Como resultado, genera un informe legible por humanos que resume los resultados y lo muestra en el CI o como un comentario a su solicitud de extracción.
Además de medir los tiempos de renderizado de componentes, también puede medir la ejecución de funciones regulares de JavaScript.
Para instalar tranquilidad, ejecute el siguiente comando en la carpeta de su aplicación:
Usando hilo
yarn add --dev reassure
Usando NPM
npm install --save-dev reassure
También necesitará una configuración de Jest Working, así como una de la biblioteca de pruebas nativas de React o la biblioteca de pruebas React.
Consulte la guía de instalación.
Puede consultar nuestros proyectos de ejemplo:
La tranquilidad intentará detectar qué biblioteca de prueba ha instalado. Si tanto React Native Testing Library como React Testing Library están presentes, le advertirá sobre eso y dará precedencia para reaccionar la biblioteca de pruebas nativas. Puede especificar explícitamente la biblioteca de pruebas que se utilizará utilizando la opción configure
:
configure ( { testingLibrary : 'react-native' } ) ;
// or
configure ( { testingLibrary : 'react' } ) ;
Debe configurarlo en su archivo de configuración de Jest, y puede anularlo en archivos de prueba particular si es necesario.
Ahora que la biblioteca está instalada, puede escribir su primer escenario de prueba en un archivo con .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 / >);
} ) ;
Esta prueba medirá los tiempos de renderizado de ComponentUnderTest
durante el montaje y los efectos de sincronización resultantes.
Nota : La tranquilidad coincidirá automáticamente con los nombres de archivo de la prueba utilizando la opción
--testMatch
con valor"**/__perf__/**/*.[jt]s?(x)", "**/*.(perf|perf-test).[jt]s?(x)"
. Sin embargo, si desea pasar una opción personalizada--testMatch
o--testRegex
, puede agregarlo al scriptreassure measure
para pasar su propio globo. Más sobre--testMatch
y--testRegex
in brom
Si su componente contiene alguna lógica de Async o si desea probar alguna interacción, debe aprobar la opción 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 });
} ) ;
El cuerpo de la función scenario
está utilizando métodos familiares de la biblioteca de pruebas nativas React.
En caso de usar una versión de la biblioteca de pruebas nativas de React inferior a V10.1.0, donde la pantalla screen
no está disponible, la función scenario
lo proporciona como su primer 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 });
} ) ;
Si su prueba contiene algún cambio de asíncrono, deberá asegurarse de que el escenario espere a que estos cambios se resuelvan, por ejemplo, utilizando las consultas findBy
, waitFor
o waitForElementToBeRemoved
Funciones de RNTL.
Para medir su primer rendimiento de prueba, debe ejecutar el siguiente comando en el terminal:
yarn reassure
Este comando ejecutará sus pruebas varias veces usando Jest, recopilando estadísticas de rendimiento y las escribirá en el archivo .reassure/current.perf
. Para verificar su configuración, verifique si el archivo de salida existe después de ejecutar el comando por primera vez.
Nota: Puede agregar
.reassure/
carpeta a su archivo.gitignore
para evitar cometer accidentalmente sus resultados.
Asegurar que CLI intentará detectar automáticamente su nombre de rama del código fuente y confirmar el hash cuando esté utilizando GIT. Puede anular estas opciones, por ejemplo, si está utilizando un sistema de control de versiones diferente:
yarn reassure --branch [branch name] --commit-hash [commit hash]
Para detectar los cambios de rendimiento, debe medir el rendimiento de dos versiones de su código de código (su código modificado) y línea de base (su punto de referencia, por ejemplo, la rama main
). Para medir el rendimiento en dos ramas, debe cambiar las ramas en GIT o clonar dos copias de su repositorio.
Queremos automatizar esta tarea para ejecutarse en el CI. Para hacer eso, necesitará crear un script de prueba de rendimiento. Debe guardarlo en su repositorio, por ejemplo, como reassure-tests.sh
.
Una versión simple de dicho script, que usa un enfoque de cambio de rama, es la siguiente:
#! /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 que la configuración de la integración del CI y todos los requisitos previos sean más convenientes, hemos preparado un comando CLI para generar todas las plantillas necesarias para que comience.
Simplemente ejecute:
yarn reassure init
Esto generará la siguiente estructura de archivo
├── <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 que le permite ejecutar tranquilidad en CI. Más sobre la importancia y la estructura de este archivo en la siguiente sección.
Si su proyecto ya contiene un dangerfile.ts/js
, la CLI no lo anulará de ninguna manera. En su lugar, generará un archivo dangerfile.reassure.ts/js
, lo que le permite comparar y actualizar el suyo a su conveniencia.
.gitignore
Si el archivo .gitignore
está presente y no aparecen menciones de reassure
, el script agregará el directorio .reassure/
al final.
reassure-tests.sh
) Para detectar los cambios de rendimiento, debe medir el rendimiento de dos versiones de su código de código (su código modificado) y línea de base (su punto de referencia, por ejemplo, la rama main
). Para medir el rendimiento en dos ramas, debe cambiar las ramas en GIT o clonar dos copias de su repositorio.
Queremos automatizar esta tarea para ejecutarse en el CI. Para hacer eso, necesitará crear un script de prueba de rendimiento. Debe guardarlo en su repositorio, por ejemplo, como reassure-tests.sh
.
Una versión simple de dicho script, que usa un enfoque de cambio de rama, es la siguiente:
#! /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 un paso de configuración final, debe configurar su CI para ejecutar el script de prueba de rendimiento y generar el resultado. Para presentar la producción en este momento, nos integramos con Danger JS, que admite todas las principales herramientas de CI.
Necesitará una configuración JS de peligro de funcionamiento.
Luego agregue el complemento JS de Peligro de tranquilidad a su 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' ) ,
} ) ;
Si no tiene un DangerFile ( dangerfile.js
o dangerfile.ts
) todavía, puede usar el generado por el script reassure init
sin hacer cambios adicionales.
También está en nuestro archivo de ejemplo DangerFile.
Finalmente, ejecute el script y el peligro de pruebas de rendimiento en su configuración CI:
- name : Run performance testing script
run : ./reassure-tests.sh
- name : Run Danger.js
run : yarn danger ci
env :
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
También puede verificar nuestro ejemplo de flujo de trabajo GitHub.
El ejemplo anterior se basa en acciones de GitHub, pero debe ser similar a otros archivos de configuración de CI y solo debe servir como referencia en tales casos.
Nota : Su prueba de rendimiento se ejecutará mucho más tiempo que las pruebas de integración regulares. Es porque ejecutamos cada escenario de prueba varias veces (por defecto, 10) y lo repitemos para dos ramas de su código. Por lo tanto, cada prueba se ejecutará 20 veces por defecto. Eso es a menos que aumente ese número aún más.
Medimos los tiempos de renderizado del componente React con precisión de microsegundos durante las mediciones de rendimiento utilizando React.Profiler
. Esto significa que el mismo código se ejecutará más rápido o más lento, dependiendo de la máquina. Por esta razón, las mediciones de base y corriente deben ejecutarse en la misma máquina. Óptimamente, deben ejecutarse uno tras otro.
Además, su agente de CI necesita tener un rendimiento estable para lograr resultados significativos. No importa si su agente es rápido o lento siempre que sea consistente en su rendimiento. Es por eso que el agente no debe usarse durante las pruebas de rendimiento para cualquier otro trabajo que pueda afectar los tiempos de renderización de medición.
Para ayudarlo a evaluar la estabilidad de su máquina, puede usar el comando reassure check-stability
. Ejecuta mediciones de rendimiento dos veces para el código actual, por lo que las mediciones de línea de base y actuales se refieren al mismo código. En tal caso, los cambios esperados son 0% (sin cambios). El grado de cambios de rendimiento aleatorio reflejará la estabilidad de su máquina. Este comando se puede ejecutar tanto en CI como en máquinas locales.
Normalmente, los cambios aleatorios deben estar por debajo del 5%. Los resultados del 10% y más se consideran demasiado altos, lo que significa que debe trabajar en ajustar la estabilidad de su máquina.
Nota : Como truco del último recurso, puede aumentar la opción
run
del valor predeterminado de 10 a 20, 50 o incluso 100 para todas o algunas de sus pruebas, en función de la suposición de que más ejecuciones de pruebas finitarán fluctuaciones de medición. Sin embargo, eso hará que sus pruebas funcionen aún más.
Puede consultar nuestro ejemplo de flujo de trabajo GitHub.
Mirando el ejemplo, puede notar que los escenarios de prueba se pueden asignar a ciertas categorías:
measureRenders
Envoltura personalizada para la función render
RNTL responsable de representar la pantalla pasada dentro de un componente React.Profiler
. Puede usar el objeto options
opcionales que permite personalizar aspectos de las pruebas
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 ejecuciones por serie para la prueba particularwarmupRuns
: número de ejecuciones de calentamiento adicionales que se realizarán y se descartarán antes de las ejecuciones reales (predeterminada 1).wrapper
: React Component, como un Provider
, con el que la ui
estará envuelta. NOTA: La duración de renderizado del wrapper
en sí se excluye de los resultados; Solo se mide el componente envuelto.scenario
: una función Async personalizada, que define la interacción del usuario dentro de la interfaz de usuario utilizando funciones RNTL o RTLwriteFile
: (predeterminado true
) debe escribir la salida en el archivo. measureFunction
Le permite envolver cualquier función sincrónica, medir sus tiempos de ejecución y escribir resultados en el archivo de salida. Puede usar options
opcionales para personalizar aspectos de las pruebas. Nota: El recuento de ejecución siempre será uno.
async function measureFunction (
fn : ( ) => void ,
options ?: MeasureFunctionOptions
) : Promise < MeasureResults > {
MeasureFunctionOptions
interface MeasureFunctionOptions {
runs ?: number ;
warmupRuns ?: number ;
}
runs
: número de ejecuciones por serie para la prueba particularwarmupRuns
: número de ejecuciones de calentamiento adicionales que se realizarán y se descartarán antes de las ejecuciones reales. La configuración predeterminada que será utilizada por el script de medición. Este objeto de configuración se puede anular con el uso de la función 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
: el número de ejecuciones repetidas en una serie por prueba (permite una mayor precisión al agregar más datos). Debe manejarse con cuidado.
warmupRuns
: el número de ejecuciones de calentamiento adicionales que se realizarán y se descartarán antes de las ejecuciones reales. outputFile
: el nombre del archivo Los registros se guardarán en verbose
: Haga que el registro de tranquilidad sea más, por ejemplo, para fines de depuración testingLibrary
: dónde buscar funciones render
y cleanup
, valores compatibles 'react-native'
, 'react'
o objeto que proporciona personalizado Funciones render
y cleanup
configure
la función function configure ( customConfig : Partial < Config > ) : void ;
La función configure
puede anular los parámetros de configuración predeterminados.
resetToDefaults
resetToDefaults ( ) : void
Restablezca la configuración actual al objeto original defaultConfig
Puede usar variables ambientales disponibles para alterar la configuración de su corredor de prueba.
TEST_RUNNER_PATH
: una ruta alternativa para su corredor de prueba. El valor predeterminado es 'node_modules/.bin/jest'
o en windows 'node_modules/jest/bin/jest'
TEST_RUNNER_ARGS
: un conjunto de argumentos alimentados al corredor. El valor predeterminado es '--runInBand --testMatch "**/__perf__/**/*.[jt]s?(x)", "**/*.(perf|perf-test).[jt]s?(x)"'
Ejemplo:
TEST_RUNNER_PATH=myOwnPath/jest/bin yarn reassure
Consulte la guía contribuyente para aprender a contribuir al repositorio y al flujo de trabajo de desarrollo.
MIT
Preguntar es un proyecto de código abierto y siempre seguirá siendo libre de usar. El proyecto se ha desarrollado en estrecha asociación con Intain y originalmente fue su proyecto interno. Gracias a su disposición a desarrollar el ecosistema nativo React & React, decidimos hacerlo de código abierto. Si crees que es genial, por favor, estre a la estrella.
CallStack es un grupo de expertos nativos React y React. Si necesita ayuda con estos o desea saludar, contáctenos a [email protected].
Como el proyecto? ⚛️ ¡Únete al equipo de callstack que hace cosas increíbles para los clientes y los impulsa React Open Source!