3 pontos por GN⁺ 2023-12-09 | 1 comentários | Compartilhar no WhatsApp
  • Muitos projetos adiam as medidas de QA e acabam dependendo de um grande sprint de QA pouco antes do release, repetindo o mesmo caos no ciclo seguinte
  • A formação em ciência da computação costuma dedicar tempo a algoritmos e linguagens, e até à gestão de projetos, mas muitas vezes não trata a garantia de qualidade de software em nível prático
  • Nas empresas, quando surgem falta de orçamento, atrasos no desenvolvimento ou aumento de escopo, o QA é o primeiro a ser reduzido, e acaba sendo entregue um software frágil que passou apenas por testes mínimos e não estruturados
  • Para defender QA, é melhor falar do custo de não fazer isso em termos de aumento no custo de desenvolvimento ou de mais tempo de estabilização antes do release, em vez de usar expressões abstratas como “mais estável”
  • Em vez de montar todo o sistema de qualidade de uma vez, é mais realista proteger primeiro as funcionalidades centrais ligadas diretamente ao valor para o cliente e escrever testes junto com a implementação de novas funções

QA empurrado para pouco antes do release

  • Em muitos projetos, o desenvolvimento avança sem medidas importantes de garantia de qualidade
  • Mesmo quando a necessidade é conhecida, a execução real muitas vezes fica concentrada em um grande sprint de QA perto do release
  • Essa abordagem aumenta o estresse e só consegue fazer o software funcionar no limite do aceitável
  • O mesmo caos se repete no próximo ciclo de release, dificultando qualquer melhoria estrutural

A lacuna de qualidade entre formação e prática

  • Os cursos de ciência da computação se concentram principalmente em algoritmos, no funcionamento do computador e na história e nos conceitos das linguagens
  • Pode até haver um semestre sobre gestão de projetos ou Scrum, mas em alguns casos o QA fica totalmente de fora
  • Como mais de 90% dos formados vão trabalhar em contexto corporativo, é necessário saber entregar software sem bugs dentro do tempo definido
  • Tratar QA de forma negligente na formação não condiz com as exigências do trabalho real

Por que o QA é o primeiro a ser cortado nas empresas

  • Quando surgem problemas de orçamento em um projeto, os padrões e medidas de QA costumam ser os primeiros a ser excluídos
  • Como o QA muitas vezes fica para o fim do projeto, se o desenvolvimento se prolonga ou o escopo aumenta, falta tempo para garantir a qualidade
  • Como resultado, a equipe faz apenas testes mínimos e não estruturados e depois entrega um software com estrutura frágil
  • Algumas equipes têm padrões de QA, mas normalmente eles são impostos pelos membros mais seniores ao restante do time
  • Mesmo com padrões, se a equipe escreve testes só para cumprir métricas de gestão do projeto, é difícil chegar a uma garantia de qualidade suficiente

O primeiro passo para quebrar o ciclo de problemas de qualidade

  • Apontar a ausência de medidas de QA exige experiência e confiança
  • Crunch antes do release, sistemas em produção falhando e monitoramento ausente viram um peso para toda a equipe
  • Assim como refatoração, melhorias que não ficam visíveis diretamente para a gestão são difíceis de defender, e o QA pode parecer ainda mais intimidador para quem nunca fez isso direito
  • É preciso levantar o problema repetidamente e retomar a discussão para criar um primeiro passo

Explicar QA na linguagem do dinheiro

  • Dizer que “o software ficará mais estável” ou “será mais fácil de manter” pode soar abstrato demais para quem não trabalha no codebase
  • O desenvolvedor precisa falar sobre o custo de não fazer QA
  • Exemplos de formulação:
    • Se não fizermos isso agora, em 4 meses o esforço e o custo de desenvolvimento vão aumentar 15%
    • Se não colocarmos testes unitários em todas as funcionalidades, a etapa de estabilização do release ficará mais longa toda vez
    • À medida que novas funcionalidades forem sendo adicionadas, será necessário testar manualmente os efeitos colaterais toda vez, reduzindo o progresso a cada release
  • Esse formato é uma linguagem mais fácil de transmitir para o negócio e para a gestão
  • No fim, medidas de QA podem melhorar a vida tanto de desenvolvedores quanto de gestores

