Aberto a contribuições

Desde que me envolvi com o Software Livre e o mundo Open Source, acabei adotando essa filosofia e aplicando seus princípios em muitos aspectos da minha vida, e este site é só uma dessas consequências.

Software Livre - Cloud

Apesar deste site servir para manter o conhecimento que adquiro aberto e acessível para a comunidade, eu nunca tinha bolado uma boa forma de tornar o site 100% livre, isto é, aberto para outras pessoas e disponibilizado seu conteúdo sem restrições. Se você não tiver paciência para ler e quiser logo saber como contribuir, clique aqui.

Aberto a contribuições é um artigo original de Mind Bending

Refatoração de código

Não precisa acompanhar o "mundo dos testes" para saber o que significa refatorar. Aliás, quem nunca ouviu algum co-worker ou você mesmo tenha feito uma refatoração de um código.

Primeiro, vamos deixar bem claro o que é refatoração. Vamos lá. Você tem até o próximo paragrafo para pensar na sua definição de refatoração de código.

Pronto? Aqui vamos nós!

Refactoring Cat

A milagrosa refatoração de código

Primeiramente é importante explanar de que há dois tipos de refatoração: a) refatoração, terceira etapa do Test-Driven Development (Red, Green, Refactor); b) refatoração de um código de produção já existente. Neste momento vou tratar apenas do item b).

A necessidade de uma refatoração dá-se inicialmente por uma decisão de um (ou mais) programadores sob um determinado trecho de código, por concluir de que aquilo não está construído de uma maneira aceitável. Disto, o cabra deve lembrar de que refatorar quer dizer: não mudar o comportamento da parte a ser refatorada. Apesar de óbvio, essa primeira premissa é a mais violada ao refatorar algo, pois junto da refatoração o programador resolve fazer umas coisinhas a mais (inserir novas features, por exemplo).

Não precisa ir muito longe para provar de que isso não funciona bem, não é mesmo? Ao refatorar você pode quebrar coisas. E, para evitar que essa quebra não vá parar em produção (ou parar o env de produção), você precisa de respostas rápidas a quaisquer mudanças que faça no código, por menores que sejam. (Test-First aqui, alguém?).

Item número dois: evite com todas as forças ficar criando tarefas de refatoração no projeto. A refatoração deve vir com um propósito. Prever o futuro não é um propósito. Não há necessidade de refatorar algo que está em produção há tempos só pelo prazer de refatorar um trecho de código. (você pode fazer isso em casa, para estudar, claro!) Pois você já deveria ter feito isto no terceiro passo do TDD: (Red, Green, Refactor). Se não o fez, espere até que venha precisar trabalhar com aquele código novamente para implementar uma nova feature, daí, divida essa feature em duas etapas: refatorar o código envolvido na nova tarefa e fazer a nova tarefa. Lembre-se: dois passos. Refatorar e somente depois, implementar.

O (semi)deus da refatoração

Lembra que falei que a palavra refatoração você já devia ter ouvido em algum ambiente antes? Sempre ao pegar um código é um costume a gente não entender o que aquilo faz (e por que faz). Por não entender, a gente vai e diz: ah, isso aqui precisa de uma refatoração. Será mesmo?

Esse tipo de atitude pode colocar em xeque os benefícios da refatoração e pior: quebrar algo em produção desnecessariamente, pura e simplesmente porque você sendo novo naquele projeto/equipe não entendeu o código - o que é normal em todo início. Com isso, você faz feio com a equipe e pode destruir todo um processo de amostragem e explicação sobre benefícios de uma refatoração planejada.

É importante que você vá com calma e espere até ter uma certeza mais clara das coisas.

Refatoração nem sempre é a melhor saída

Outro ponto a favor de evitar sair refatorando sem saber quem nem porquê é ter o controle analítico de analisar o cenário em questão e verificar se a refatoração de código solucionaria o problema. Já vi casos em que o código em si não estava ruim, estava aceitável, o verdadeiro problema era um design mal pensando e neste caso, a refatoração não ajudaria em nada. Você precisaria ir além nas decisões.

É preferível manter um código espaguete por mais um tempo do que perder a (única) chance de mostrar os benefícios. No podcast de número 157 do Ruby Rogues, Rebecca Wirfs-Brock afirmou outro ponto importante:

