Un novato junto a "React Testing" segunda parte...

Fri Jan 15 2021 07:49:00 GMT+0000

Este segundo post, es la continuación de un total de tres sobre mis experiencia durante el estudio de la libreía React Testing. En la primera parte empecé con una pequeña descripción y sus ventajas, en esta segunda parte vamos a ver un poco más sobre ella ya que nos centraremos en las queries o consultas, las cuales nos van ayudar para la realización de los test.

Queries o Consultas

Los argumentos de una consulta pueden ser string, expresion regular o funciones, además podemos encontrar opciones para ajustar como el nodo es analizado, la cuales son :


ByLabelText

Nos buscará la etiqueta que coincida con el TextMatch que le pasemos y luego nos encontrará el elemento asociado con dicha etiqueta.

1
2
3
4
5
6
7
8
getByLabelText(
container: HTMLElement, //if you're using `screen`, then skip this argument
text: TextMatch,
options?: {
selector?: string = '*',
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import * as React from "react";
import "./Label.scss";
const Label = () => {
return (
<>
<div className={"classLabel"}>
<label htmlFor="username-input">
Testing getByLabelText and getByText
</label>
<input id="username-input" />
</div>
</>
);
};

export default Label;

Test

1
2
3
4
5
6
7
8
import * as React from "react";
import * as Testing from "@testing-library/react";
import Label from "./Label";

test("for label queries", () => {
Testing.render(<Label/>);
Testing.screen.getByLabelText("Testing getByLabelText and getByText");
});

ByPlaceholderText

Nos buscará en todos los elementos que contentagan placeholder hasta econtrar uno que coincida con el TextMatch que le pasemos.

1
2
3
4
5
6
7
getByPlaceholderText(
container: HTMLElement, //if you're using `screen`, then skip this argument
text: TextMatch,
options?: {
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
import * as React from "react";
import "./InputWithPlaceHolder.scss";

const InputWithPlaceHolder = () => {
return (
<div className={"input-place-holder"}>
<h3>Testing getByPlaceholderText</h3>
<input type="text" placeholder={"I am a placeholder"} />
</div>
);
};

export default InputWithPlaceHolder;

Test

1
2
3
4
5
6
7
8
import * as React from "react";
import * as Testing from "@testing-library/react";
import InputWithPlaceHolder from "./InputWithPlaceHolder";

test("testing getBy Placeholder", () => {
Testing.render(<InputWithPlaceHolder />);
Testing.screen.getByPlaceholderText("I am a placeholder");
});

~ Buscar por placeholder no es la mejor opción, por lo general se usa getByLabelText ~


ByText

Nos buscará en todos lo elementos que contengan texto en el nodo con textContent que coincida con el TextMatch que le pasemos. Además funciona con inputs cuyo atributos sean del tipo submit o button.

Podemos pasarle como opción ignore en estado false si queremos evitar que nos devuelva como true una etiqueta script.

1
2
3
4
5
6
7
8
9
getByText(
container: HTMLElement, //if you're using `screen`, then skip this argument
text: TextMatch,
options?: {
selector?: string = '*',
exact?: boolean = true,
ignore?: string|boolean = 'script, style',
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
import * as React from 'react';

const Label = () => {

return (<><label htmlFor="username-input">Label</label>
<input id="username-input"/>
</>);
};

export default Label;

Test

1
2
3
4
5
6
7
8
9
10
11
import * as React from 'react';
import * as Testing from '@testing-library/react';
import Label from "./Label";


test('queries getByText', () => {

Testing.render(<Label/>);
Testing.screen.getByText(/Label/i);

});

ByAltText

Esta búsqueda es solamente soportada por elementos que contengan el atributo alt,como por ejemplo<img>, <input> y <area> ya que nos devolvería dichos elementos si su atributo alt coincide con el TextMatch indicado.

1
2
3
4
5
6
7
getByAltText(
container: HTMLElement, //if you're using `screen`, then skip this argument
text: TextMatch,
options?: {
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import * as React from "react";
import IconReactTesting from "../../img/octopus-128x128.png";
import "./Img.scss";

const Img = () => {
return (
<div className={"img-class"}>
<h3>Testing ByAltText</h3>
<img src={IconReactTesting} alt={"This is a img"} />
</div>
);
};

export default Img;

Test

1
2
3
4
5
6
7
8
9
import * as React from 'react';
import * as Testing from '@testing-library/react';
import Img from '../Img/Img';

test('queries getByAltText', () => {

Testing.render(<Img/>);
Testing.screen.getByAltText('This is a img');
})

ByTitle

Esta búsqueda nos devolvería el elemento que contenga en su atributo title el TextMatch que le pasemos, funcionaría con elementos svg ya que contengan dentro la etiqueta title.

1
2
3
4
5
6
7
getByTitle(
container: HTMLElement, //if you're using `screen`, then skip this argument
title: TextMatch,
options?: {
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
import * as React from "react";
import "./InputWithTitle.scss";

const InputWithTitle = () => {
return (
<div className={"input-with-title"}>
<h3>Testing ByTitle</h3>
<input type={"text"} title={"This a input with title"} />
</div>
);
};

export default InputWithTitle;

Test

1
2
3
4
5
6
7
8
import * as React from 'react';
import * as Testing from '@testing-library/react';
import InputWithTitle from "./InputWithTitle";

test('queries getByTitle', () => {
Testing.render(<InputWithTitle/>);
Testing.screen.getByTitle('This a input with title');
})

ByDisplayValue

Esta búsqueda nos devolvería el input, textarea o select que contengan el valor indicado en el TextMatch.

1
2
3
4
5
6
7
getByDisplayValue(
container: HTMLElement, //if you're using `screen`, then skip this argument
value: TextMatch,
options?: {
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import * as React from "react";
import "./InputWithDisplayValue.scss";

const InputWithDisplayValue = () => {
return (
<div className={"display-value"}>
<h3>Testing ByDisplayValue</h3>
<input
type={"text"}
title={"This a input with title"}
value={"This a input with display value"}
readOnly={true}
/>
</div>
);
};

export default InputWithDisplayValue;

Test

1
2
3
4
5
6
7
8
import * as React from 'react';
import * as Testing from '@testing-library/react';
import InputWithDisplayValue from "./InputWithDisplayValue";

test('queries getByTitle', () => {
Testing.render(<InputWithDisplayValue/>);
Testing.screen.getByDisplayValue('This a input with display value');
});

ByRole

Búsqueda por el atributo role incluyendo también en los elementos que ya tienen dicha etiqueta implícita (tabla de elementos HTML con roles predeterminados), hay que tener en cuenta que introducir un atributo role en un elemento que ya lo tiene por defecto, nos puede causar problemas, ya que podríamos introducir un role que no le corresponde.

Si tenemos varios elementos con el mismo role podríamos buscarlo por su nombre accesible nombre accesible, dicha busqueda no sustituye a ByAlt o ByTitle.

Tenemos varias opciones que podemos configurar para la búsqueda, como hidden, selected, checked, pressed, queryFallbacks y levels (podrás ver algo más sobre la configuración en la parte ByRole que encuentras en la documentación).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
getByRole(
container: HTMLElement, //if you're using `screen`, then skip this argument
role: TextMatch,
options?: {
exact?: boolean = true,
hidden?: boolean = false,
name?: TextMatch,
normalizer?: NormalizerFn,
selected?: boolean,
checked?: boolean,
pressed?: boolean,
queryFallbacks?: boolean,
level?: number,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import * as React from "react";
import "./ByRole.scss";

const ByRole = () => {
return (
<>
<div className={"byRole"}>
<header>
<h3>This is to prove the queries ByRole</h3>
</header>

<button type="submit">This is a submit button</button>

<button type="reset">This is a reset button</button>

<button type="button">This is a button</button>
</div>
</>
);
};

export default ByRole;

Test

1
2
3
4
5
6
7
8
import * as React from "react";
import * as Testing from "@testing-library/react";
import ByRole from "./ByRole";

test("to testing byRole", () => {
Testing.render(<ByRole />);
Testing.screen.getByRole("button", { name: "This is a reset button" });
});

ByTestId

Solamente es recomendable cuando ninguna de las queries anteriores nos permite hacer la búsqueda.

1
2
3
4
5
6
7
getByTestId(
container: HTMLElement, // if you're using `screen`, then skip this argument
text: TextMatch,
options?: {
exact?: boolean = true,
normalizer?: NormalizerFn,
}): HTMLElement

Componente

1
2
3
4
5
6
7
8
9
10
11
import * as React from "react";
import "./ExampleByTestId.scss";
const ExampleByTestId = () => {
return (
<div className={"byTestId"} data-testid={"custom-element"}>
<p>Testing ByTestId</p>
</div>
);
};

export default ExampleByTestId;

Test

1
2
3
4
5
6
7
8
9
import * as React from 'react';
import * as Testing from '@testing-library/react';
import ExampleByTestId from "./ExampleByTestId";


test('testing getByTestId',()=>{
Testing.render(<ExampleByTestId/>);
Testing.screen.getByTestId('custom-element');
});

En este post he querido ver las queries que nos brinda esta librería, para terminar mi aprendizaje de React Testing veremos en el siguiente los Firing Events y algunos de los métodos que hereda de DOM Testing Library .

Nos vemos en el próximo post,……

Top