Olá! Boas-vindas a mais um curso de Playwright com Angular. Meu nome é Antônio Evaldo e serei o instrutor.
Audiodescrição: Antônio Evaldo se identifica como uma pessoa branca. No rosto, usa óculos com armação escura arredondada, possui bigode e cavanhaque escuros. Tem cabelos escuros, cacheados e volumosos, na altura dos ombros. No corpo, usa uma camiseta preta. Ao fundo, uma parede lisa com três pôsteres pendurados, iluminada em tons de rosa e azul.
Neste curso, vamos continuar o projeto do Jornada Milhas, realizando mais testes End-to-End nele. Abrindo esse projeto no navegador, veremos que se trata de um aplicativo de busca de passagens, onde é possível fazer login e cadastro.
Falando nisso, também vamos aprender a fazer testes End-to-End nas duas páginas que faltam: de cadastro e de edição de perfil. Vamos verificá-las no Playwright.
Acessando o Playwright, já estamos com a versão final desses testes. Podemos ver no explorador lateral esquerdo que temos um cadastro.spec.ts
com dois novos testes, um deles se chama "Deve conseguir fazer cadastro".
Ao executá-lo, podemos ver na tela principal uma nova aba com as etapas desse teste. Passando o mouse por cima de cada um deles e verificando o conteúdo correspondente na tela principal, conseguimos conferir que os dados estão sendo preenchidos e, no final, o cadastro é feito com sucesso.
A outra parte que vamos implementar é a edicaoDePerfil.spec.ts
, dentro do qual um dos testes é "Deve conseguir editar perfil". Ele possui um processo parecido com o anterior, no qual fazemos cadastro, login, e editamos esse perfil com novos dados.
Nesse processo, vamos aprender muita coisa interessante sobre o Playwright.
Vamos começar o curso entendendo sobre o teste de cadastro de pessoas usuárias, que vai envolver conceitos como isolamento de testes e gerar dados aleatórios utilizando a biblioteca Faker.js.
Em seguida, vamos abordar a otimização de login para os testes que dependem dessa etapa. No processo, vamos entender sobre paralelismo e workers do Playwright, além de alguns conceitos bem interessantes.
Depois, vamos aprender sobre os testes da página de edição de perfil e a reutilização de código entre classes. Por fim, vamos finalizar o curso com chave de ouro, aprendendo sobre Mocks, uma forma de otimizar os testes dependendo do cenário da nossa empresa.
Os requisitos para conseguir realizar este curso são:
Com o conteúdo acima, você terá se preparado para prosseguir neste curso.
Vamos começar a testar?
Já temos o projeto Jornada Milhas baixado no computador. Acesse a atividade de preparação do ambiente nesta aula para que seja possível baixá-lo.
Importante: Mesmo que você já tenha feito esse projeto em outro curso, deve baixá-lo novamente, pois este com o qual vamos trabalhar possui algumas diferenças. Por exemplo, ele possui mais alguns data test ids (ids de teste de dados) e algumas mensagens de erros mais personalizadas.
Vamos abrir o código do projeto no VS Code e abrir o terminal integrado com "Ctrl+'". Nele, já instalamos as dependências com o npm install
, e agora vamos executar o comando abaixo para rodar o projeto front-end.
npm start
Em seguida, vamos abrir o terminal no computador, na pasta da API "jornada-milhasapi". Também já instalamos as dependências para ela, e agora vamos executar com o npm start
.
npm start
Como sempre, precisamos ter esses dois projetos rodando para conseguir executar nossos testes end-to-end.
Enquanto está sendo executado, voltaremos para o terminal do VS Code e conferir que o front-end já está sendo disponibilizado na porta 4200 do localhost.
http://localhost:4200/
Vamos clicar nesse endereço para abrir esse link no navegador. Nele, veremos que o projeto está correto.
Qual é o principal objetivo nesse curso? Temos demandas para realizar novos testes end-to-end em páginas que ainda não foram testadas. No caso, a página de cadastro - que podemos conferir clicando no botão "CADASTRE-SE", no canto superior direito da página - e a página de perfil, que vamos conhecer melhor ao longo do curso.
Antes de começar os testes, vamos verificar o projeto do VS Code. Acessando o explorador lateral esquerdo, podemos conferir a pasta raiz do projeto, que possui uma pasta chamada "e2e". No interior desta última, temos a pasta "page-objects" e os arquivos de teste.
example.spec.ts
fazerLogin.spec.ts
jornadaBuscarPassagens.spec.ts
visitarPaginaInicial.spec.ts
Vamos organizar esse projeto antes de escrevermos os próximos testes, o que também ajudará na manutenção do código.
Primeiro, vamos excluir o arquivo example.spec
, porque ele foi criado por padrão no Playwright e não faz parte do projeto.
Em seguida, dentro da pasta "e2e", vamos criar uma nova pasta chamada "specs" e guardar nossos testes detro dela, selecionando os arquivos fazerLogin.spec.ts
, jornadaBuscarPassagens.spec.ts
e visitarPaginaInicial.spec.ts
com o mouse e os arrastando para seu interior.
Na janela exibida, pressionaremos "Move" para confirmar que queremos mover esses arquivos para a nova pasta. Em seguida, veremos outra janela de diálogo pedindo para atualizar os import
s desses arquivos. Vamos permitir a atualização clicando em "Yes".
Ao acessar o arquivo fazerLogin.spec.ts
, veremos que os erros de importação terão sumido.
No interior da pasta "page-objects", acessaremos o arquivo PaginaLogin.ts
, no qual temos o bloco de código abaixo, por volta da linha 4, que usa uma fixture para facilitar algumas reutilizações de código. Acima dele, temos um import
do conteúdo utilizado.
PaginaLogin.ts
:
import { test as base } from "@playwright/test";
export const test = base.extend<{ paginaLogin: PaginaLogin }>({
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
}
});
Vamos recortar essas linhas com "Ctrl+X" e salvar esse arquivo.
Voltando ao explorador lateral, dentro da pasta "page-objects", vamos criar uma nova pasta chamada "setup" e em seu interior, um novo arquivo chamado fixtures.ts
. Dentro deste, vamos concentrar todas as fixtures do projeto, nos permitindo utilizá-las mais facilmente.
Acessando o interior desse arquivo e fechando o explorador lateral, vamos fazer um "Ctrl+V" nesse código. Por fim, vamos importar esse PaginaLogin
, clicando nele, pressionando "Ctrl+Enter" e selecionando "PaginaLogin".
fixtures.ts
:
import { test as base } from "@playwright/test";
import PaginaLogin from "./PaginaLogin";
export const test = base.extend<{ paginaLogin: PaginaLogin }>({
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
}
});
Vamos salvar esse arquivo e acessar o arquivo fazerLogin.spec
. Em seu interior, temos que corrigir a importação na linha 1: o test
não está em "page-objects/Paginalogin" mas sim em "../setup/fixtures".
fazerLogin.spec
:
import { test } from '../setup/fixtures';
Com isso, os erros terão sumido.
Para deixar o projeto inteiro em congruência com essa nova organização, vamos abrir o arquivo jornadaBuscarPassagens.spec.ts
para usar esses fixtures também.
Em seu interior, podemos tirar a linha const paginaPrincipal = new PaginaPrincipal(page)
com a instanciação.
Após essa alteração, precisamos criar a fixture de paginaPrincipal
. Para isso, voltaremos ao arquivo fixtures.ts
e copiaremos as cinco linhas do bloco paginaLogin: async ({ page }, use) => {}
, adicionaremos uma vírgula após o fechamento de suas chaves e colaremos esse conteúdo na linha seguinte.
No interior desse novo bloco, vamos escrever paginaPrincipal
em todos os lugares que usamos o paginaLogin
.
fixtures.ts
:
export const test = base.extend<{ paginaLogin: PaginaLogin }>({
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
},
paginaPrincipal: async ({ page }, use) => {
const paginaPrincipal = new PaginaPrincipal(page);
await paginaPrincipal.visitar();
await use(paginaPrincipal);
},
});
Vamos importar esse paginaPrincipal
.
import PaginaPrincipal from "e2e/page-objects/PaginaPrincipal";
Por fim, temos que adicionar o paginaPrincipal
na tipagem do base.extend
. Para isso, vamos acessar o interior das chaves desse método e pressionar "Enter" antes e depois de paginaLogin: PaginaLogin
. Acrescentaremos uma vírgula após paginaLogin
, desceremos uma linha e escreveremos paginaPrincipal
do tipo paginaPrincipal
.
export const test = base.extend<{
paginaLogin: PaginaLogin,
PaginaPrincipal: PaginaPrincipal
}>({
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
},
paginaPrincipal: async ({ page }, use) => {
const paginaPrincipal = new PaginaPrincipal(page);
await paginaPrincipal.visitar();
await use(paginaPrincipal);
},
});
Salvaremos esse arquivo e voltaremos para jornadaBuscarPassagens.spec.ts
. Vamos modificar o import
do test
na linha 1 de "@playwright/test" para "../setup/fixtures". Temos que deixar o test
entre chaves para funcionar, já que não é um export default
.
jornadaBuscarPassagens.spec.ts
:
import { test } from "../setup/fixtures";
Também não precisamos mais da importação do paginaPrincipal
, por isso, vamos deletá-la. E por fim, na desestruturação da linha test('Deve buscar passagem de somente ida', async ({ page }) => {
, podemos substituir o page
por paginaPrincipal
.
test.describe('Buscar Passagens', () => {
test('Deve buscar passagem de somente ida', async ({ paginaPrincipal }) => {
// Código omitido
}
Após salvar esse arquivo, podemos rodar os testes para ver se tudo o que fizemos continua funcionando após essa pequena refatoração.
Vamos abrir o terminal integrado e criar um novo terminal, clicando no botão de "+" no canto superior direito. Em seu interior, vamos rodar o script com o comando abaixo.
npm run e2e-ui
Esse comando existe no package.json
e vai executar a interface do Playwright em uma nova janela.
Emseu interior, se acessarmos o explorador lateral esquerdo e clicarmos no botão de "play" para pedir que todos os nossos testes sejam executados, esperamos que tudo continue funcionando.
Enquanto esperamos a execução, podemos expandir alguns desses arquivos de teste clicando na seta à esquerda de cada um no explorador.
Após a execução, veremos que alguns testes já estão passando, pois exibem um sinal de "check" verde à sua esquerda.
Somente um teste exibe um xis vermelho, indicando que não passou: o de fazer login. Vamos descobrir ao longo do curso porque ele não passou, mas podemos adiantar que tem algo a ver com o cadastro.
Depois dessas refatorações, nos preparamos para escrever os testes. Nos veremos lá!
Nós já organizamos melhor o projeto, criamos mais pastas e arquivos e organizamos as features (funcionalidades) em um único local. Isso vai nos ajudar a escrever mais testes novos, que é exatamente o que vamos fazer agora.
Lembrando que temos alguns testes para implementar, e vamos começar pelo teste da página de cadastro. Como é uma página nova, precisaremos criar um novo Page Object no projeto.
Com o explorador do VS Code aberto, vamos abrir a pasta "page-objects", acessar o arquivo PaginaLogin.ts
e copiar todo o código em seu interior, porque ele possui a base que vamos utilizar no novo arquivo.
Após a cópia, fecharemos esse arquivo e voltaremos ao explorador. Dentro da pasta "page-objects", vamos criar um novo arquivo chamado PaginaCadastro.ts
. Acessaremos o seu interior, fecharemos a barra do explorador e colaremos o código.
Em seguida, vamos renomear a classe de PaginaLogin
para PaginaCadastro
. Dentro das chaves dessa classe, vamos remover os private readonly
de botaoLogin
, inputEmail
, inputSenha
e botaoAcessarConta
, mantendo apenas o private readonly page
como propriedade dessa classe.
Entre as chaves do construtor, removeremos as atribuições que não precisamos mais, mantendo somente a linha this.page = page
.
Já entre as chaves do método visitar
, vamos comentar a segunda e a terceira linha, mantendo ativa apenas a await this.page.goto('/')
que visita a URL base.
Em seguida, vamos apagar os métodos fazerLogin
e loginFeitoComSucesso
, porque não vamos precisar deles. Vamos manter somente o método estaMostrandoMensagemDeErro
, porque vamos utilizá-lo nessa página.
PaginaCadastro.ts
:
import { Locator, Page, expect } from "@playwright/test";
export default class PaginaLogin {
private readonly page: Page;
constructor(page: Page) {
this.page = page;
}
async visitar() {
await this.page.goto('/');
// await this.botaoLogin.click();
// await expect(this.page).toHaveURL('/auth/login');
}
async estaMostrandoMensagemDeErro(mensagem: string) {
const elementoErro = this.page.getByText(mensagem);
await expect(elementoErro).toBeVisible();
}
}
Após as alterações, podemos salvar esse arquivo.
Como temos essa classe nova, podemos criar uma fixture para ela também. No explorador lateral, vamos abrir o arquivo fixtures.ts
na pasta "setup". Em seu interior, vamos mover o bloco pagina principal
de lugar, do final do arquivo para cima do paginaLogin
.
Fizemos isso porque, para mim, Antônio Evaldo, faz mais sentido esse bloco ficar antes de paginaLogin
. Vamos mudar a ordem dos objetos da Generics também, entre os sinais de menor e maior de base.extend
.
fixtures.ts
:
export const test = base.extend<{
PaginaPrincipal: PaginaPrincipal,
paginaLogin: PaginaLogin,
}>({
paginaPrincipal: async ({ page }, use) => {
const paginaPrincipal = new PaginaPrincipal(page);
await paginaPrincipal.visitar();
await use(paginaPrincipal);
},
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
},
});
Vamos copiar o bloco de paginaLogin
e colar logo abaixo de si mesmo, sem sair das chaves do objeto do base.extend
. Nessa cópia, vamos substituir todos os locais que tem PaginaLogin
por paginaCadastro
.
No objeto da fixture, entre os sinais de menos e mais de base.extend
, também precisamos adicionar a tipagem de paginaCadastro
do tipo paginaCadastro
.
export const test = base.extend<{
PaginaPrincipal: PaginaPrincipal,
paginaLogin: PaginaLogin,
paginaCadastro: paginaCadastro
}>({
paginaPrincipal: async ({ page }, use) => {
const paginaPrincipal = new PaginaPrincipal(page);
await paginaPrincipal.visitar();
await use(paginaPrincipal);
},
paginaLogin: async ({ page }, use) => {
const paginaLogin = new PaginaLogin(page);
await paginaLogin.visitar();
await use(paginaLogin);
},
paginaCadastro: async ({ page }, use) => {
const paginaCadastro = new paginaCadastro(page);
await paginaCadastro.visitar();
await use(paginaCadastro);
},
});
Vamos importar esse paginaCadastro
e organizar os imports
na ordem abaixo, que se estendem da linha 1 à 4.
import { test as base } from "@playwright/test";
import PaginaPrincipal from "e2e/page-objects/PaginaPrincipal";
import PaginaLogin from "e2e/page-objects/PaginaLogin";
import PaginaCadastro from "e2e/page-objects/PaginaCadastro";
Com isso, os erros sumiram, portanto, deve estar tudo ok. Salvaremos esse arquivo.
Para completar esse fluxo, vamos criar dentro da pasta "specs" um novo arquivo chamado cadastro.spec.ts
. Em seu interior, para relembrar o código de testes, vamos escrever test
e, entre as sugestões do editor, selecionar o "test" importado de "e2e/setup/fixtures". É importante fazer isso.
cadastro.spec.ts
:
import { test } from "e2e/setup/fixtures";
Na linha 3, adicionaremos o test.describe
. Entre um par de parênteses e entre aspas simples, vamos chamar esse cenário de testes de Página de cadastro
.
Adicionando uma vírgula após as aspas, colocaremos uma arrow function (função seta) como segundo parâmetro, digitando () => {}
. Entre as chaves dessa função, vamos colocar test
, um par de parênteses e entre estes, digitaremos o nome do primeiro teste entre aspas duplas: Deve conseguir fazer cadastro
. Esse teste representa o caminho feliz.
À direita das aspas duplas, adicionaremos uma função seta como segundo parâmetro, transformando-a em assíncrona, adicionando um async
à sua esquerda. Entre os parênteses dessa função, vamos abrir um par de chaves e entre elas, desestruturar nos parâmetros a fixture chamada paginaCadastro
.
Ao digitar parte do nome da fixture, ela aparecerá nas sugestões, indicando que está disponível para nós e que o código está dando certo até agora.
Por fim, podemos escrever await paginaCadastro.visitar()
entre as chaves da função seta assíncrona.
test.describe('Página de cadastro', () => {
test("Deve conseguir fazer cadastro", async ({ paginaCadastro }) => {
await paginaCadastro.visitar();
}
}
Salvaremos esse arquivo e voltaremos ao Playwright para conferir em sua interface se vamos conseguir visitar, pelo menos, a página principal do Jornada Milhas.
Na aba do explorador na lateral esquerda, o novo arquivo, o novo cenário e o novo teste já apareceram na interface. Vamos executar esse teste clicando no botão de "play" à sua direita e esperar.
Após a execução, parece que deu tudo certo. Veremos na aba de ações exibida à esquerda da tela principal que o teste passou.
Passed
É importante notar que não estamos mais usando a opção "Watch All", que possui o ícone de um olho, para observar todas as mudanças dos arquivos e executar os testes automaticamente. Desmarcamos propositalmente, porque isso impactaria em alguns testes.
Alguns testes teriam efeitos colaterais caso fossem executados toda vez que modificássemos um arquivo. Por esse motivo, vamos executar os testes manualmente neste curso.
Até agora, deu tudo certo. Vamos finalizar essa parte verificando se conseguimos visitar a página de cadastro.
Vamos voltar no VS Code, no Page Object do arquivo PaginaCadastro.ts
. Em seu interior, vamos colar a parte que faz a atribuição de todos os locators, ou seja, todos os elementos com os quais vamos precisar interagir na página de cadastro.
Vamos copiar todas as atribuições, disponíveis abaixo. Lembrando que todos os data test ids já estão no projeto.
PaginaCadastro.ts
:
this.botaoVisitarPaginaCadastro = page.getByTestId('header-botao-cadastre-se');
this.inputNome = page.getByTestId('form-base-input-nome');
this.inputDataNascimento = page.getByTestId('form-base-input-data-nascimento');
this.inputCpf = page.getByTestId('form-base-input-cpf');
this.inputCidade = page.getByTestId('form-base-input-cidade');
this.inputTelefone = page.getByTestId('form-base-input-telefone');
this.inputEstado = page
.getByTestId('form-base-container-estado')
.getByLabel('Estado');
this.inputEmail = page.getByTestId('form-base-input-email');
this.inputSenha = page.getByTestId('form-base-input-senha');
this.inputConfirmarEmail = page.getByTestId('form-base-input-confirmar-email');
this.inputConfirmarSenha = page.getByTestId('form-base-input-confirmar-senha');
this.botaoSubmeterForm = page.getByTestId('form-base-botao-submeter-form');
this.checkboxTermos = page
.getByTestId('form-base-checkbox-termos')
.getByLabel('Li e aceito os termos e condições deste cadastro');
}
Dentro do construtor, pulando uma linha abaixo de this.page = page
, vamos colar o conteúdo copiado.
export default class PaginaCadastro {
private readonly page: Page;
constructor(page: Page) {
this.page = page;
this.botaoVisitarPaginaCadastro = page.getByTestId('header-botao-cadastre-se');
this.inputNome = page.getByTestId('form-base-input-nome');
this.inputDataNascimento = page.getByTestId('form-base-input-data-nascimento');
this.inputCpf = page.getByTestId('form-base-input-cpf');
this.inputCidade = page.getByTestId('form-base-input-cidade');
this.inputTelefone = page.getByTestId('form-base-input-telefone');
this.inputEstado = page
.getByTestId('form-base-container-estado')
.getByLabel('Estado');
this.inputEmail = page.getByTestId('form-base-input-email');
this.inputSenha = page.getByTestId('form-base-input-senha');
this.inputConfirmarEmail = page.getByTestId('form-base-input-confirmar-email');
this.inputConfirmarSenha = page.getByTestId('form-base-input-confirmar-senha');
this.botaoSubmeterForm = page.getByTestId('form-base-botao-submeter-form');
this.checkboxTermos = page
.getByTestId('form-base-checkbox-termos')
.getByLabel('Li e aceito os termos e condições deste cadastro');
}
//Código omitido
}
Nesse código, temos todos os elementos com os quais vamos precisar interagir na página de cadastro. Estamos pegando o botaoVisitarPaginaCadastro
, por exemplo, e partir dessa página, recuperamos os inputs de nome, data de nascimento, CPF, cidade e telefone. Conforme dito, todos eles estão tomando como base data test ids que já estão no código.
Agora, vamos dar um "Ctrl+." em um desses elementos que estão com erro no VS Code para acionar a lista de sugestões "Quick Fix" (correção rápida). Nela, vamos selecionar a opção de adicionar todos os membros faltantes ("Add all missing members").
Com isso, o VS Code adicionará automaticamente todas essas propriedades na classe, e nos bastará adicionar um private readonly
antes de cada uma.
Para selecionar várias linhas no mesmo local, ao mesmo tempo, clicaremos no início da primeira linha de propriedades e seguraremos o botão de rolagem do mouse. Com isso, podemos escreveremos private read-only
apenas uma vez.
export default class PaginaCadastro {
private readonly page: Page;
private readonly botaoVisitarPaginaCadastro: Locator;
private readonly inputNome: Locator;
private readonly inputDataNascimento: Locator;
private readonly radiosGenero: { [chave in Genero]: Locator };
private readonly inputCpf: Locator;
private readonly inputCidade: Locator;
private readonly inputTelefone: Locator;
private readonly inputEstado: Locator;
private readonly inputEmail: Locator;
private readonly inputSenha: Locator;
private readonly inputConfirmarEmail: Locator;
private readonly inputConfirmarSenha: Locator;
private readonly botaoSubmeterForm: Locator;
private readonly checkboxTermos: Locator;
constructor(page: Page) {
// Código omitido
}
O próximo passo é acessar o método visitar
e descomentar as duas linhas que tínhamos comentado.
Na primeira linha descomentada, vamos substituir o botaoLogin
por botaoVisitarPaginaCadastro
, pois é nele que vamos clicar para visitar a página de cadastro. Já na linha await expect
, entre os parênteses de toHaveURL
, esperaremos a nova URL /auth/cadastro
em vez de /auth/login
.
async visitar() {
await this.page.goto('/');
await this.botaoVisitarPaginaCadastro.click();
await expect(this.page).toHaveURL('/auth/cadastro');
}
Salvaremos esse arquivo e voltaremos ao Playwright. Vamos executar mais uma vez o teste desse arquivo, "Deve conseguir fazer cadastro", e ver se funciona.
Após aguardar um pouco, veremos que o teste passou.
Passed.
Conseguimos conferir na tela principal que a página de cadastro realmente foi renderizada.
O próximo passo seria começar a interagir com os elementos dessa página, preencher os campos e tentar fazer um cadastro de verdade. No próximo vídeo, vamos ver um aspecto importante em relação a essa parte.
Te esperamos lá!
O curso Angular: teste e otimize o fluxo de autenticação com Playwright possui 143 minutos de vídeos, em um total de 49 atividades. Gostou? Conheça nossos outros cursos de Angular em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.