You’re sort of arguing that refactoring is not necessarily always the best way to clean up a design. Sometimes, you might want to start over.

Às vezes realmente vale mais a pena fazer um git reset ou um git stash (como disse o Avdi Grimm brincando com ela) mental e partir a fazer uma outra solução do zero. Já tive que fazer isto inúmeras vezes ao longo do tempo. Um grande aliado nesse processo são os Testes de Unidade com Test-First, pois eles dão uma resposta muito rápida sobre seu progresso (ou estagnada) de raciocínio.

Hoje a conclusão, dar-se-á em forma de resumão!

Resumão:

  1. Respostas rápidas ao refatorar. Teste de unidade é a única forma de conseguir isto rapida e isoladamente.
  2. Refatorar. Depois de pronto, volte para implementar o que ia fazer no começo. Não faça os dois juntos por mais que Goku desça da núvem para te pedir isto.
  3. Refatorar ao entrar num projeto: it's a trap!
  4. Às vezes é melhor um git reset mental e partir para outra solução.
  5. Estar apoiado em teste de unidade e test-first trará a confiança necessária para tomar a decisão de refatorar.
  6. Esforce-se para não tornar a refatoração uma task do seu projeto. Ela deve ser junto de uma task de implementação. Refatorar precisa de propósito.
  7. Red, Green, Refactor (TDD) != Refatorar código de produção.

O Teste mudo

Já defendi aqui nos posts o Test-First inúmeras vezes. Hoje, vou na linha oposta: quando o teste torna-se totalmente dispensável.

Vácuo

Imagine você entrando numa equipe para auxiliar a resolver uma lista de bugs existentes. Você faz algumas perguntas e obtém como respostas:

  1. Os bugs em questão existem há tempos. Foram "consertados", porém "reapareceram";
  2. O projeto tem seus 145 testes que rodam em 3 minutos;
  3. Nenhum teste falha.

Primeira ação sua é obviamente dar uma olhada no /specs do projeto, pois as condições que ocasionam os bugs podem não estarem cobertas nos testes. Simples, você pensa. Só criar teste cases e pronto.

Criando o caso de falha

Seguindo o princípio da engenharia reversa, você deveria criar o teste que simula o bug. Ao abrir o código de teste, porém, você encontra um setup de 25 linhas, criando o chamado Persistent Fixtures do xUnit Patterns.

Todos os testes são de integração. Pelo menos, como diz o DHH, o teste de integração garante que seu código funciona.

Será ?

Você segue adiante. Vê duplicação de código de teste. Mas isso obviamente não importa, pois ele precisa apenas verificar que o código funciona. Você olha pelo código, procurando o melhor "lugar" para encaixar teus novos casos de teste até que se depara com nada menos do que o teste que está verificando aquela funcionabilidade esperada. E ele é Green.

O teste mudo

Ele não diz nada. Ele testa uma action da Controller e de brinde, passa pela funcionabilidade quebrada. Por ser um integration-all-in-one-full-stack teste, você não tem muito o que mudar, pois é basicamente um Input numa URL e a análise de um retorno. Neste cenário, você não tem o que mudar, pois o código de integração não garante que aquele bug apareça e seu teste finalmente falhe. Sua opção é tentar criar um Teste de Unidade.

One size fits all

Você percebe que o código de domínio totalmente ligado ao framework que você utiliza. Percebe que não poderá fazer um teste de unidade sem carregar junto nada menos do que 8 dependências. Mockar 8 coisas ? This is madness!

Como o framework é arquitetural, você está refém das convenções fornecidas por ele. Neste caso, você não tem muito o que fazer a não ser lamentar.

Fallback em debugging

Você desiste dos testes e decide que precisa resolver. Solução ? Partir para ferramentas de debugging. Com debug, você precisa entender variáveis e intra-código totalmente desnecessário para aquela tarefa porém, obrigatória no debugging uma vez que você precisa entender o fluxo (stack) da aplicação.

Depois de algumas boas horas, você percebe que o bug era na verdade uma infestação, pois havia mais de um lugar totalmente diferente que exercitava o código e criava o bug. Em miúdos: três telas utilizando duas regras totalmente diferentes para chegar a mesma solução. Lembre-se: Test-Driven development é desnecessário.

