Henrique Zolini Logo
SVG shape SVG shape SVG shape SVG shape

Olá, sou Henrique Zolini Sobre Mim

Um desenvolvedor experiente, criativo e atento aos mínimos detalhes.

Desenvolvedor há mais de 14 anos, cursei técnico em informática, técnico em administração para pequenas e médias empresas, técnico em habilidades gerenciais e analise de sistemas.

Gosto de compartilhar meu conhecimento e ajudar outras pessoas a adotarem as tecnologias pelas quais sou apaixonado. Faço isso transmitindo meu trabalho ao vivo, revisando o código da comunidade, desenvolvendo projetos de código aberto e escrevendo postagens técnicas em blogs.

Sou capaz de aprender rapidamente novas ferramentas e tecnologias quando necessário. Costumo identificar a necessidade de novos sistemas ou ferramentas para melhorar a eficiência do fluxo de trabalho. Estou sempre motivado por um desafio e gosto de estar bem organizado para entregar resultados consistentes.

SVG shape SVG shape SVG shape

O que eu faço? Serviços

 Demo Icons

Websites

Criação de websites com foco na experiência do usuário, modernos e atualizados com as últimas técnologias do mercado.

Demo Icons

Softwares

Sistemas personalizados de alta tecnologia, desenvolvidos cuidadosamente a partir das necessidades de cada cliente.

Demo Icons

Aplicativos

Apps personalizados para os sistemas Android e iOS, desenvolvidos cuidadosamente a partir das necessidades de cada cliente.

Demo Icons

UX Design

Criação de projetos para Websites, Sistemas e Aplicativos afim de facilitar o entendimento e proporcionar a melhor experiência ao usuário.

Demo Icons

Consultoria

Análise e planejamento para encontrar as tecnologias certas para o seu negócio e levar da maneira correta o seu projeto ao sucesso.

Demo Icons

Treinamentos

Cursos, aulas e treinamentos para pessoas que desejam entrar ou se especializar na área de tecnologia e desenvolvimento de software.

ExperiênciaExperiência

Formação

Analise E Desenvolvimento De Sistemas

2021 Faculdade Estácio

O curso superior de tecnologia em Análise e Desenvolvimento de Sistemas visa capacitar o profissional a analisar, projetar, desenvolver e implantar sistemas de informação.

Técnico Em Informática

2011 Cotemig Colégio e Faculdade

O ensino médio com técnico reúne em três anos de curso, os conhecimentos do ensino médio regular e as competências de analisar, projetar, desenvolver e implantar sistemas de informação.

Liderança com Foco em Resultados

2011 Senac Minas

Curso técnico com carga horária de 21h com foco no aprimoramento em planejamento dos processos e atividades, visando à melhoria dos desempenhos de pessoas e equipes de trabalho.

Habilidade Gerenciais

2010 Senac Minas

Curso técnico com carga horária de 21h com foco no aprimoramento das habilidades gerenciais de comunicação, liderança e resolução de conflitos para promover o sucesso de suas equipes.

Experiência

Grupo Boticário

Atual Especialista Full-Stack

Atuação como Tech Lead/Especialista Full-Stack trabalhando na arquitetura e desenvolvimento de projetos utilizando ReactJS, ES6, NodeJS, APIs, GCP Big Query, CSS3 e HTML5.

Getrak

2021 Desenvolvedor Full-Stack

Atuação como Desenvolvedor Full-Stack, trabalhando na arquitetura e desenvolvimento de projetos utilizando ReactJS, React Native, VueJS, ES6, NodeJS, PHP Laravel, CSS3 e HTML5.

Nerus Software

2020 Desenvolvedor Full-Stack

Atuação como analista FullStack, trabalhando na arquitetura e desenvolvimento de projetos utilizando Docker, NodeJS, Webpack, ES6, React, Apollo Server, GraphQL, Axios e Material Design.

Pixew

2016 CEO / CTO

Responsável pelo levantamento de requisitos, escopo e gestão de equipes para desenvolvimento de sistemas. Acompanhamento do desenvolvimento do produto para grantir a qualidade do produto.

Skills Skills

React
95%
React Native
95%
NodeJS
90%
Javascript
90%
HTML5
95%
CSS3
85%
NextJS
85%
PHP
80%
MySQL
90%
Docker
90%
Também AWS, Vercel, Apollo, GraphQL, Redux, Webpack, VueJS, jQuery, Laravel, Java, Elixir, Python. Photoshop e Illustrator.

