Complexidade ciclomática, análise estática e refatoração \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 19 Horas 

 51 Min 

 12 Seg 

   Tempo restante da oferta: 19 51 12 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Complexidade ciclomática, análise estática e refatoração  [ Algoritmos ](https://www.treinaweb.com.br/blog/categoria/algoritmos) 

# Complexidade ciclomática, análise estática e refatoração

 Veremos nesse artigo como se dá a mensuração da complexidade ciclomática; como os analisadores estáticos podem nos auxiliar e a importância da refatoração.

 [ Kennedy Tedesco ](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco) 10 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/background-post.jpg)  

*Complexidade ciclomática* é uma métrica do campo da engenharia de software, desenvolvida por *Thomas J. McCabe* em 1976, e serve para mensurar a complexidade de um determinado módulo (uma classe, um método, uma função etc), a partir da contagem do número de caminhos independentes que ele pode executar até o seu fim. Um caminho independente é aquele que apresenta pelo menos uma nova condição (possibilidade de desvio de fluxo) ou um novo conjunto de comandos a serem executados.

> As métricas de software podem ser definidas como métodos de determinar quantitativamente a extensão em que o projeto, o processo e o produto de software têm certos atributos. Isto inclui a fórmula para determinar o valor da métrica como também sua forma de apresentação e as diretrizes de utilização e interpretação dos resultados obtidos no contexto do ambiente de desenvolvimento de software. *FERNANDES, A. A. (1995) - Gerência de Software através de métricas, São Paulo, Editora Atlas*.

O resultado da complexidade ciclomática indica quantos testes (pelo menos) precisam ser executados para que se verifique todos os fluxos possíveis que o código pode tomar, a fim de garantir uma completa cobertura de testes.

[  ![ASD - Adaptive Software Development](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/asd.svg)   Curso ASD - Adaptive Software Development Conhecer o curso ](https://www.treinaweb.com.br/curso/asd-adaptive-software-development)

## Calculando a complexidade ciclomática

Existem diferentes formas de se calcular:

- Usando a notação de um [grafo de fluxo](https://pt.wikipedia.org/wiki/Grafo_de_fluxo_de_controle);
- Usando [fluxograma](https://pt.wikipedia.org/wiki/Fluxograma);
- Com **análise estática** do código, usando uma ferramenta que automatize essa tarefa.

Tendo um grafo de fluxo ou um fluxograma, temos três fórmulas equivalentes para se mensurar a complexidade ciclomática:

1. **V(G) = R** - onde **R** é o número de regiões do grafo de fluxo.
2. **V(G) = E – N + 2** - onde **E** é o número de arestas (setas) e **N** é o número de nós do grafo G.
3. **V(G) = P + 1** - onde **P** é o número de nós-predicados contidos no grafo G (só funciona se os nós-predicado tiverem no máximo duas arestas saindo.)

***Ps:*** *Nós-predicado* são àqueles que podem desviar o fluxo da execução: *if*, *while*, *switch* etc.

Exemplo usando a notação de grafo de fluxo:

![Grafo de fluxo](https://d2m498l008ebpa.cloudfront.net/2017/02/grafo.png)

> Exemplo retirado do trabalho da professora *Bianca Zadrozny* (do Instituto de Computação da UFF), que pode ser consultado [aqui](http://www2.ic.uff.br/~bianca/engsoft2/index_arquivos/Aula9-EngSoft2.pdf) como excelente referência.

A complexidade ciclomática desse código é **6**. Esse resultado pode ser obtido usando uma das três formas acima descritas:

**1)** **V(G) = R** - onde **R** é o número de regiões do grafo de fluxo.

![Grafo de fluxo 2](https://d2m498l008ebpa.cloudfront.net/2017/02/grafo2-1.jpg)

Temos 6 regiões.

**2)** **V(G) = E – N + 2** - onde **E** é o número de arestas (setas) e **N** é o número de nós do grafo G.

```
V(G) = 17 arestas/setas – 13 nós + 2 = 6

```

**3)** **V(G) = P + 1** - onde **P** é o número de nós-predicados contidos no grafo G.

```
V(G) = 5 nós-predicados + 1 = 6

```

No final temos, então, 6 caminhos independentes. Com isso, sabemos que precisamos ter uma gama de pelo menos 6 testes para garantir uma boa cobertura para esse código.

Os seis caminhos independentes são:

- **1)** 1-2-10-12-13
- **2)** 1-2-10-11-13
- **3)** 1-2-3-10-11-13
- **4)** 1-2-3-4-5-8-9-2-\[…\]
- **5)** 1-2-3-4-5-6-8-9-2-\[…\]
- **6)** 1-2-3-4-5-6-7-8-9-2-\[…\]