Concluindo

Você resolve o bug após várias horas. Faz teste manual e verifica que tudo está perfeito, inclusive seus testes continuam green, mostrando que aquela suite é totalmente dispensável e que teste sem propósito deveriar estar morto.

Essa pode ser uma história totalmente folclórica ou não.

MariaDB 10.0 entra no [extra]

Leandro Inácio escreveu:

Uma nova major release do MariaDB será movida para o [extra] em breve. A mudança no esquema de versionamento foi feita para distinguir claramente as funcionalidades fornecidas a partir do MySQL 5.6. A partir de agora, não será possível mudar facilmente entre as várias versões da implementação do MySQL fornecida no repositório oficial.

Devido a grande mudança no MariaDB 10.0, é recomendado (embora, não necessário) fazer um dump das tabelas antes de atualizar e depois recarregar o arquivo do dump. Após a atualização para nova versão não esqueça de reiniciar o mysqld.service e executar mysql_upgrade para checar os possíveis erros do banco de dados.

Adicionalmente a engine de armazenamento TokuDB foi desabilitada por repetidas falhas no empacotamento. Sinto muito por qualquer inconveniente causado.

Para informações mais detalhadas nas mudanças e no procedimento de atualização, por favor veja a base de conhecimento do MariaDB e o manual do MySQL.

URL da notícia: https://www.archlinux.org/news/mariadb-100-enters-extra/

Argumentos e Parâmetros em C

Os parâmetros e argumentos são aquelas opções que usamos quando executamos um programa na linha de comando, como df -h ou ls -la --color. Tratar esses parâmetros e argumentos faz com que nossos programas estejam em compliance com o sistema operacional.

C Language

A implementação dos parâmetros e argumentos da linha de comando é um assunto complexo e requer dedicação. Abaixo explico de maneira prática como implementá-los através de funções GNU. No entanto, vou explicar também um pouco desse padrão da linha de comando, dos parâmetros e dos argumentos, pois é imprescindível saber como eles funcionam para uma correta implementação.

Argumentos e Parâmetros em C é um artigo original de Mind Bending

SMPlayer!

O SMPlayer é um dos melhores players de vídeo que já utilizei!

Esse pequeno post tem como objetivo mostrar como fazer a instalação do SM de forma completa aqui no Arch, acredito que o mesmo deve estar disponível não só no Arch mas na grande maioria das distribuições tem até pra Windows!

Vamos fazer a instalação no Arch, logo:

# pacman -S smplayer smplayer-themes smplayer-skins

Uma característica/configuração muito legal do SM é que “se começar a ver um filme e tiver que parar… não se preocupe, pois quando o abrir novamente ele continuará do ponto onde o deixou e com as mesmas definições: áudio, faixa, legendas, volume…” e isso é excelente!

Então instale, teste e divirta-se!

Excelente player multimídia!

Excelente player multimídia!

 


Test-Driven Development é desnecessário!

Há alguns dias atrás ouvi a seguinte afirmativa:

Acredito que testes de unidade são importantes; Não vejo necessidade porém, em fazer TDD.

Será?

Unclebob NO TEST, NO BEER!

Separando as coisas: Teste de Unidade

Teste de unidade, como comentei anteriormente, tem como objetivo garantir que uma parte da regra de negócio funcione como foi solicitada/descrita pelo interessado pelo software. O teste deve abranger apenas um cenário, seja ele feliz (do caminho feliz); ou falho. Todo e qualquer input que se faça necessário deverá ser introduzido com o auxílio de Mocks ou/e Stubs, fazendo assim com que o teste seja o mais independente possível do restante das classes que colaboram/interagem com aquele trecho na vida real (código de produção).

Uma maneira de verificar se seu código de teste está bem escrito é atentar-se para a anatomia do teste de unidade: deverá ter um trecho para input dos dados necessário ao teste; execução do código que está sob teste; e por fim, analisar os resultados obtidos.

Fazer o teste depois do código de produção poderá no início trazer confiabilidade do que se está fazendo. Ao crescer a aplicação porém, é provável que você perca o controle da suite e o resultado é preocupante: um bolo de testes acoplados e sem garantias sob o código de produção. Nessa hora você cairá um beco sem saída e culpará injustamente "essa falácia de testar software".