RecomendaçõesRecebidas

Quote icon
Quote icon
Quote icon

O Henrique foi meu líder durante 1 ano na iYer Solutions. Destaco a sua capacidade técnica, paciência na passagem de conhecimento, a capacidade de trabalho, o rigor e a forte orientação para entregas de valor. Trabalhamos num momento em que grandes paradigmas e padrões de desenvolvimento estavam emergindo e ao longo do tempo, os desafios foram crescendo, com a régua mais alta na concretização de objetivos e alcance de resultados. Sempre foram superados, com uma equipa motivada e bem liderada por ele. Esta capacidade de engajamento em ambiente de crescente tensão por resultados, sempre superados, não é para todos, mas é inerente ao Henrique. Por isso, o recomendo com toda a certeza que ele é totalmente capaz de assumir qualquer posição técnica e de liderança em uma organização.

Rodrigo Assis
Product Owner na Acordo Certo

Tive a oportunidade de ter o Henrique como meu mentor durante um tempo e foi muito gratificante. Me ensinou muito além do que os livros mostram, e sim o que o mercado exige na prática. Tem muita facilidade em buscar e aplicar soluções pertinentes ao problema, o que facilita muito na aprendizagem. É uma pessoa que tem paixão no que faz. Obrigado por tudo!

Ricardo Alves
Analista de Customer Success na Getrak

Profissional extremamente dedicado, pontual e competente!

Geovanna Britto
Analista de Cultura na Getrak
SVG circle shape

BlogBlog

Demo Image
10, Julho de 2024 Henrique Zolini

Cobertura de Testes x Qualidade

Photo by Arnold Francisca on Unsplash

Gostaria de compartilhar uma reflexão pessoal e uma dificuldade constante que enfrento diariamente: como garantir a qualidade dos testes? Este é um tema que me motiva a explorar a relação entre cobertura e qualidade. Diariamente, percebo como essa questão influencia diretamente na entrega dos produtos.

Na minha percepção, os líderes de alta hierarquia acreditam que uma cobertura de testes de 100% garante a qualidade e o funcionamento adequado dos produtos. A cobertura de testes unitários é amplamente considerada um indicador crucial de qualidade de software, pois sugere que toda a lógica do código foi testada antes da implantação. No entanto, mesmo assim, os produtos ainda podem falhar. Por quê?

Eu mesmo já investi horas criando testes unitários para alcançar uma cobertura acima de 90%, apenas para descobrir, na fase de produção, que o produto ainda continha bugs. Muitos desenvolvedores experientes já passaram por isso: cumprir as métricas do Sonar ou de algum painel de controle, mas sem alcançar o resultado esperado. Por quê?

A cobertura de testes basicamente indica que todas as unidades de código têm um teste correspondente. Mas isso é apenas o começo. Usar a cobertura de testes unitários como único indicador de confiabilidade do produto apresenta riscos significativos. Primeiro, ela não valida o produto como um todo. Segundo, os próprios testes unitários podem ser mal concebidos ou de baixa qualidade. A maioria das ferramentas automatizadas, como o Sonar, não consegue discernir isso. Elas simplesmente afirmam que todas as unidades são testadas, sem avaliar a qualidade desses testes.

Por exemplo, se um desenvolvedor cria um teste unitário que verifica algo tão trivial como “1 é igual a 1”, sem realizar asserções válidas, ferramentas de análise estática como o Sonar interpretam isso como uma unidade de código coberta por um teste, embora isso não prove efetivamente nada.

Eu já cansei de ver testes que não têm utilidade prática, como por exemplo:

Teste de componente que verifica título passado como prop

import React from 'react';
import { render } from '@testing-library/react';
import Layout from './Layout';

test('renders the title passed as prop', () => { // (cobertura de 100%)
  const { getByText } = render(<Layout titulo="Test Title">Content</Layout>);
  const titleElement = getByText(/Test Title/i);
  expect(titleElement).toBeInTheDocument();
});

Por que isso não serve para nada?

  • Este teste apenas verifica se o componente renderiza o título passado como prop, algo que é muito simples e não cobre lógica ou comportamento do componente.
  • Testes que não têm lógica de negócio complexa tornam-se redundantes.

Testes de cálculo simples

function add(a, b) {
  return a + b;
}

test('adds 1 + 2 to equal 3', () => { // (cobertura de 100%)
  expect(add(1, 2)).toBe(3);
});

