├── .gitignore ├── README.md ├── package.json ├── public └── index.html ├── src ├── App.css ├── App.js ├── App.test.js ├── ilustracao.svg ├── index.css ├── index.js └── setupTests.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Primeiro tutorial do canal quero ser dev 2 | 3 | ## Para quem é esse tutorial? 4 | 5 | ✅ Pra quem já estudou html, css e javascript 6 | 7 | ✅ Pra quem está estudando react 8 | 9 | ✅ Pra quem deseja iniciar nos testes em aplicações react 10 | 11 | ## O projeto 12 | 13 | Link da aplicação em produção: testing-react-quero-ser-dev.netlify.app 14 | 15 | Neste projeto estamos estudando como dar os passos iniciais com react-testing-library. 16 | 17 | Esta aplicação simples feita com create react-app deverá ter o comportamento abaixo: 18 | 19 | ![image](https://media.giphy.com/media/KMyt74nbfFpnTEIgLU/giphy.gif) 20 | 21 | O mais legal é que vamos fazer com testes garantindo os cenários abaixo: 22 | 23 | ✅ Quando a tela carrega, o componente renderiza corretamente com todos os elementos? 24 | 25 | ✅ A imagem está acessível com o texto alternativo? 26 | 27 | ✅ O input funciona capturando o valor digitado? 28 | 29 | ✅ Após a usuária digitar o nome, o texto renderiza corretamente na tela? 30 | 31 | ## Conteúdo 32 | 33 | Vamos aprender a testar em react? Na prática a gente vai imitar comportamento humano interagindo com a aplicação só que de forma automatizada. 34 | 35 | Sim, você vai poder dizer que começou a estudar testes unitários e automatizados com React Testing Library, que segundo a documentação é uma família completa de pacotes para criar testes utilizando boas práticas centradas no comportamento da pessoa usuária. 36 | 37 | Vamos lá! 38 | 39 | ### Estrutura básica do teste 40 | 41 | > Bloco de teste 42 | 43 | - Renderizar o componente que queremos testar 44 | - Encontrar os elementos que queremos interagir 45 | - Interagir com esses elementos 46 | - Afirmar o resultado esperado 47 | 48 | > describe, it e expect 49 | 50 | - describe serve para criarmos um conjunto de testes 51 | - it ou test serve para criar um caso de teste 52 | - expect serve para descrever o que esperamos com resultado ideal para aquele teste 53 | 54 | > screen, render, fireEvent, queryBy.../findBy..., toBeInTheDocument/toHaveTextContent 55 | 56 | - screen é o que nos permite visualizar a tela e a partir daí encontrar os nós do DOM 57 | - render é o metodo que renderiza nosso componente no ambiente de testes 58 | - fireEvent simula alguns eventos e interações da pessoa usuária 59 | - queryBy.../findBy... são as queries, alguns dos muitos metódos que nos ajuda a encontrar, buscar, trazer um ou mais elementos da tela 60 | - toBeInTheDocument/toHaveTextContent são os matchers, alguns dos muitos metodos que nos ajudam a comparar o resultado esperado com o resultado recebido. Eles nos ajudam também com o log de mensagens de erro. 61 | 62 | ### Tecnologias 63 | 64 | | Ferramenta | Descrição | 65 | | ----------------------- | ------------------------------------------------------- | 66 | | `ReactJS` | Biblioteca de javascript | 67 | | `React-Testing-library` | Bibliotecas para criação de testes em javascript | 68 | | `yarn` | Gerenciador de pacotes | 69 | | `Netlify` | Servidor para deploy automático da aplicação via github | 70 | 71 | ### Arquitetura 72 | 73 | #### 📂public 74 | 75 | > Está o index.html nosso arquivo que recebe a div root manipulada pela virtualDOM 76 | 77 | #### 📂src 78 | 79 | > Estão os arquivos de imagem, css, testes e componentes 80 | 81 | #### 📂node_modules 82 | 83 | > Ficam salvos somente em nosso computador todos os pacotes e dependências para nosso projeto react funcionar 84 | 85 | ``` 86 | 📁 Testing 87 | | 88 | | - 📁 src 89 | | |- 📄 App.js 90 | | |- 📄 index.js 91 | | |- 📄 App.test.js 92 | | |- 📄 ilustracao.svg 93 | | |- 📄 App.css 94 | | |- 📄 index.css 95 | | |- 📄 setupTests.js 96 | | 97 | | - 📁 public 98 | | |- 📄 index.html 99 | | 100 | |- 📄 README.md 101 | |- 📄 .gitignore 102 | |- 📄 package.json 103 | |- 📄 yarn.lock 104 | 105 | ``` 106 | 107 | ### Como rodar o projeto localmente 108 | 109 | Siga os passos e inclua as informações abaixo: 110 | 111 | | Passo | Comando/informação | 112 | | --------------------------- | ------------------ | 113 | | Faça o fork | `botão de forkar` | 114 | | Faça o clone | `git clone` | 115 | | Instale as dependências | `yarn` | 116 | | Rode os testes | `yarn test` | 117 | | Rode o projeto no localhost | `yarn start` | 118 | 119 | ### 😎 Próximos passos para estudar 120 | 121 | - TDD (Programação orientada a testes) 122 | - Documentação do React Testing Library 123 | - Testar projetos que envolvam consumo de API 124 | - Melhores práticas e pensamento crítico para criação de testes 125 | 126 | --- 127 | 128 | _Foi incrível compartilhar essa jornada com você! Qualquer dúvida ou sugestão, chama no contatinho!_ 129 | 130 | ### Saudações, Simara! 131 | 132 | Gif Yeah 133 | 134 | Professora na {reprograma}, desenvolvedora na ThoughtWorks e criadora do Canal e Podcast Quero Ser Dev. 135 | 136 | Vamos nos conectar! 137 | 138 | - [instagram](https://www.instagram.com/simara_conceicao) 139 | - [linkedin](https://www.linkedin.com/in/simaraconceicao/) 140 | - [github](https://github.com/simaraconceicao) 141 | - [spotify](https://open.spotify.com/show/59vCz4TY6tPHXW26qJknh3) 142 | - [quero ser dev](https://queroserdev.com) 143 | 144 |
145 | Feito com 💜 por Simara Conceição 146 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testing", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^12.0.0", 8 | "@testing-library/user-event": "^13.2.1", 9 | "react": "^17.0.2", 10 | "react-dom": "^17.0.2", 11 | "react-scripts": "5.0.0", 12 | "web-vitals": "^2.1.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "browserslist": { 21 | "production": [ 22 | ">0.2%", 23 | "not dead", 24 | "not op_mini all" 25 | ], 26 | "development": [ 27 | "last 1 chrome version", 28 | "last 1 firefox version", 29 | "last 1 safari version" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | gap: 16rem; 6 | margin-top: 10rem; 7 | } 8 | 9 | img { 10 | height: 400px; 11 | width: 400px; 12 | } 13 | 14 | .input-container { 15 | display: flex; 16 | gap: 0.25rem; 17 | align-items: center; 18 | background: #fff; 19 | font-size: 16px; 20 | } 21 | 22 | .input-name { 23 | background: #fff; 24 | border: 0.5 solid rgb(160, 0, 184); 25 | padding: 12px 24px; 26 | border-radius: 8px; 27 | } 28 | 29 | h1 { 30 | color: #fff; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import './App.css' 3 | import ilustraImg from './ilustracao.svg' 4 | 5 | export default function App() { 6 | const [name, setName] = useState() 7 | 8 | return ( 9 |
10 | ilustração de uma mulher negra usando o computador e segurando uma xícara 14 |
15 | setName(e.target.value)} 20 | /> 21 |