Podemos afirmar também que fazer teste de unidade para mostrar para o chefe não é uma boa ideia, pois o parabéns que você obterá com ele hoje, poderá se transformar no maior vilão, quando você perder o controle estrutural do seu código.

Separando as coisas: Test-Driven Development

Tem seu cerne em: Red, Green, Refactor. Em miúdos:

  1. Escreva o teste que irá exercitar uma parte isolada do seu código (leia acima sobre isso).
  2. Escreva o código (de produção) que irá fazer o teste ficar verde (passar).
  3. Verifique se seu código de produção (e o de teste) podem ter melhora, tanto na escrita quando na qualidade e best practices da linguagem.

Repita esse processo até começar a colher os resultados do TDD. Depois que estiver mais acostumado (coisa de algumas semanas), você poderá se adaptar melhor. Lembre-se: Baby Steps são importantes nesta fase: faça uma coisa de cada vez. Não escreva 20 linhas de código sem ir verificando com seu teste o que está acontecendo. Não tenha pressa. Você está aprendendo uma nova forma de ver o mundo.

Without TDD you will lose control

Outro dia, mexendo num código da galera aqui, encontrei um método que possuia 37 variáveis temporárias; 7 loops; 11 ifs/else; 5 comentários de uma linha.

É nítido que o programador não sabia mais onde colocar as coisas. Ele perdeu o controle do código de uma forma tão intensa, que ele precisou fazer 3 loops com a mesma Collection, para fazer coisas diferentes com ela.

Nem é preciso entrar no detalhe de Single Responsibility Principle; Dont Repeat Yourself. Ele não sabia aonde colocar cada coisa. Ponto.

É nisso que o TDD auxilia. Ele está ali como um guarda, pronto para levantar uma bandeira assim que você começa a se perder. Ele sinaliza através dos testes a necessidade de repensar a solução, reorganizar o código para a nova feature, para fazer o flush mental.

Test-Driven Development é sobre onde colocar seu código e não sobre Verificação e Validação.

Enquanto você não ter essa visão, continuará a sofrer com debugging, duplicação à n-ésima (duplicação da duplicação n vezes) e o renomado Bug Ioiô: bug que é resolvido e depois aparece novamente.

O ponto de encontro

Teste de Unidade + Design Orientado a Objetos: Test-Driven Development Design.

Concluindo

Não, você não é o Jiraya da programação. Pouco importa se você tem toda a ideia na sua cabeça, aposto com você de que, se ao invés de primeiro fazer o código de produção fizer o teste, aquela sua toda ideia inicial terá sido apenas um rascunho da versão que criará guiada pelos testes.

A dica final é: não seja afobado. Ao começar fazer testes de unidades, faça do modo clássico: Red, Green, Refactor.

Tem uma definição bacana sobre Test-Driven Development? Mande um tweet com a hashtag #deftdd ou me mencione. Vou retuitar todas as criativas ;)

Hack ‘n’ Cast - v0.3 Introdução ao GNU/Linux

O GNU/Linux foi a mola propulsora da Internet como a conhecemos hoje e, por isso, é uma peça de tecnologia fundamental pra qualquer profissional. Hoje vamos saber um pouco de sua história, entender porquê escrevemos GNU antes de Linux e discutir um pouco sobre a disputa épica entre Linus e Tanenbaum.

Baixe o episódio e leia o shownotes

UNIX System Signals em Python

Após publicar o texto sobre UNIX System Signals em C, percebi que pode ter dado a impressão que apenas a linguagem C possui essa integração. Com isso, escrevi este artigo para demonstrar o mesmo mecanismo demonstrado pelo Fernando Almeida.

Zen of Python

Todo o conceito de sinais, sua dinâmica de envio e uma tabela listando todos os sinais existentes está disponível aqui. Então vamos direto para o código!

UNIX System Signals em Python é um artigo original de Mind Bending

SucoLento – Ep.01 (piloto)

“SucoLento” é uma série de vídeos sobre sucos verdes.

Este  é o episódio piloto da série, estamos brincando e experimentando com a linguagem visual, e queremos saber sua opinião.

Você tem alguma sugestão ou receita para darmos continuidade ao projeto? Deixe seu comentário!