Por que isso não serve para nada?

  • É obvio que 1 + 2 é 3.
  • Testar uma função simples de adição não agrega valor, pois a operação de adição é garantida pelo próprio JavaScript.
  • Testes de lógica trivial geralmente não refletem a complexidade e os casos de uso reais do sistema.
O importante não é obter 100% de cobertura do código fonte. O importante deve ser cobrir todos os cenários que possuam uma lógica que, se alterada, vai afetar o core do produto. Um teste deve ser criado para proteger uma lógica de negócios e minimizar o risco.

Para ilustrar um cenário, vou dar um exemplo, que reflete bem os problemas dos testes apenas para bater cobertura.

Código

class BankAccount {
  constructor(initialBalance) {
    this.balance = initialBalance;
  }
  deposit(amount) {
    if (amount > 0) {
      this.balance += amount;
    }
  }
  getBalance() {
    return this.balance;
  }
}
module.exports = BankAccount;

Teste Unitário Ruim

const BankAccount = require('./BankAccount');

test('testDepositPositiveAmount', () => {
  const account = new BankAccount(100);
  account.deposit(50);
  expect(account.getBalance()).toBe(150);
});

test('testGetBalance', () => {
  const account = new BankAccount(100);
  expect(account.getBalance()).toBe(100);
});

Por que este é um teste unitário ruim?

  • Cobertura Superficial: Apenas verifica se a função deposit adiciona valores positivos e se getBalance retorna o saldo inicial. Não cobre outros cenários.
  • Falta de Testes Negativos: Não há verificação de comportamento para valores inválidos ou negativos.
  • Sem Validação de Tipos: Não testa comportamentos para tipos de dados incorretos, como strings ou valores null.
  • Baixa Robustez: Não garante que a lógica de negócio está correta para todos os cenários possíveis.

Teste Unitário Bom

describe('BankAccount', () => {
  test('should initialize with the correct balance', () => {
    const account = new BankAccount(100);
    expect(account.getBalance()).toBe(100);
  });

  test('should deposit positive amount correctly', () => {
    const account = new BankAccount(100);
    account.deposit(50);
    expect(account.getBalance()).toBe(150);
  });

  test('should not deposit negative amount', () => {
    const account = new BankAccount(100);
    account.deposit(-50);
    expect(account.getBalance()).toBe(100);
  });

  test('should not deposit zero amount', () => {
    const account = new BankAccount(100);
    account.deposit(0);
    expect(account.getBalance()).toBe(100);
  });

  test('should handle string deposit gracefully', () => {
    const account = new BankAccount(100);
    account.deposit("50");
    expect(account.getBalance()).toBe(100);
  });

  test('should handle null deposit gracefully', () => {
    const account = new BankAccount(100);
    account.deposit(null);
    expect(account.getBalance()).toBe(100);
  });

  test('should handle undefined deposit gracefully', () => {
    const account = new BankAccount(100);
    account.deposit(undefined);
    expect(account.getBalance()).toBe(100);
  });
});

Por que este é um teste unitário bom?

  • Cobertura Completa: Cobre todos os caminhos possíveis de execução da função deposit.
  • Testes Negativos: Verifica comportamentos para valores inválidos, como negativos e zero.
  • Validação de Tipos: Garante que a função deposit lida corretamente com tipos de dados incorretos, como strings, null e undefined.
  • Robustez e Confiabilidade: Garante que a lógica de negócio está correta e robusta contra entradas inválidas e casos de borda.
  • Segregação de Cenários: Cada cenário de teste é separado, facilitando a manutenção e entendimento do código de teste.

AMBOS OS TESTES APRESENTAM 100% DE COBERTURA. O ponto que quero destacar aqui é que, às vezes, tratar a cobertura de testes com tanta importância cria um ambiente de trabalho maçante, onde as pessoas precisam testar até cenários inúteis para atender à meta de cobertura. Isso leva a um comportamento em que as pessoas param de raciocinar e pensar de fato em quais testes são importantes, criando testes apenas para garantir essa meta.

Muitas vezes, a meta de cobertura de 100% é vista como um tabu, fazendo com que se testem até métodos sem importância, apenas para que as ferramentas indiquem 100% de cobertura. Esse tipo de pensamento pode causar sérios problemas, pois as pessoas deixam de considerar os casos de teste realmente importantes e acabam negligenciando cenários críticos.

Para concluir, é importante refletir sobre como podemos melhorar a qualidade dos nossos testes, em vez de focar na cobertura, uma métrica que não indica nada de concreto.