Hello, {name}

22 |
23 |
24 | ) 25 | } -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen, fireEvent } from '@testing-library/react' 2 | import App from './App.js' 3 | 4 | describe('App', () => { 5 | it('should be able to render the component correctly', () => { 6 | render() 7 | 8 | expect(screen.queryByText('Hello,')).toBeInTheDocument() 9 | expect(screen.queryByPlaceholderText('digite seu nome')).toBeInTheDocument() 10 | expect(screen.queryByRole('img')).toBeInTheDocument() 11 | }) 12 | 13 | it('should be able to find the image by the alt text', async () => { 14 | render() 15 | 16 | const image = await screen.findByAltText('ilustração de uma mulher negra usando o computador e segurando uma xícara') 17 | expect(image).toBeInTheDocument() 18 | }) 19 | 20 | it('should be able to get input value correctly', () => { 21 | render() 22 | 23 | const inputElement = screen.queryByPlaceholderText('digite seu nome') 24 | fireEvent.change(inputElement, { 25 | target: { 26 | value: 'Simara' 27 | } 28 | }) 29 | 30 | expect(screen.queryByText('Simara')).toHaveTextContent('Simara') 31 | }) 32 | 33 | it('should be able to render the correct content after user type', () => { 34 | render() 35 | 36 | const input = screen.queryByPlaceholderText('digite seu nome') 37 | 38 | fireEvent.change(input, { 39 | target: { 40 | value: 'Simara' 41 | } 42 | }) 43 | 44 | expect(screen.queryByText('Simara')).toHaveTextContent('Simara') 45 | expect(screen.queryByText('Hello,')).toHaveTextContent('Hello, Simara') 46 | }) 47 | }) -------------------------------------------------------------------------------- /src/ilustracao.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | 15 | * { 16 | background-color: rgb(129, 87, 168); 17 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import './index.css' 4 | import App from './App' 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | --------------------------------------------------------------------------------