Começar com a dose mínima eficaz

  • Se o QA for planejado como um grande investimento inicial, isso pode travar o andamento do projeto e dificultar o acordo das partes interessadas
  • Um ponto de partida realista é encontrar a parte mais importante da aplicação
  • Normalmente existe um caso de uso, uma funcionalidade ou um comportamento central do qual toda a aplicação depende
  • É melhor testar primeiro as funcionalidades centrais que precisam necessariamente funcionar corretamente para entregar valor ao cliente
  • A dose mínima eficaz (MED) significa a menor dose capaz de produzir o resultado desejado
  • Em QA, a MED pode ser uma destas opções:
    • plano de testes manuais
    • testes automatizados no pipeline
    • outras medidas que garantam o comportamento central
  • Depois de garantir as funcionalidades centrais, é possível ampliar a estabilidade gradualmente
  • Também é importante adicionar testes unitários a cada nova funcionalidade e validar informações fora do seu controle, como APIs externas ou entrada do usuário
  • QA também deve ser melhorado de forma iterativa e gradual

Perguntas de QA a fazer em um novo projeto

  • Ao iniciar ou entrar em um novo projeto, é preciso verificar se existe pelo menos alguma noção de QA
  • A equipe deve pensar nas seguintes perguntas:
    • O que estamos entregando?
    • O que precisa funcionar obrigatoriamente?
    • Como vamos garantir isso?
    • Quais medidas decidimos intencionalmente não adotar, e por quê?
  • Registrar isso em documento e somar um plano de testes cria uma boa base para o software evoluir
  • Também é recomendável revisar a abordagem escolhida periodicamente, por exemplo a cada trimestre

Escrever testes junto com a implementação

  • Mesmo sem usar TDD, recomenda-se escrever os testes enquanto o software está sendo desenvolvido
  • O momento de implementar uma funcionalidade é um bom momento para escrever testes
  • Escrever testes ao mesmo tempo força o código a ter uma estrutura realmente testável
  • Quando os testes são adicionados depois a um software já existente, muitas vezes fica evidente que o código está excessivamente acoplado ou viola o princípio da responsabilidade única
  • Os testes servem como explicação de que o comportamento desejado foi compreendido e validado, e também funcionam como uma forma de documentação do código

Efeitos positivos para o projeto e para a carreira

  • Ao levantar a discussão sobre qualidade e propor soluções possíveis, você mostra às pessoas ao redor que se importa com o projeto
  • Discutir qualidade pode ampliar sua esfera de influência como desenvolvedor
  • A qualidade de vida de desenvolvedores e gestores também pode melhorar
  • O projeto pode crescer em um ritmo saudável quando existem medidas de QA
  • Nem todo mundo precisa virar embaixador de QA, mas é possível começar com um pequeno MED e mostrar formas melhores de trabalhar dentro da equipe