Acredito que testes estão intrinsecamente ligados à cultura, responsabilidade e ao dia a dia do desenvolvedor. Eles devem ser encarados como uma prática contínua e aprimorada constantemente, e não apenas uma meta numérica a ser atingida.

Espero que este artigo tenha sido útil para uma reflexão. Agradeço por dedicar seu tempo para ler e espero ter contribuído de alguma forma para o seu conhecimento. Fique à vontade para compartilhar suas opiniões nos comentários e continuar essa conversa. Até a próxima!

Demo Image
03, Março de 2024 Henrique Zolini

O Dilema dos Product Managers

Photo by Jo Szczepanska on Unsplash

Com 15 anos de experiência no mercado de tecnologia, vivenciei em primeira mão os desafios que podem surgir quando Product Managers (PMs) não possuem formação ou experiência em tecnologia. Essa realidade, cada vez mais comum, gera problemas como requisitos infundados, divergentes e mal pensados, impactando negativamente o desenvolvimento de software.

Antigamente, os analistas de requisitos, geralmente formados em Sistemas de Informação, coletavam as necessidades dos usuários e as traduziam em linguagem técnica para a equipe de desenvolvimento. Com a popularização das metodologias ágeis, o papel do PM se expandiu, absorvendo essa responsabilidade.

No entanto, a crescente demanda por PMs nem sempre acompanha a busca por profissionais com expertise técnica. A contratação de PMs sem formação ou vivência em tecnologia, baseada apenas em cursos rápidos, é uma tendência preocupante que exige uma análise mais profunda.

Estudo de caso: Consequências da falta de expertise técnica

Problemas específicos que vivenciei:

Requisitos infundados:

  • Exigência de funcionalidades impossíveis, como a criação de um sistema complexo em um curto período de tempo.
  • Propostas irreais que não consideravam as limitações técnicas existentes.

Requisitos divergentes:

  • Mudanças constantes nos requisitos, gerando retrabalho e atrasos no cronograma.
  • Falta de clareza sobre as prioridades, levando a decisões inconsistentes.

Requisitos mal pensados:

  • Especificações incompletas ou ambíguas, levando a interpretações errôneas e resultados indesejáveis.
  • Falta de atenção aos detalhes, resultando em software com bugs e falhas no processo do usuário.

Para entender melhor as raízes do problema, investiguei os perfis de LinkedIn de alguns PMs com quem trabalhei. A descoberta foi alarmante: a grande maioria não possuía nenhuma experiência com desenvolvimento de software ou formação em tecnologia.

Formação dos PMs:

  • Cursos rápidos online: A maioria dos PMs havia realizado apenas cursos rápidos de Product Management na internet.
  • Formações diversas: A formação original desses PMs era em áreas completamente diferentes, como Geografia, Design de Interiores e até Música.

Ao analisar a trajetória dos melhores PMs com quem tive o prazer de colaborar, um padrão interessante se desenhou: a maioria possuía formação em áreas como Sistemas de Informação, Ciência da Computação ou, no mínimo, experiência prática com desenvolvimento de software. Essa vivência proporcionava uma compreensão profunda das nuances e desafios do processo de desenvolvimento, tornando-os parceiros valiosos para as equipes.

Conclusão:

Embora a metodologia ágil tenha expandido o papel do PM, a experiência e formação em tecnologia continuam sendo cruciais para o sucesso na função. A busca por profissionais com esse perfil é fundamental para garantir a qualidade dos produtos de software e evitar os desafios mencionados neste artigo.

Este artigo é apenas um ponto de partida para uma reflexão crítica sobre o papel dos Product Managers no mercado de tecnologia. A discussão sobre o tema é complexa e envolve diversos fatores.

Espero que este artigo tenha sido útil para uma reflexão. Agradeço por dedicar seu tempo para ler e espero ter contribuído de alguma forma para o seu conhecimento. Fique à vontade para compartilhar suas opiniões nos comentários e continuar essa conversa. Até a próxima!

Demo Image
22, Agosto de 2023 Henrique Zolini

Respeite o Processo

A sabedoria por trás dos prazos e do crescimento sustentável.

Em qualquer campo em que você atue, é provável que já tenha se deparado com a seguinte situação: prazos apertados e a pressão para entregar resultados imediatos. Muitas vezes, essa urgência é acompanhada da ideia de que basta alocar mais recursos humanos para acelerar o processo. No entanto, essa abordagem simplista e apressada ignora um princípio fundamental que permeia todas as áreas de atuação, desde TI até marketing, administração, lançamento de produtos e muito mais: o respeito pelo processo.