Você pode traçar mentalmente um a um. Por exemplo, o primeiro caminho:

- 1-2-10-12-13

![Representação caminhos grafo](https://d2m498l008ebpa.cloudfront.net/2017/02/caminho-1.jpg)

Com os caminhos definidos, você pode planejar os casos de teste para cada um deles.

## Ferramentas para análise estática

Essa é, claro, a mais produtiva forma: usar um analisador estático. Dentre as várias vantagens, temos:

- Precisão;
- Possibilidade de incluir a análise na integração contínua;
- Geração de relatórios da evolução das métricas;

Existem várias ferramentas, você pode pesquisar sobre “análise estática” na linguagem que você utiliza em seus projetos, certamente encontrará várias opções (com focos variados).

Uma ferramenta bastante utilizada é a [*Sonar*](http://www.sonarqube.org/). Ela suporta mais de 25 linguagens. Tem a premissa de avaliar “débito de código” (o “preço” que se paga no futuro por algo que foi implementado no presente sem se preocupar tanto com a qualidade).

Se você desenvolve em **[PHP](https://www.treinaweb.com.br/blog/o-que-e-php/ "O que é PHP?")**, escrevi um artigo sobre [Ferramenta para avaliar a complexidade de código escrito em PHP](https://www.treinaweb.com.br/blog/ferramenta-para-avaliar-a-complexidade-de-codigo-escrito-em-php/).

Se você desenvolve em .NET temos:

- [ReSharper](https://www.jetbrains.com/resharper/) (Oferece muito mais que só análise estática)
- [ndepend](http://www.ndepend.com/) (Tem um foco maior nas relações entre os objetos, acoplamento etc)

## Quais os parâmetros aceitáveis para a complexidade dos meus métodos?

De acordo com o [trabalho](http://www.mccabe.com/pdf/MeasuringSoftwareComplexityUAV.pdf) de *McCabe*, os valores de referência são:

  Complexidade Avaliação   1-10 Método simples. **Baixo risco**.   11-20 Método razoavelmente complexo. **Moderado risco**.   21-50 Método muito complexo. **Elevado risco**.   51-N Método de **altíssimo risco** e bastante instável.  

Esses são apenas valores de referência. O fato de um método ter baixa complexidade não quer dizer que ele não pode ser melhorado ou até mesmo refatorado. Essa é a parte relativa da “coisa”. Caberá a você e a sua equipe identificar esses pontos.

## Como posso melhorar os meus códigos?

Um código com baixa complexidade ciclomática não necessariamente já esgotou todas as possibilidades de melhorias. Há um conjunto de fatores envolvidos. Mas, em termos gerais, refatorar é a melhor “ferramenta” para se ter um código melhor autodocumentado e com menos complexidade.

Nem sempre conseguimos de “prima” acertar em cheio naquilo que desenvolvemos. Para preencher essa lacuna, existe a refatoração: melhorar a compreensão do código existente (sem alterar o seu comportamento).

*[Martin Fowler](https://pt.wikipedia.org/wiki/Martin_Fowler)* criou um catálogo com algumas [técnicas de refatoração](https://refactoring.com/catalog/). Elas são focadas em se ter um código autodocumentado (expressivo, de fácil leitura, coeso etc).

[  ![ASD - Adaptive Software Development](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/asd.svg)   Curso ASD - Adaptive Software Development Conhecer o curso ](https://www.treinaweb.com.br/curso/asd-adaptive-software-development)

Algumas das principais técnicas descritas:

**Substituir recursividade por iteração**: O código recursivo é difícil de entender e na maioria dos casos pode ser substituído por iteração. A não ser que se tenha um objetivo muito bem definido para a existência da recursão (para se ter algum expressivo ganho em performance; ou se você está trabalhando com uma operação muito complexa com árvores binárias etc).

Exemplo (baseado no do catálogo):

```java
public void countDown(int n) {
	if(n == 0) return;

	System.out.println(n + "...");
	waitASecond();
	countDown(n-1);
}

```

Poderia ser escrito assim:

```java
public void countDown(int n) {
	while(n > 0) {
		System.out.println(n + "...");
		waitASecond();
		n -= 1;
	}
}

```

**Decompor condicional:** Quando se têm uma estrutura condicional muito complicada com diversos *if-elseif-else*, pode-se extrair métodos dos resultados dessas condições e invocá-los.

Exemplo (baseado no do catálogo):

```java
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
	charge = quantity * _winterRate + _winterServiceCharge;
} else {
	charge = quantity * _summerRate;
}

```

Poderia ser decomposto para:

```java
if (notSummer(date)) {
  charge = winterCharge(quantity);
} else {
  charge = summerCharge(quantity);
}

```

**Substituir ninhos de condicionais por cláusulas de proteção:** Para tirar a complexidade do entendimento do caminho de execução.

Exemplo (baseado no do catálogo):

```java
double getPayAmount() {
  double result;
  if (_isDead) result = deadAmount();
  else {
    if (_isSeparated) result = separatedAmount();
    else {
      if (_isRetired) result = retiredAmount();
      else result = normalPayAmount();
    };
  }
  return result;
};

```

Poderia ser escrito assim:

```java
double getPayAmount() {
  if (_isDead) return deadAmount();
  if (_isSeparated) return separatedAmount();
  if (_isRetired) return retiredAmount();
  return normalPayAmount();
};

```

**Substituir condicional por polimorfismo:** Tendo um comando condicional que a partir do tipo de objeto escolhe diferentes comportamentos, você pode tornar o método original abstrato e mover essas condicionais para suas próprias subclasses.

Exemplo retirado do [catálogo](https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism):

```java
class Bird {
  //...
  double getSpeed() {
    switch (type) {
      case EUROPEAN:
        return getBaseSpeed();
      case AFRICAN:
        return getBaseSpeed() - getLoadFactor() * numberOfCoconuts;
      case NORWEGIAN_BLUE:
        return (isNailed) ? 0 : getBaseSpeed(voltage);
    }
    throw new RuntimeException("Should be unreachable");
  }
}

```

Poderia ser descomposto para:

```java
abstract class Bird {
  //...
  abstract double getSpeed();
}

class European extends Bird {
  double getSpeed() {
    return getBaseSpeed();
  }
}

class African extends Bird {
  double getSpeed() {
    return getBaseSpeed() - getLoadFactor() * numberOfCoconuts;
  }
}

class NorwegianBlue extends Bird {
  double getSpeed() {
    return (isNailed) ? 0 : getBaseSpeed(voltage);
  }
}

// Somewhere in client code
speed = bird.getSpeed();

```

Outras técnicas com exemplos aplicados, você pode consultar [aqui](https://sourcemaking.com/refactoring/refactorings).

## Focar na qualidade do meu software ou na entrega?

Ideologicamente falando, o processo de refatorar é contínuo. O software vai crescer, precisará ser “tocado” e a refatoração andará lado a lado a tudo isso. Não existe código perfeito, não existe código “à prova de bala”, mas é possível ter código coeso, fácil de ser lido e o principal: fácil de ser testado.

Aliar entrega (o resultado final, o que interessa para a empresa) com qualidade de software é uma questão ampla e complexa. Sabemos que, na maioria das vezes, a realidade é essa: pressão para que as entregas aconteçam o mais rápido possível. Quase nunca entra na análise de tempo e custo o que será gasto para cuidar da qualidade/análise do código. O foco é quase sempre nas entregas e, pensando no lado “corporativo”, elas são extremamente importantes para manter a competitividade da empresa e isso não pode ser ignorado, mas também tem o lado negativo, que é o débito de código (o custo e o tempo que será gasto no futuro para implementar algo novo ou corrigir uma implementação).

Não tem “receita de bolo”, não tem manual, a equipe precisa aprender a mensurar todas essas nuances e achar um “meio termo”. Não dá pra julgar essa guerra de interesses, todos têm seus motivos e suas justificativas.

Outro ponto interessante de reflexão: Não, ninguém usa todas as “melhores técnicas” de codificação (e isso é muito relativo). “Código impecável” e que usa as “melhores técnicas” etc, quase sempre é apenas *case* para palestrantes, professores e artigos (como este aqui). No entanto, isso não tira e nem invalida o fato de que, como desenvolvedores, podemos evoluir, podemos encontrar novas formas e novos conceitos de pensar no “todo” que envolve o desenvolvimento de software. E essa responsabilidade é nossa, não sendo possível delegá-la.

#### Concluindo

Os temas aqui introduzidos são vastos. A ideia não foi a de esgotar os assuntos (e isso nem seria possível), o objetivo principal foi o de acender àquela “chama” que carregamos em nós: àquela que alimenta o nosso amor e interesse pelo desenvolvimento de software. Temos de mantê-la acesa, estudando coisas novas e buscando um conhecimento multimodal.

Até a próxima!

[  ![Desenvolvedor PHP Sênior](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Formação Desenvolvedor PHP Sênior Conhecer a formação ](https://www.treinaweb.com.br/formacao/desenvolvedor-php-senior)

- [ #Linguagens de Programação ](https://www.treinaweb.com.br/blog/tag/linguagens-de-programacao)
- [ #Teste de Software ](https://www.treinaweb.com.br/blog/tag/teste-de-software)
- [ #Engenharia de Software ](https://www.treinaweb.com.br/blog/tag/engenharia-de-software)

Autor

 ![Kennedy Tedesco](//secure.gravatar.com/avatar/236c86e9469327ba7a9250ff15fef424?d=mm)

## Kennedy Tedesco

 Head de desenvolvimento. Vasta experiência em desenvolvimento Web com foco em PHP. Graduado em Sistemas de Informação. Pós-graduando em Arquitetura de Software Distribuído pela PUC Minas. Zend Certified Engineer (ZCE) e Coffee Addicted Person (CAP). [@KennedyTedesco](https://twitter.com/KennedyTedesco) 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/10/04103322/ferramentas-php-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Ferramentas essenciais para um projeto PHP ](https://www.treinaweb.com.br/blog/ferramentas-essenciais-para-um-projeto-php) 

     Neste artigo cito as quatro principais ferramentas que considero essenciais para qualquer projeto PHP: PHPUnit, PHPStan, PHP-CS-Fixer e PHP Insights.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/complexity-code-copy-400x280.jpg)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     10 anos atrás

    ##  [ Ferramenta para avaliar a complexidade de código escrito em PHP ](https://www.treinaweb.com.br/blog/ferramenta-para-avaliar-a-complexidade-de-codigo-escrito-em-php) 

     Conheça um pouco mais sobre a phploc, ferramenta para avaliar a complexidade de código escrito em PHP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/10/TESTE-CAIXA-BRANCA-400x280.png)  [ Testes e Projetos ](https://www.treinaweb.com.br/blog/categoria/testes-e-projetos) 

     6 anos atrás

    ##  [ Principais técnicas de testes estruturais ](https://www.treinaweb.com.br/blog/principais-tecnicas-de-testes-estruturais) 

     O teste estrutural pode ser considerado um dos mais importantes tipos de validação de software, tendo como resultado a diminuição no número de erros no sistema e, portanto, contribuindo com uma maior qualidade e confiabilidade.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/22125738/capa-impacto-software-organizacoes-modernas-400x280.png)  [ Tecnologia ](https://www.treinaweb.com.br/blog/categoria/tecnologia) 

     7 anos atrás

    ##  [ O impacto do software nas organizações modernas ](https://www.treinaweb.com.br/blog/o-impacto-do-software-nas-organizacoes-modernas) 

     Hoje, software tem o poder de definir o destino de organizações inteiras, ressaltando a importância de profissionais na área de desenvolvimento de software.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/08/dicas-etapa-code-challenge-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     3 anos atrás

    ##  [ Dicas para a etapa de code challenge ](https://www.treinaweb.com.br/blog/dicas-para-a-etapa-de-code-challenge) 

     Vai participar de um code challenge? Confira essas dicas para se sair bem nessa etapa da entrevista.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/03/Metodologia-bem-organizando-seu-css-400x280.jpg)  [ CSS ](https://www.treinaweb.com.br/blog/categoria/css) 

     4 anos atrás

    ##  [ Metodologia BEM: organizando seu CSS ](https://www.treinaweb.com.br/blog/metodologia-bem-organizando-seu-css) 

     Melhore a qualidade do código CSS em seu projeto web com a Metodologia BEM. Aprenda como aplicá-la e aproveite seus benefícios.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/11/06145813/react-16-400x280.jpg)  [ Padrões de Projeto ](https://www.treinaweb.com.br/blog/categoria/padroes-de-projeto) 

     4 anos atrás

    ##  [ Boas práticas para o React ](https://www.treinaweb.com.br/blog/boas-praticas-para-o-react) 

     Veja neste artigo algumas das dicas e boas práticas para utilizar em uma aplicação React e tenha um código mais limpo na sua aplicação.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/12/o_que_e_jasmine-400x280.png)  [ Javascript ](https://www.treinaweb.com.br/blog/categoria/javascript) 

     6 anos atrás

    ##  [ O que é Jasmine? ](https://www.treinaweb.com.br/blog/o-que-e-jasmine) 

     Veja neste artigo o que é Jasmine.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/05103838/SIGNALR-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     7 anos atrás

    ##  [ Aplicações em tempo real com ASP.NET Core SignalR ](https://www.treinaweb.com.br/blog/aplicacoes-em-tempo-real-com-asp-net-core-signalr) 

     Aprenda como criar uma streaming api utilizando a biblioteca de aplicações em templo real, SignalR.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/02/13190452/php-cloud-400x280.jpg)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Aplicação Serverless desenvolvida em PHP usando AWS Lambda ](https://www.treinaweb.com.br/blog/aplicacao-serverless-desenvolvida-em-php-usando-aws-lambda) 

     Veja como fazer o deploy de uma aplicação PHP Serverless no AWS Lambda usando o Bref.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/24191010/capa-niveis-desenvolvedor-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     8 anos atrás

    ##  [ O que define um desenvolvedor como júnior, pleno ou sênior? ](https://www.treinaweb.com.br/blog/o-que-define-um-desenvolvedor-como-junior-pleno-ou-senior) 

     Confira neste artigo as diferenças entre os três níveis de desenvolvedores: júnior, pleno e sênior.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/03/08160445/capa-linq-400x280.jpg)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     8 anos atrás

    ##  [ Afinal: o que é de fato o LINQ? ](https://www.treinaweb.com.br/blog/afinal-o-que-e-de-fato-o-linq) 

     O LINQ é uma das features mais legais e poderosas do .NET. Porém, você sabe exatamente o que é o LINQ afinal? Sabe como o LINQ trabalha para tornar suas consultas agnósticas? Vamos responder a estas perguntas neste artigo.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **19h 51min 12s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