1 comentários

 
GN⁺ 2023-12-09
Opiniões do Hacker News
  • Esse tipo de conteúdo é ensinado. Só que não fica nas disciplinas centrais de ciência da computação, e sim em eletivas como engenharia de software
    A CMU tem até programas de mestrado e doutorado em engenharia de software, que cobrem o que o post do blog menciona e mais. Há uma grande desconexão entre CS e SE, mas não chega ao ponto de “ninguém ensina como fazer software de qualidade”

    • Aprendi isso em um curso de graduação em CS na Suécia, e acho que o fato de eu ter me tornado praticamente tech lead em menos de um ano no meu primeiro emprego não foi por alguma grandeza inata, mas porque estudei engenharia de software
      Ironicamente, quando era estudante, engenharia de software era a disciplina de que eu menos gostava. As aulas de padrões de projeto que seguiam UML rigidamente pareciam antiquadas, e as aulas de QA em que aprendíamos TDD e ferramentas do ecossistema Java também eram tediosas. Anos depois, quando entrei em uma equipe que criava workflows e ferramentas de teste para software com altos requisitos de segurança, meus colegas ficaram surpresos porque eu já sabia o que precisava ser feito
    • Há uma grande diferença entre dizer que a CMU ensina e dizer que a maioria das universidades ensina
      Mesmo quando ensinam, geralmente é algo antiquado ou muito literal, como escrever aplicações web. Se houvesse uma disciplina focada em implementação, trabalho em equipe e construção de sistemas complexos, eu realmente teria querido cursá-la
    • 90% dos formados em CS acabam trabalhando não como cientistas da computação, mas como engenheiros de software
      Esse conteúdo não deveria ficar como eletiva ou em um programa de mestrado; é preciso haver um programa de graduação em engenharia de software, e 90% dos estudantes de CS deveriam migrar para ele
    • Um amigo tentou durante anos criar uma disciplina de engenharia de software no departamento onde trabalhava como instrutor. O plano básico era receber a passagem de conhecimento e a base de código do semestre anterior, implementar novos recursos, fazer deploy e operar o serviço, e então escrever a passagem de conhecimento para o semestre seguinte
      A base de código era um serviço simples que oferecia varredura de vírus/malware, e foi projetada para sempre gerar trabalho adicional, incluindo scanners e assinaturas. Era uma ideia de mais de 15 anos atrás, mas poderia ter virado uma excelente disciplina contínua; é uma pena que ele não tenha conseguido convencer o departamento
    • Se meus amigos não tivessem me contado experiências tão vividamente ruins com a disciplina de compiladores, eu não teria cursado a outra opção que preenchia aquela categoria, computação distribuída
      Talvez não tenha sido exatamente a disciplina que definiu minha graduação, mas chegou bem perto, e o fato de a maioria das pessoas que projetam sistemas não conhecer esse conteúdo me causa ao mesmo tempo raiva e pavor existencial
  • É mais fácil trabalhar com pessoas que têm diploma em CS porque há menos necessidade de convencê-las da importância de bons algoritmos ou de que não se deve implementar parsers e criptografia por conta própria
    Já no lado da engenharia de software, não há uma credencial confiável que indique que a ingenuidade sobre qualidade, trabalho em equipe e colaboração com outros times tenha sido igualmente polida. Surgem pessoas treinadas pela experiência de escrever rapidamente código horrível e não verificado e sair antes de os problemas explodirem; a gerência gosta delas e despreza quem fica para limpar os destroços

    • Perspectiva interessante. Concluí cerca de 95% de um mestrado em CS antes de sair para montar uma startup e, embora eu reconheça o valor de geradores de parser, há muitos casos em que uma implementação manual simples de parser é adequada, útil e mais rápida
      Protocolos baseados em strings com delimitadores claros geralmente podem ser analisados com muita facilidade, e dependendo do caso de uso basta tratar apenas uma parte deles. Claro, testes e requisitos funcionais precisam ser considerados. Se o caso for criar uma linguagem, o conselho pode ser diferente
    • Criptografia, sim, mas fico em dúvida se isso vale mesmo para parsers. Parece haver uma espécie de curva em U aqui
      Iniciantes fazem por conta própria; desenvolvedores intermediários e projetos de médio porte usam geradores de parser; e as pessoas que mantêm os parsers mais sofisticados também preferem escrevê-los manualmente. O GCC também usava um parser bison antigamente, mas mudou para um parser recursivo descendente escrito à mão para obter mensagens de erro melhores, e o Clang também usa recursão descendente
    • Tenho uma objeção quanto a parsers. Como é muito difícil fornecer mensagens de erro diagnósticas úteis com yacc/bison, a maioria das linguagens acaba usando um parser recursivo descendente escrito à mão
      A única exceção que conheço pessoalmente é o jq, e por isso é difícil produzir mensagens úteis de erro de sintaxe na implementação do jq
    • Criptografia e parsers não deveriam estar na mesma frase. Não há momento apropriado para escrever sua própria criptografia, mas uma parcela considerável de grandes projetos de compiladores e interpretadores usa parsers escritos à mão, e muitos também escrevem o lexer manualmente
      Escrever um parser pode ser simples o bastante para caber em um único exercício, e o código de um parser escrito à mão acaba se parecendo com uma gramática LL. Parsing é a parte mais fácil de escrever compiladores ou ferramentas de linguagem; então, se um parser escrito à mão é um padrão alto demais para a equipe, o projeto inteiro pode ser suspeito. Não estou dizendo para nunca usar geradores de parser, mas eu preferiria trabalhar em um projeto com um parser escrito à mão e bem testado a um projeto que complica o build com ferramentas adicionais ou usa ferramentas antigas como Bison e ANTLR
    • É uma questão de cultura. É melhor evitar organizações de desenvolvimento estilo cowboy
      Ainda assim, os padrões gerais parecem ter subido em relação a 20 anos atrás. Por exemplo, controle de código-fonte, testes unitários e CI/CD não são mais controversos
  • A premissa de que “é preciso entregar software sem bugs no prazo” é um ponto de partida bastante ruim para começar um texto sobre software de qualidade.
    Se você acredita que consegue implantar código sem bugs, está na hora de mudar de profissão.

    • Se você já escreveu software em nível de operação em uma empresa real, precisa aceitar que, no momento em que cria um novo commit, até uma mudança de 1 linha pode quebrar alguma coisa.
      Mesmo fazendo testes unitários, testes de integração e testes de aceitação pelo usuário, uma única alteração de código significa a possibilidade de um novo bug. Quando um desenvolvedor diz “eu nunca implanto código com bugs”, dá vontade de investigar melhor o que ele quer dizer.
    • Infelizmente, isso é verdade. Entregar no prazo e não ter bugs são coisas inversamente proporcionais e, num mundo em que é difícil pedir ao PM tempo para testes melhores ou para pagar dívida técnica, essa é simplesmente a realidade.
    • Esse tipo de sabedoria parece vir da experiência ou de uma forma de pensar em um nível mais alto. Como o texto diz, a maioria dos testes/TDD/QA é acrescentada depois ou empurrada para uma “sprint de QA” no final.
      Quando você passa de “escrevi a função”, “testei a função” e “testei até a função chamada pela rede”, percebe que, por melhor que seja a cobertura de casos de borda e por mais rigoroso que seja o QA, sempre resta algum comportamento indefinido 0-day em uma configuração específica, um hardware específico ou um kernel específico. O máximo que se pode dizer é que, como passou por testes, olhos humanos e revisão, há uma garantia de que quase não há bugs; no fim, só resta cruzar os dedos.
    • É uma visão bem ácida sobre engenharia. Fica a dúvida de por que aceitamos em software coisas que não seriam aceitas em outras áreas da engenharia.
    • Se o custo de corrigir um bug for maior do que o custo que ele causa à experiência do usuário ou às tarefas a fazer, é totalmente aceitável que o bug escape para produção.
      Se um bug leva uma semana para corrigir, mas só é encontrado por poucos usuários em uma situação muito rara, talvez nem valha a pena corrigi-lo.
  • Existem cursos de ciência da computação, e também universidades que enfatizam estágios e prática. Mas muitos departamentos de CS nas universidades vieram da matemática e são centrados em teoria.
    Acho isso aceitável, assim como química não é engenharia química. A universidade não é simplesmente uma escola profissionalizante; a ideia de quase todo diploma é treinar a capacidade de pensar e demonstrar habilidade para aprender conteúdos complexos.

    • A sociedade precisa de uma mistura de escolas profissionalizantes e universidades tradicionais. Se a universidade não oferece os dois, ela falha com todo mundo.
      Uma educação universitária puramente acadêmica, sem considerar se tem utilidade no mundo real, é prejudicial à educação; mas uma formação puramente profissional, que ensina apenas o método sem compreensão, também não é útil. Ainda assim, as escolas profissionalizantes reais também não são totalmente assim: mesmo que pulem as partes difíceis, costumam oferecer uma compreensão profunda das coisas importantes.
    • Mesmo nesses estágios, você não aprende a criar software de boa qualidade; aprende a entregar uma SPA conectada a uma API em 15 semanas. Se não conseguir, não é contratado.
      Ainda assim, é uma boa forma de ter um vislumbre do mundo profissional de software.
  • Isso se aprende em boas organizações de desenvolvimento. Há 10 ou 15 anos, grosso modo, eram as FAANG; hoje, um exemplo seria a TailScale.
    É possível não cair em microservices inúteis, camadas e mais camadas de Docker, camadas de serialização/desserialização JSON e um monte de testes unitários só para cobertura, enquanto se ignora QuickCheck, Hypothesis e fuzzing. Também é possível adotar conjuntos de mudanças empilhadas, rotação de on-call da equipe que escreveu o código, minimizar ligação dinâmica e erros de dependência não obrigatória, projetar de acordo com runtimes de linguagens gerenciadas e exigir como “legibilidade” a sintaxe verbal legível da linguagem. Embora isso seja repetidamente ignorado, saber como entregar software de qualidade é conhecimento público.

    • Não sei o que “grosso modo, FAANG” quer dizer, e também fico em dúvida se “hoje é TailScale” se refere à VPN.
      Pode até haver ideias sobre software de qualidade, mas este comentário é difícil de entender.
    • O problema dominante parece ser que software de boa qualidade frequentemente não vence software péssimo em termos de receita.
    • Gostaria de conselhos sobre como encontrar essas boas organizações e esse conhecimento sobre qualidade.
      Também queria saber o que observar e se há livros ou cursos recomendáveis.
  • É difícil chegar a métricas válidas o bastante para sustentar uma afirmação do tipo “se não fizermos isso agora, o esforço e o custo de desenvolvimento aumentarão 15% daqui a 4 meses”.
    Em uma startup, dois fundadores uma vez disseram “não escreva testes unitários”. Eu não discuti; entendi que o verdadeiro significado daquilo era que eu estava lento demais e deveria entregar o mais rápido possível. Entreguei rápido, mantive a qualidade e escrevi testes unitários também. Eles não precisavam saber; só precisavam do resultado. O ponto oculto dessas discussões é que a maioria das organizações de software não sabe entregar com rapidez e qualidade ao mesmo tempo. Não existe fórmula mágica; é preciso artesanato individual, e também é um esporte de equipe. A situação varia de lugar para lugar, então alguns processos leves podem funcionar em parte, mas o efeito é limitado. No fim, é preciso uma boa equipe com experiência, valores corretos e sabedoria para focar na entrega de valor.

  • A premissa de que a universidade ensina como fazer software na indústria é uma afirmação bastante ousada.
    Além disso, este texto parece algo dos anos 90, quando se distribuía software em CD ou disquete. Hoje, pipelines de implantação contínua muitas vezes tornam o conceito de “release” nebuloso, e isso é considerado uma boa prática. Nesse contexto, a ideia de que um departamento de QA garante manualmente que um release não tem bugs parece bastante ultrapassada.

    • Nem todo mundo escreve um web app que pode ser atualizado a qualquer momento quando o CI passa, ou um app de celular que pode ser atualizado toda semana.
      Também há pessoas que escrevem código embarcado em dispositivos nos quais fazer upgrade não é simples.
    • Isso lembra casos como a Boeing. Como a história de que o 737 Max foi testado por uma terceirizada barata na Índia, há uma quantidade enorme de software que não tem implantação contínua.
  • Se você precisa da aprovação de alguém, precisa explicar a essa pessoa por que a ideia é boa.
    Dizer que “é mais estável” ou que “fica mais fácil de manter” não ressoa com quem não trabalha diretamente na codebase. Desenvolvedores precisam falar sobre o custo de não fazer QA, ou seja, na linguagem do dinheiro. Mesmo que “mas este é o jeito certo!” pareça um argumento irrefutável, a pessoa que aprova pode não se importar com essa correção. Esse princípio se aplica não só a consertar software do jeito certo, mas a quase tudo no ambiente de trabalho.

    • Acho que a única forma de escapar dessa situação infernal é trabalhar em um lugar cuja liderança já seja madura o suficiente para entender essas coisas.
      Se você precisa explicar por que qualidade é importante, eles estão no mínimo tão ignorantes quanto você, talvez até mais. Uma organização assim deve aceitar seu próprio destino. Em empresas maduras, por outro lado, você é recompensado mais rápido e melhor, e também desenvolve mais rapidamente uma noção de como o negócio deve funcionar. Claro, você precisa provar por conta própria que o tempo investido leva a melhorias reais, e isso não pode ser um impulso quixotesco de amador.
  • É possível ter, em linhas gerais, apenas três entre qualidade, prazo curto, baixa complexidade de comunicação e pouco dinheiro; e, nesse conjunto, o tempo está mais para variável dependente
    As pessoas tentam aplicar processos e estruturas de fábrica ao software, que é ao mesmo tempo um esporte coletivo e uma área da engenharia. Assim como não se ensina nem se monta um time de basquete dividindo o ataque em procedimentos por etapa e checklists, é preciso minimizar a comunicação e fazer o time se mover como um só. Isso não é construir um processo, é formar equipes e indivíduos. Faça planos, mas, como disse Moltke, nenhum plano de operações sobrevive com certeza ao primeiro contato com o inimigo. Só que a mentalidade de negócios acredita que, se o plano não saiu como previsto, é preciso acrescentar mais processos, e isso permite que o gerente culpe indivíduos no próximo fracasso. Processos têm seu lugar para garantir que as coisas aconteçam dentro de uma estrutura legal e moral, e para reduzir condições adversas, como apostar por engano todo o dinheiro de um fundo hedge durante testes. Mas, na maioria das startups e empresas, eles são usados de uma forma que não coloca a equipe no centro

    • A analogia com construção é ruim. Quem constrói é o compilador; a equipe de desenvolvimento faz projeto iterativo pressupondo feedback e ajustes frequentes
      Não se costuma gritar com um arquiteto tradicional perguntando quando vai terminar. Em geral, termina quando o cliente fica satisfeito ou toma uma decisão. Muito desenvolvimento é parecido com isso
  • Questiono se existe alguma atividade humana que consiga ensinar com sucesso o atributo chamado qualidade
    Pela minha experiência, a capacidade de produzir algo de qualidade só é adquirida com prática, prática e prática

    • Pode-se dizer que toda prática industrial é assim
      Em contrapartida, o título apenas quer dizer que programação não é uma prática industrial. Para quem prestou atenção, isso deveria ser óbvio, mas alguns se recusam a enxergar até o fim
    • Uma boa educação consiste, em grande parte, em criar situações em que o aprendiz consiga praticar de forma eficaz
      Basta olhar para a escrita: muita gente aprende a melhorar a qualidade. Isso acontece orientando sobre o que escrever e, mais importante, sobre como refletir a respeito da qualidade do texto que acabou de escrever e melhorá-lo
    • Arte também se encaixa nisso. Quanto mais profunda a formação, mais ela passa a se concentrar em pequenas diferenças e na qualidade
      A prática sempre ajuda, mas qualidade também é algo que muita gente aprende e desenvolve
    • Por problemas de saúde, não posso mais voar profissionalmente, mas sinto que na aviação se aprende esse tipo de coisa, enquanto no setor de tecnologia isso faz falta
      Ao aprender a voar, você aprende os padrões, mas, com o tempo, aprende a estreitar as tolerâncias. Por exemplo, se em uma curva acentuada o critério de altitude é ±100 pés, isso é o mínimo; você mira 50 pés, 20 pés e, depois, algo em que o ponteiro praticamente não se mova. O objetivo é “melhor, sempre melhor; o que posso fazer melhor?”, e, no voo, você só passa se satisfizer todos os itens, não pela média geral. Culturalmente, “satisfatório” não é o fim, é o ponto de partida
      Sinto que essa atitude cria um modelo muito mais colaborativo. Na aviação, todos querem sinceramente que todos tenham sucesso e, se alguém falha, você também tem parte da responsabilidade. Havia uma cultura em que, se você cometia um erro, precisava encontrar maneiras de reduzir a possibilidade de erros futuros; nas companhias aéreas, a Garantia da Qualidade das Operações de Voo (FOQA) também tem um papel grande. Em pequenas operações remotas, isso era mais informal, mas na maioria das vezes se aproximava de uma cultura “sem culpa”; o ponto central era “como podemos melhorar?”
      Qualidade, tomada de decisão e “fazer a coisa certa” eram centrais na cultura da aviação. Em uma operação respeitável, se alguém julgava que o tempo estava ruim demais para operar com segurança, isso levava ao cancelamento da operação, e ninguém decolava à força só para concluir o trabalho. O setor de tecnologia, no qual entrei depois, parece o oposto. O próprio conceito de produto mínimo viável revela o problema. Não deveria ser “mínimo viável”, e sim “produto de qualidade mínima aceitável como ponto de partida”. O mínimo não deve ser o alvo; o mínimo é apenas o ponto de partida
    • A prática só faz sentido quando se tenta produzir qualidade
      Se você só pratica produzir lixo, apenas ficará bom em produzir lixo. Existem, de fato, pessoas que não se importam com qualidade; nesses casos, todo o pressuposto desmorona