A armadilha da pressa e da desconsideração do processo

É uma armadilha comum cair na crença de que adicionar mais pessoas a uma tarefa automaticamente resultará em uma entrega mais rápida. Esse equívoco se origina da suposição de que o trabalho é uma linha de montagem simples, onde cada novo par de mãos contribui linearmente para a produtividade. Infelizmente, a realidade é muito mais complexa.

Imagine dobrar o tamanho de uma equipe de desenvolvimento de software para atender a um prazo apertado. Embora a intenção seja nobre, essa abordagem muitas vezes leva a resultados desastrosos. A curva de aprendizado das novas pessoas, a necessidade de alinhamento e comunicação eficiente, a coordenação do trabalho e outros fatores podem na verdade atrasar o processo.

O Professor William Ibbs da Universidade de Berkeley, fez uma coletânea de 14 estudos sobre os efeitos do aumento forçado do efetivo em frentes de serviço nos projetos de capital. O primeiro gráfico abaixo mostra uma relação percentual entre “%” do aumento do efetivo e o “%” da queda de produtividade.

Tomando o estudo do Corps of Engineers como uma média das curvas, podemos observar que um aumento forçado de 20% do efetivo causa uma perda de 10% de produtividade. Em outras palavras, um aumento de 20% não vai dar uma aumento da produção de 20% e sim de 10%, ou seja, um custo de 10% maior de mão-de-obra no projeto.

Em alguns casos, quando não se observa essa perda, o que ocorre é um plano de recuperação que cai por terra já no primeiro ciclo de medição. Contudo, ainda pode ficar na subjetividade do que seria um “aumento forçado” do efetivo.

Além disso, esquecer a importância do processo é ignorar a natureza intrínseca da maturação. Cada projeto, seja ele um código de software ou um plano de marketing, exige tempo para evoluir, ajustar-se e alcançar a qualidade desejada. Tentar acelerar artificialmente esse processo muitas vezes resulta em um produto ou serviço insatisfatório, com problemas que só emergirão após o lançamento.

O valor do conhecimento e do espaço de trabalho

Não podemos subestimar a importância do conhecimento especializado e do espaço de trabalho adequado. Introduzir pessoas sem a experiência necessária pode levar a erros, retrabalho e ineficiências. Da mesma forma, um ambiente de trabalho adequado, com recursos e ferramentas corretas, é fundamental para a eficácia e a qualidade do trabalho.

O conhecimento não é algo que pode ser adquirido da noite para o dia. Portanto, uma abordagem mais sensata é investir na capacitação da equipe existente ou contratar recursos que possuam a expertise necessária. Isso garantirá que as pessoas estejam aptas a enfrentar os desafios que o projeto apresenta.

O papel do planejamento e da análise de riscos

A otimização dos processos é um objetivo válido, mas ela deve ser conduzida de maneira sensata e realista. Um planejamento detalhado, aliado a uma análise de riscos adequada, é fundamental para guiar as mudanças necessárias sem comprometer a qualidade ou a eficiência.

Antes de implementar mudanças radicais, é importante avaliar as possíveis consequências, identificar os gargalos existentes e desenvolver estratégias para mitigar riscos. Uma abordagem gradual, testando e ajustando as mudanças, muitas vezes leva a resultados mais satisfatórios a longo prazo.

O equilíbrio entre velocidade e qualidade

Respeitar o processo não é apenas uma filosofia vaga, mas uma abordagem sábia e pragmática que vale a pena abraçar em todas as áreas. Não importa se estamos falando de desenvolvimento de software, marketing, operações ou qualquer outra disciplina — a pressa imprudente raramente leva a bons resultados.

Em vez de ceder à tentação de “mais rápido, mais rápido”, devemos reconhecer a importância do processo de maturação, do conhecimento especializado e do planejamento estratégico. A abordagem sensata é aquela que busca o equilíbrio entre a velocidade e a qualidade, considerando todos os fatores envolvidos.

Portanto, da próxima vez que sentir a pressão para acelerar o processo, lembre-se do ditado: “Quem tem pressa come cru”. A paciência e o respeito pelo processo não apenas levam a resultados melhores, mas também a um ambiente de trabalho mais saudável e produtivo.

Interessado em trabalhar comigo?

Vamos marcar um café e conversar sobre seu projeto. Quero trabalhar com você para criar algo realmente incrível!