Quem critica negativamente vai escrever assim agora ?
Ou
No minimo ridiculo não ?
É bom saber que tem testes de alguma forma, agora o cara criticar de forma negativa quando o projeto não tem pega mal pra ele mesmo (na minha opinião).
Tenho andado afastado do guj por muito bom tempo e não sei se você se está referindo a outra thread, mas na real alguém criticar um projeto porque não usa TDD ? Ou você quer dizer “Criticar porque não usar Test-first” ?
Ou criticar porque “não usa teste” ? É que não é tudo a mesma coisa. Ha uma escala aqui. Teste é obrigatório, TDD é mais do que opcional. Test-First está no meio.
De onde vem este sentimento que se criticam projetos por falta de testes ?
Entendi sua filosofia, e sei que você é um bom “entendedor”, para deixar mais claro ou mais confuso vamos falar sobre arquivos de testes salvos em meio magnético de preferência utilizando um framework conhecido de mercado/comunidade.
Porque do contrário do óbvio, não existe código sem teste (experimento), no mínimo testou-se na mente na menor unidade possível. Por exemplo, alguém pede para fazer uma consulta em um banco
de dados, a consulta sql é construida e, no momento da execução em um cliente qualquer, foi efetuado um experimento ou teste, nota-se que faltam campos , melhora-se a consulta e o software
"o comando SQL" está pronto. (SQL é uma linguagem)
Não existe verdade absoluta o que existe é a verdade de cada um.
Agora respondendo a sua pergunta, não estou com sentimento de nada sobre ninguém, apenas iniciei uma discussão para ver o que os demais membros pensam a respeito de crítica negativa em projetos
que não possuem testes no formato supracitado.
E se por acaso lhe interessar, não foi algo proposital posso falar abertamente aqui o que aconteceu, sexta-feira busquei no gogole por “combo Reload Group” cai em uma thread sobre o neoframework
e comecei a filosofar se o linux que eu estava utilizando naquele momento possuia ou não testes unitários, se o JDK possuia, se a classe ArrayList possuia testes etc etc
Acredito que o resultado foi bom , nunca havia enviado email para Richard Stallman, para Patrick do slackware, ou o criador do kernel que no caso não respondeu mas tudo bem. Foi uma discussão bacana não houve baixaria.
Pergunta respondida ?
[editado]
Procure pelo mentawai ou menta beans, irá encontrar muita coisa sobre criticas negativas pelo fato do projeto naquele momento não possuir testes no formato citado anteriormente.
[/editado]
Já que você achou legal esse feedback, vou te repassar o outro email que ele me mandou, para você ver o que é atitude humilde…
Perguntei sobre os testes
Ele respondeu “Não tenho opinião sobre isso , desculpe”
Mandei outro email (no outro dia) dizendo: “Você não precisa se desculpar, você é o Dr. Richard Stallman, o mestre”
4) Ele respondeu: “Por favor não me chame de mestre, mestre significa alguém que comanda um escravo. Você merece a liberdade e liberdade significa não possuir mestre”
Sou fã do cara, não nego. Tirei screenshot desse e do outro email, tem gente que é fã de banda de pagode, de time de futebol enfim…
Dois parágrafos em particular do que você escreveu que eu gostaria de comentar.
Cobertura de 100% eu acho impossível tambem, mas o fato de estar 70% por si só não é necessariamente bom. Nesse ponto eu tenho que concordar com o saoj, se eu tenho testes apenas pela obrigação de tê-los, e ainda que eu os tenha cobrindo os pontos mais importantes da aplicação, ainda assim pode não ser bom.
Para exemplificar vamos ao segundo parágrafo, supondo que voce esteja falando de testes automatizados quando diz que criá-los é difícil e caro.
Difícil? Não sei se são, difícil sim é aprender as técnicas a tal ponto que escrevê-los seja fácil.
Caro é que é a questão: Segundo os princípios Lean, qualquer coisa que não adicione valor a um produto é desperdício. Sob este ponto de vista, testes, como um todo, são desperdício. O usuário não se importa com testes, como foi testado, ou sequer se foi testado, o que ele importa pra ele é que as funcionalidades que ele precisa estejam lá e funcionando.
Se você tem um programador que consegue, o que acho pouco provável, escrever código sem falhas já na primeira vez que codifica então você está num cenário ideal. Você pode simplesmente desenvolver o que o cliente precisa e pôr em produção, sem testes, sem perda de tempo, sem desperdício. E ainda assim o cliente estará satisfeito.
O problema é que isso beira ao impossível e antes de por algo em produção você precisa garantir que funciona para evitar o desgaste de ser avisado pelo usuário que algum ponto crucial parou de funcionar. E nesse ponto entram os testes com todos os custos que vêm com eles.
Aqui você vai precisar pesar o que é mais barato quando comparado ao resultado. Se você não tem uma equipe experiente em testes automatizados e tem um sistema que não é crítico a ponto de alguns simples testes funcionais nos caminhos principais do aplicativo serem suficientes para evitar problemas com o usuário. Ótimo, faça isso.
Mas esse também é um cenário excepcional. Embora, a grande maioria dos sistemas de médio e grande porte que eu vi, ou ouvi falar, não tenham rotinas de testes automatizados eles deveriam ter. E o fato de não os terem os torna mais caro do que se tivessem. Logo, nesses casos, testes automatizados são mais baratos.
Eu trabalho num sistema que se utiliza de diversas fórmulas de cálculo de valores, fórmulas que no geral são parecidas entre si, mas que possuem particularidades para cada cliente que as utiliza. Eu tenho que constantemente combinar as partes comuns com as particulares. Considerando que são mais de 80 clientes você pode imaginar o custo de garantir que tudo está funcionando apenas “executando o sistema”. É impossível.
Nesse caso, e em muitos outros, testes automáticos são mais baratos, inclusive do ponto de vista do programador. Se eu alterei uma linha de código eu posso rodar uma bateria de até milhares de testes em menos tempo do que eu vou levar para subir o servidor de aplicação. Lógico que cedo ou tarde eu vou subir o servidor e rodar a aplicação, mas não para cada linha que eu alterei, luxo a que posso me dar com testes automáticos.
Ainda falando em custo, mas voltando ao ponto dos “ideais” 70%. Mesmo que eu os tenha, e ainda que eles cubram as partes mais importantes da minha aplicação, mesmo assim o desperdício e o transtorno que eles me causam podem ser bem maiores do que simplesmente alterar e depois testar manualmente a aplicação. Códigos de testes mal feitos são infernais, ter que gastar mais tempos alterando código de teste do que alterando código real é de deixar qualquer um louco. Se a cada a vez que você altera um if dezenas ou centenas de testes se quebram você, com certeza, está investindo em algo que não se paga. Ainda que uma ferramenta de cobertura te diga que 70% de código estácoberto.
E o mais grave com testes mal feitos é que cedo ou tarde, e normalmente cedo, eles vão ser abandonados. Aí sim o desperdício se completa, porque TUDO o que você gastou com eles foi pro lixo.
Isso aí eu acho também que foi um dos grandes lances dessa thread :D[/quote]
Achei muito legal também esse negócio de mandar email pros caras.
Mas voltando (ou insistindo ainda nela) à obrigatoriedade do uso de TDD, veja que os exemplos que o Helio citou são exceções. A regra histórica de desenvolvimento de software é a falha. Desde um número absurdo, inaceitável até, de cancelamento de projetos, até atrasos, entrega de funcionalidades meia boca, mal implementadas, aplicações bugadas e coisas do gênero. Essa é a regra da qualidade do software hoje.
Eu dei uma procurada básica sem perder muito tempo e achei num post sobre gerenciamento de projetos alguns números. Segundo o Standish Group em 2003 o número de projetos de software concluído com sucesso foi de 28% (impressionante!!!), enquanto projetos na área de engenharia, segundo Why Software Projects Fail, os projetos concluídos com sucesso estão na casa dos 94%. Sendo que concluído com sucesso quer dizer, entregue no custo e prazo determinados. http://www.fernandoamaral.com.br/Default.aspx?Artigo=52
Não investiguei a veracidade desses números, nem em que contexto se aplicam, por tanto podem estar distorcidos. Embora eu tenha estranhado os 94%, achando alto demais, todos nós sabemos que o número de falhas em projetos de software é extremamente alto.
Por isso eu acho “perigoso” tentar provar uma tese de que algumas técnicas recentes, que se propõem a preencher lacunas há muito abertas na codificação de software são desnecessárias e fazer isso se utilizando de exceções à regra de que projetos de software tradicionais costumam falhar.
Eu não tenho números, nem sei se alguém os tem (embora muitos clamem ter achado o santo graal do desenvolvimento de software), sobre como TDD e testes automáticos como um todo melhoraram o desenvolvimento de software. Eu posso responder por mim e para mim ele é um divisor de águas.
E não estou sozinho nessa opinião, há algum tempo assisti a uma palestra do Robert C. Martin em que ele diz acreditar que TDD se tornará parte integrante do processo de desenvolvimento de software no futuro. Ele compara TDD ao fim do goto, pensado impossível a princípio escrever código sem goto, hoje ele é praticamente ignorado.
Michael C. Feathers, autor de um dos mais extraordinários livros sobre desenvolvimento de software que li (Working Effectively with Legacy Code), considera código legado todo código que não possui testes unitários automatizados.
Só para citar alguns dos grandes autores que defendem a prática de escrever testes antes do código, de ter um sistema cuja consistência possa ser verificada sempre que necessário.
[quote=YvGa][quote=sergiotaborda]
Cobertura de 100% é impossível. O normal é 30-50% e 70% é absurdamente bom. Mas claro, testar todos os get/set não conta nesta cobertura. Além disso testes são incrementais. Começa por testar o que você espera que possa dar errado. Depois, vc vai receber tikets com erros que mostra que alguns cenários vc não previu e vc adiciona mais testes e assim vai… ninguém testa tudo da primeira vez. Seria insano.
Criar testes é dificil, caro , demorado e muitas vezes mais dificil que criar o próprio sistema. Eu vivo isto todos os dias, não apenas no trabalho, mas no meu projeto pessoal que tem mais de 60 mil linhas de código e 1900 classes. Para tudo isto tenho 127 testes com 16% de cobertura - muito pouco. Mas não vale me enganar achando que o mais importantes é o código e que não preciso dos testes. É claro que preciso. Muitos refactorings são feitos na fé e isso não é bom. Não vale me enganar dizendo que se o Spring ou o JDK não têm testes eu também não preciso. Não vale tentar arranjar desculpas para não fazer os testes.
[/quote]
Dois parágrafos em particular do que você escreveu que eu gostaria de comentar.
Cobertura de 100% eu acho impossível tambem, mas o fato de estar 70% por si só não é necessariamente bom. Nesse ponto eu tenho que concordar com o saoj, se eu tenho testes apenas pela obrigação de tê-los, e ainda que eu os tenha cobrindo os pontos mais importantes da aplicação, ainda assim pode não ser bom.
Para exemplificar vamos ao segundo parágrafo, supondo que voce esteja falando de testes automatizados quando diz que criá-los é difícil e caro.
Difícil? Não sei se são, difícil sim é aprender as técnicas a tal ponto que escrevê-los seja fácil.
[/quote]
Quando eu disse 70% de cobertura, me refiro a caso de teste automáticos que cubram 70% da funcionalidade e não a 70% do código ser executado.
Ha essa ideia - errada quanto a mim - de ferramentas como o Cobertura que medem as linhas que são executadas durante um junit da vida. Isso não é cobertura de verdade, é enganação. Como vc disse, e bem, ha muitas coisas a considerar mais importantes que isso.
Este é um outro pré-conceito errado (missconception). Valor do produto existe para os stakeholders, o cliente é apenas um desses stakeholders. A empresa é outro. Aceitando que os testes não elevam o valor para o cliente ( o que poderíamos argumentar que não é verdade) eles elevam para a empresa. Diminui risco, diminui impacto, diminui surpresas , melhora o design, melhora o entendimento , melhora a documentação que código é por si mesmo.
Testes nunca são um desperdício. Mas claro, estou falando de testes como deve ser, não experiencias ou junits aqui e ali sem nexo nenhum. Como vc falou, criar um arcabouço de testes (test harness) não é trivial. Poderemos criar um junit que testa todos os get/set da vida e tem cobertura de execução de código de 100% mesmo assim é um lixo e não serve para nada. A discussão parte do principio que estamos falando de testes verdadeiros, em feitos e bem pensados.
Sim. Esse é o ponto.
Ha o custo de montagem do teste. Ou seja, pessoas trabalhando para criar e manter código que testa outro código. Isto como vc falou exige pessoas especializadas e como tal é caro. Mas caro aqui em termos de muito dinheiro não em termos de custo/beneficio. Este dinheiro é um investimento. Quando vc paga a alguém para testar manualmente o custo é o mesmo (pode ser o mesmo) mas é uma despesa, não um investimento.
O importante, como vc e mais alguém já disseram ai, é entender que o test harness é um colchão que protege o projeto, o produto , o investimento. E é por isso que ele é importante e é por isso que todos os desenvolvedores deveriam pressionar para ter um. Não ter um é como aceitar deixar viajar seus filhos sem cinto de segurança ou não passar alcool antes e depois da vacina. Vc pode viver sem isso, mas o risco é maior.
O TDD em si é uma moda, mas o Test-First e o Test Harness não são. Isto deve ser claro na mente de todos.
Se Donald Knuth, Joe Armstrong e Ken Thopnsom, pra citar alguns, encontraram o santo graal eu não sei, mas o que eles falam, eu seria um trouxa se não escutasse.
Por outro lado, pra cada um que diz ter achado o santo graal do desenvolvimento de software, existe 10 blogueiros e autores de livros que só sabem falar sobre como programar OO usando TDD, mas não fazer.
Bom, pelo menos eles não ficaram conhecidos pelo software que criaram.
Agora, não me leve a mal, até gosto do trabalho do Bob Martin, mas não vamos confundir evangelizadores de testes com os verdadeiros mestres da arte!
[quote=NickGaspar][quote=YvGa]
embora muitos clamem ter achado o santo graal do desenvolvimento de software
[/quote]
Se Donald Knuth, Joe Armstrong e Ken Thopnsom, pra citar alguns, encontraram o santo graal eu não sei, mas o que eles falam, eu seria um trouxa se não escutasse.
Por outro lado, pra cada um que diz ter achado o santo graal do desenvolvimento de software, existe 10 blogueiros e autores de livros que só sabem falar sobre como programar OO usando TDD, mas não fazer.
Bom, pelo menos eles não ficaram conhecidos pelo software que criaram.
Agora, não me leve a mal, até gosto do trabalho do Bob Martin, mas não vamos confundir evangelizadores de testes com os verdadeiros mestres da arte![/quote]
Como eu disse no meu post anterior, não devemos usar da exceção para tentar provar a regra.
Eu não sou um grande mestre, eu não tenho toda a bagagem e nem todas as qualificações que eles têm para simplesmente ignorar o que aqueles como eu dizem.
Repetindo Keith Braithwaite:
Se dez blogueiros e alguns autores me dizem que teste unitário é bom (e eu comprovei por conta própria que para mim é), mas alguns dos mestres dizem que para eles é perda de tempo em quem eu devo acreditar?
Lógico que nos blogueiros e autores, pois eles estão bem mais próximos da minha realidade do que esses caras. Eu não sou um gênio, nem nunca vou me tornar, eu sou apenas alguem que recebe um pouco de dinheiro para entregar bom software para o meu cliente. Mais ou menos como os blogueiros que dizem que testes unitários são importantes, com mais ou menos os mesmos problemas e as mesmas dificuldades. Se funcionou para eles, é bem possível que funcione para mim. O que funcionou para Donald Knuth, pouco provavelmente funcionará para mim.
Se você está entre os gênios que pode simplesmente ignorar o benefício que esta técnica tem trazido, ótimo para você. Mas esse não é o meu caso, não é o nosso caso, o da maioria dos programadores.
E só para garantir que ninguém se esqueceu. Ainda hoje, a falha é a regra em projetos de software.
Quando vc está programando vc introduz muitos bugs que os testes unitários vão pegar pra vc?
Ou quando o Junit fica vermelhinho não é um bug mas sim os contratos que mudaram e agora vc tem que atualizar os seus testes unitários?
Se os testes unitários estão pegando vários bugs que vc está introduzindo no seu código, então eles realmente são essenciais.
No meu emprego atual tem teste unistário pra kacete. Mas nas raras vezes que ele fica vermelho não é bug não. É contrato que foi modificado, apenas isso.
PS: Eu não sou gênio e não uso teste unitário. Estou mais para compulsivo. Genealidade está mais para matemática e física, do que para lógica. Para esses vc realmente precisa de um pode de processamento cerebral elevado.
Mais um objetivo atingido sobre abrir mentes nesta thread ! Alguém precisa pegar pontos relevantes e postar em algum lugar.
sergiotaborda:
Comentários sensatos.
YvGa:
Não há nada melhor do que a realidade e eu à admiro na maioria dos meus devaneios.
A vida real é assim mesmo, tem um diretor querendo um software pra agora e nem quer saber se você é júnior, sênior, se agrega valor ou não à empresa dele, mas se você não entrega a parada “Rodando”, você perde o emprego que você gosta. Isso é bem real, gostei da exposição do seu comentário, vários passam por isso. Ainda digo mais, tem um monte de gênio do passado ou atuais, que lidam apenas com uma linguagem, é sério, não sabem desenrolar html, nem se preocupam com o xmlhttprequest 2, com desenvolvimento mobile nativo, híbrido ou usando html5 + css3 +js, nem relatórios chatos, etc etc etc, performance, segurança etc…
Embora não sejam obrigados a saberem para serem chamados ou não de gênios.
saoj :
O saoj é um caso a parte. Só quem já teve oportunidade de trocar umas ideias real-time, gtalk ou seja lá o que for, para presenciar resultados de coisas complexas resolvidas em pouco tempo. Meu pensamento no geral é parecido com o dele, não sou foda como o cara mas sou compulsivo.
Essa semana irão entrar 2 em produção um java swing puro feito todo na mão por que não sei usar o netbeans ainda e não gosto do código gerado por ele e outro que não vou citar detalhes, nenhum desses tem teste unitário, foi testado claro, mas bateria de teste com junit. Se tivesse seria bom mesmo é verdade, mas não tem e vai gerar lucro para a empresa. No geral eu acho que é importante saber fazer testes, com ou sem junit não precisa ser com o junit também, contanto que a funcionalidade atenda as espectativas, se não tiver teste no formato fomentado ou mercadológico ou seja lá o que for eu programo também do mesmo jeito.
Quando vc está programando vc introduz muitos bugs que os testes unitários vão pegar pra vc?
Ou quando o Junit fica vermelhinho não é um bug mas sim os contratos que mudaram e agora vc tem que atualizar os seus testes unitários?
Se os testes unitários estão pegando vários bugs que vc está introduzindo no seu código, então eles realmente são essenciais.
No meu emprego atual tem teste unistário pra kacete. Mas nas raras vezes que ele fica vermelho não é bug não. É contrato que foi modificado, apenas isso.
PS: Eu não sou gênio e não uso teste unitário. Estou mais para compulsivo. Genealidade está mais para matemática e física, do que para lógica. Para esses vc realmente precisa de um pode de processamento cerebral elevado.
[/quote]
Certo, saoj, vamos lá.
Eu não ignoro o fato de que para se ter testes é preciso cuidar deles, e cuidar deles tem um custo. Se eu passei uma impressão diferente, o que não acho, me desculpem, mas nem de longe foi a minha intenção. A tecla que eu continuo batendo é a de diminuir ao máximo o custo deles para que eles se paguem, para que tê-los valha a pena. Como eu já disse, várias vezes, eu acho que não se deve (não se pode, talvez fosse melhor) gastar mais tempo trabalhando com testes do que trabalhando com o código testado.
Não, normalmente não, embora eventualmente aconteça.
Sim, geralmente as alterações são por conta dos contratos que mudaram e eu tenho que atualizar meus testes unitários. E é a partir deste ponto exato que nossas opiniões começam a divergir. E a partir deste ponto que nós, nos nossos estudos, carreira, teorias e seja lá mais o que for, seguimos caminhos diferentes. Neste ponto tanto eu como você achamos que ter testes unitários “protegendo” a aplicação estava ficando custoso demais. Você optou por abandonar a técnica, eu optei por buscar formas de simplificar os testes para diminuir esse custo. Eu descobri que eu preciso nos meus códigos de teste, tanto ou mais código limpo do que preciso no meu código testado.
Não vou te dizer que sou um mestre do teste unitário, que se você vir meu código de testes vai ficar tão maravilhado pela simplicidade que vai começar a escrever testes no mesmo instante. Mas eu já percorri um trajeto considerável nesse caminho e sempre que esbarro em problemas nos meus testes eu procuro formas de simplificá-los ainda mais. E isto tem me dado resultado.
Quando eu altero algo meus testes ficam vermelhos normalmente por causa de quebra de contrato, mas alinhar esse contrato e fazer os testes refletí-los tem se tornado tarefa cada vez mais simples. Quando eu digo simples, eu quero dizer rápida. Altero dois ou três testes, as vezes só a montagem comum deles e pronto, eles estão verdes novamente. E adequados às novas regras do sistema.
O que eu tenho sempre em mente é: não se pode perder mais tempo mantendo testes do que mantendo o código testado.
Mas ainda assim o fato de eu ter que alterar testes por causa de alteração de contrato não significa necessariamente que eles só me dão trabalho. Muitas vezes essas quebras de contrato me mostram a inviabilidade de uma solução que eu havia pensado e que talvez não fosse tão óbvia somente olhando o código a ser alterado.
Eu não tenho como manter na minha cabeça todas as possibilidades de efeito colateral de uma alteração, então a quebra de contrato não serve somente pra me encher o saco com tarefa mecânica de alterar o que eu não precisaria se eu não tivesse testes. As vezes eu corro lá no teste que quebrou pra alterar rapidinho e ficar tudo verdinho de novo e epa!!! Não era tão simples assim. Alterar para que atenda ao contrato é simples, acrescento ou removo um parâmetro, mudo a entrada, a saída ou sei lá mais o quê e pronto, tudo compila. Compila, mas não fica verde. E aí eu vejo que vou ter que alterar o contrato bem mais do que havia previsto, ou não da forma como havia previsto, ou que não vou poder alterar de jeito nenhum.
Isso é bem mais comum do que ver os testes encontrando bugs. Mas ainda assim eles encontram. De vez em quando acontece de você se encostar na cadeira esticar bem as pernas, se espreguiçar, mandar rodar os testes e já ir levantando pegar um cafézinho antes de anunciar que terminou, e os testes ficam vermelhos.
Mas o ponto principal, saoj, é que com testes unitários ou sem, os contratos foram modificados e cada ponto em que eles foram modificados e as continuações desses pontos, mesmo aquele daquele cliente menor que quase não pede alteração, mas usa o sistema, todos eles terão de ser executados. Cada caminho desse, cada combinação dessas vai ter que ser validada. Se você não tem testes automáticos alguém vai ter que executar pra você cada uma das funcionalidades que dependia daquele contrato para ver se continua funcionando de acordo com o novo. E esse alguém vai ter que se lembrar de cabeça onde estão e como devem se comportar essas funcionalidades.
Se você tem uma capacidade de design de código tão bom a ponto de desdenhar disso tudo, e eu não tenho porque duvidar disso, não mesmo, até porque os frameworks nos quais você trabalha são elogiados por muita gente, ótimo para você. E se isso é realmente possível eu espero um dia chegar lá. Mas não é o meu caso hoje, e sem hipocrisia, nem falsa modéstia. Eu sou um designer de código no máximo meia-boca, mas a maioria é como eu e a maioria precisa de mecanismos que os ajudem a escrever código melhor e mais confiável.
Eu sou a favor de alterações conservadoras e seguras. De bom entendimento de lógica para que se for alterar não vai fazer merda. Mas tem alterações mais complexas (porra, realmente vc precisa fazer essa alteração complexa) que vai ser foda de garantir que algo não quebrou. Daí vc dá uma testada manual mesmo. Roda o seu sisteminha e testa aquela parte do seu sistema. Não precisa necessariamente testar tudo, mas só aquela parte.
Chegamos num ponto de que não há certo ou errado mais. Vai de gosto mesmo.
Bom ponto, Paulo.
Edit: Outra coisa que sou a favor é de experimentar e mudar que nem um louco no começo. Mas daí chegar num ponto mínimo onde vc tem uma FUNDAÇÃO boa. E partir dali seguir de forma mais conservadora. Sou totalmente contra, por questões de sanidade, responsabilidade e foco em resultado, no meio do projeto fazer uma alteração radical nas coisas. A não ser que ninguém use e que vc esteja cagando para bugs, etc.
Resumindo. No início muda que nem um louco. Estabiliza uma fundação. Depois liga o conservative mode. E som na caixa!
Será que um cara que escreve API passaria por algo assim ? Ou a % de chance disso acontecer em relação a um que escreve software corporativo de workflow de aprovação por exemplo, seria maior ou menor ?
De qualquer forma essa colocação foi super válida para apontar esse pensamento.
Este pequena frase esconde várias coisas. Primeiro podem ingenuamente pensar que esse sistema irão dar lucro agora. O cara recebe em troca do software e tanto faz se funciona ou não. o usuário nunca irá saber a menos que use.
Ora o problema é que o usuário não compra o software para ter no armário. Ele vai usar. E vai encontrar problemas. E os problemas sempre voltam à origem. E ai começa o ciclo de correções e a erosão da confiança do cliente e do dinheiro antes recebido.
O que parece ia lucro , deixa de ser.
Se estamos falando de produto é ainda pior. qualquer alteração aumenta o risco sobremaneira e é mais caro alterar o legado do que fazer do zero. E ai se criam os famosos modulos ( = não vamos mexer no que temos vamos fazer um puxadinho)
e agora os problemas se multiplicam pelo numero de módulos e este fractal de problemas não tem fim.
Sim, claro, façamos o sistema sem testes automáticos. Afinal isso é muito caro. Porque gastar dinheiro com isso. “gastar” dinheiro com isso. Quando alguém fala que fazer testes é despesa, pronto, ai sabemos que o cara não sabe do que fala. Pior, ainda vive em 1950.
Segundo, quem realmente comanda a parada é o desenvolvedor. O que é que realmente vai acontecer se chegar o prazo e o software não estiver pronto ? Vamos extender o prazo, trabalhar horas extra. E isso que vai acontecer. Nenhum cataclismo irá acontecer.O mundo não acada quando o programador diz que não está pronto. Aliás a gerencia espera ouvir isso. Eles só não acreditam ou não querem acreditar. Todos sabemos que a gerencia já tinha cortado o tempo ao meio para começo de conversa, portanto, não é surpresa para ninguém. Ora ,mas esse atrazo não pode ser grátis. O desenvolvedor tem que dar algo em troca. Será que é aceitável atrazar o sistema porque o programador não sabe o que faz. Não. Mas e se ele sim sabe o que faz e está tentando diminuir o risco ? Alguém o pode culpa por isso ? Não. Alguém já foi despedido por fazer testes unitários a mais ? Não. Então o outro lado da medalha não é apenas a empresa e a gerencia que perdem e acham que fazer testes é “gastar” tempo. O pecado original aqui é a preguiça do programador e a falta de comprometimento com a ética do desenvolvimento. Então o que sobra ? Sobra força a que o gerente lhe diga “não faça testes, é gastar tempo”. Quando a ordem vem de cima é outra música.
E tudo isto nos leva ao terceiro ponto. O atraso civilizacional em que vivemos onde os nossos superiores não reconhecem o óbvio e nossos pares são preguiçosos.
Alguém duvida da eficácia do método ? Alguém duvida que realmente aumenta a segurança, diminuir o risco e o tempo de refactoring ? Então porque discutir se é custosos manter ?
Além se preocupa se é custoso manter os sistemas de testes de uma central nuclear ? Não. Até que eles falham e todos morrem de medo da radiação.
Podemos ver pessoas dizendo que assumem o risco. “Ah! eu não faço testes porque sou o Chuck Noris e os bugs fogem de mim”. Claro. Todos podemos fazer isso. Mas aceitar o risco é uma coisa. Ignorá-lo é outra. E outra pior é não saber que ele existe.
Talvez o investimento não valha a pena. Não é todo o risco que pode ser mitigado. às vezes é simplesmente muito caro e não compensa. Ok. Mas esta decisão é lógica e baseada em fatos. Não é uma questão de gosto. Não é uma questão de preguiça.
Não é uma questão de que tenho que efetivamente manter dois sistemas funcionando ( o test harness e o sistema). Podriamos perguntar, mas se o teste harness é código que o testa a ele ? Ora, existem planos de contigencia do plano principal, mas em software isso é insanamente caro. Portanto, por agora, temos que assumir o risco do código de testes estar errado. Transferimos os risco. Mas transferimos o risco do sistema principal que nos dá lucro para o sistema de apoio que não nos dá prejuizo. É bem diferente.
Outro ponto que está sendo esquecido é que ninguém trabalha sozinho. É fácil vc trabalhar sozinho num framework que pode até ser grande e complexo, mas vc tem tudo na cabeça e sabe onde as coisas irão falhar e assume o risco e não faz testes. Outro cenário bem diferente é ter 10 ou 20 pessoas trabalhando com estilos diferentes em pedaços diferentes do código que ninguém realmente conhece todo. Quem vai assumir o risco ? Você vai assumir o risco do código que o seu colega criou ? Por muito que ele seja um gênio ou cuidadoso , vc poria a mão no fogo por ele ?
Ninguém vai me dizer que sim, né ? Então vamos nos deixar de bla bla bla sobe o quão dificil é manter um test harness. Simplesmente é. E simplesmente é necessário. Pronto. É como manter a segurança de um central nuclear ou ter que educar os filhos. Não é fácil, mas é necessário. É claro que queremos que seja o mais rápido, barato e simples possível, mas isso é completamente diferente de simplesmente não fazer nada.
A razão de porque as empresas e os gerentes não levam o test harness a sério é porque os desenvolvedores não o levam a sério e não o sabem vender. Eu me incluo aqui.Eu sei o quão sério é, mas não consigo vender porque logo alguém vem e fala que é “gastar” dinheiro. E tudo bem se fosse o gerente a falar isso. O pior é quando é outro colega. Ai passa a ideia que existe um caminho mais fácil. Claro. Mais fácil. Mas não mais seguro.
Depois que todos são conscientes do que é, e como funciona, e como irá influenciar o futuro e ai, baseado em dados e fatos se chega à conclusão que não é necessário, isso é legítimo. Mas descartar à partida baseado em uma filosofia de vida dos estilo “Chuck noris” ai não dá. É simplesmente idiota.
SE vc tem um classe matriz que vc vai usar em programa que c vai usar 2 vezes, não ha porque mitigar o risco. Seria mais caro que fazer o programa. Agora se vc vai usar essa classe num sistema de calculo que trabalha com milhões e pode ganhar ou perder milhares, vc vai encarar o risco ? E se for um sistema de apoio à vida ? Tamanho e proporção. É isso que temos que ter antes. Por isso que eu não acho que TDD é ensinada corretamente. O Beck tem tendencia a exagerar. Para ele eu tria que testar que 2+ # não é 4 para depois decobrir que 2+2 que é 4 , quando eu já sei à prioria isso. Eu teria que criar um teste para a matriz, antes de criar a matriz mesmo que eu só vá usar 2 vezes. Ou o exagero do tio Bob que o TDD é equivalente e matar o goto. Por amor de Deus, não é nada disso. Tamanho e proporção. Tamanho e proporção.
Discordo de vc aqui. Posso falar pela minha experiência. Cada um tem a sua e é ela que vai determinar seu modo de ver as coisas. Ninguém nasce com convicções. É o ambiente e o caminho que o cara percorre que as cria.
Trabalhei em banco de investimento onde um bug significava prejuízo certo e instantâneo. Entre 50k e 200k. Claro que a empresa fazia bastante dinheiro para aguentar um erro desse por mês, mas eu vi uns 4 ou 5 em dois anos. A pergunta é: Se houvesse testes unitários haveria esses erros? Provavelmente, porque nunca era erro simples. Eu fiz um erro desse uma vez que custou uns 100k. Claro que me lembro até hoje. Assumi que a conexão nunca iria me enviar uma coisa, que essa coisa era impossível. Na verdade se eu soubesse disso teria codificado um IF conservador para pegar esse caso, mesmo ele sendo 99.9% impossível. Mas nem sabia da existência dessa possibilidade. Daí a coisa mapeou um produto A como se fosse um produto B. Descobriu-se a cagada em 5 minutos com posições inconsistentes mas o estrago já tinha sido feito. Dava para pegar esse erro com teste unitário? Claro que não.
Se eu altero código dos outros, que eu não domino, basta ser conservador. Se vc for querer ser chuck norris de entender tudo, codificar usando padrões GoF, fazer cobertura 100% o que vai acontecer é que vc vai demorar 10 vezes mais para fazer a coisa e a chance de ter um erro ali será praticamente a mesma. Existe pessoas e empresas práticas que querem resultado e dinheiro. E outras que querem engenharia de software e padrões GoF. Essas últimas geralmente são empresas grandes onde dinheiro não é problema e a burocracia é grande de qualquer jeito então pode-se gastar o tempo que for refatorando e é até melhor pois não vão te pedir para fazer outras coisas. 8)
Tudo que é necessário é boa lógica, bom OO e pouco puritanismo. Fiz essa alteração de acordo como os deuses da engenharia de software gostariam de vê-la? Não! Mas te garanto que é 100% segura! E fiz em 5 segundos. Pode colocar em produção.
Já trabalhei em outra banco de investimento que era o oposto disso. Daí tirei minha preferência, vendo os dois mundos operar.
Teste unitário é bom. Sim, com certeza. Teste unitário é fundamental. Não, na minha opinião.
Um sistema que tem mais teste unitário que outro é mais seguro do que outro. Pela minha experiência acho que não.
Mudança radical num sistema que já esteja em produção e funcionando por um bom tempo é permitida? DE JEITO NENHUM. Gasta um tempo inicial para fazer a coisa direitinho e bonita. Depois entube a sua decisão e se preocupe em gerar resultados para o negócio e não em ficar brincando de engenharia de software. (Nota: Se tivesse teste unitário a mudança radical TAMBÉM não seria permitida em fase avançada)
A regra dos práticos é clara: não se faz mudança radical em sistema que já está funcionando em produção há muito tempo. O cara que fez, fez tudo cagado? Sorry, então refaz do zero a parte cagada, mas não vai brincar de meter a mão para colocar padrões GoF e arranjar um bug em produção que antes não existia. A merda principal foi ter feito a coisa cagada in the first place. Por isso que é importantíssimo gastar um tempo inicial numa boa fundação. Começar com uma fundação cagada aí não há deus de engenharia de software (quanto menos teste unitário) que vai te salvar.
Na boa, não posso divulgar o cenário desses 2 projetos.
Logo você está livre para conclusões boas ou ruins.
Agora sobre chuck noris, cowboy esses rótulos, não achei muito legal, porque no geral não desenvolvemos apenas lá, tem infra e mais uma série de coisas para cuidarmos. mas tranquilo.
Me lembrei de quando trabalhava home-office , tive que derrubar 2 coqueiros (com um facão vagabundo) para ter acesso à internet, lembro que no segundo coqueiro eu estava pensando na infra-estrutura do projeto e uma pendência com o maven que eu tinha que resolver. Quando terminei pensei “Porra, isso faz parte ?”
Meu gerente na época falou que foi a primeira vez que ele teve problema desse na carreira dele. Falei sobre a pendência do Maven o cara falou que eu havia perdido 2 dias sem internet e mais uma manhã de um sábado derrubando coqueiro, deixa a pendência pra lá.
Incrivel porque um monte de teste unitário foi pro lixo também… o detalhe é que o cliente é um hotel residencial grande pra caralho em NY. Cuidava desde o servidor CentOS pra aguentar as pancadas de usuários em 4 de julho e natal. Mas isso ai qualquer zé-cueca faz hoje em dia “joga no cloud”.
Eu até quiz terminar os testes, mas fiquei com uma preguiça da porra, confesso. Sem falar que tive um problema temporário de coluna e os calos nas mãos porque os coqueiros que derrubei tinham mais de 20 anos, sei disso porque eram da casa do sogro. Mas tudo em prol do software !
Hoje senti vontade de aplicar no sistema java swing que citei anteriormente. Fica a dica para quem não conhecia assim como eu.
O cenário desse projeto foi assim com o stakeholder in house:
Sr. “A” ------------------------------ Eu
“Cliquei aqui deu problema…” > “Corrigido”
“Não está aparecendo a aba…” > “Corrigido”
“A tabela não está carregando dependendo de xpto” > “Corrigido”
…
E assim por diante
Nesse caso uma ferramenta como o uispec4j ajudaria em não desperdiçar o tempo do “Sr. A” ou pelo menos reduzir correto ? Quando houve uma pré-implantação, tivemos que modificar
o sistema de tabulação inteiro do TAB para o Enter. Isso só com bola de cristal mesmo, para descobrir que o cara da ponta usa apenas o teclado numérico porque segura documentos com a outra mão.
Set set = new HashSet(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.clear();
set.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set);
Sobre agregar valor, nesse caso agregaria mais valor usar o uispec4j do que uma bateria de testes no modo TDD ou seja lá como for ?
Eu acredito que sim, mas se alguém puder complementar.
Putz parece que existem problemas do uispec4j no linux
java.lang.UnsatisfiedLinkError: sun.awt.motif.MToolkit.init(Ljava/lang/String;)V
at sun.awt.motif.MToolkit.init(Native Method)
at sun.awt.motif.MToolkit.(MToolkit.java:146)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at org.uispec4j.interception.toolkit.UISpecToolkit.buildUnderlyingToolkit(UISpecToolkit.java:128)
at org.uispec4j.interception.toolkit.UISpecToolkit.setUp(UISpecToolkit.java:39)
at org.uispec4j.interception.toolkit.UISpecToolkit.(UISpecToolkit.java:24)
at org.uispec4j.UISpec4J.initToolkit(UISpec4J.java:39)
at org.uispec4j.UISpec4J.init(UISpec4J.java:31)
at org.uispec4j.UISpecTestCase.(UISpecTestCase.java:31)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at junit.framework.TestSuite.createTest(TestSuite.java:61)
at junit.framework.TestSuite.addTestMethod(TestSuite.java:294)
at junit.framework.TestSuite.addTestsFromTestCase(TestSuite.java:150)
at junit.framework.TestSuite.(TestSuite.java:129)
at org.junit.internal.runners.JUnit38ClassRunner.(JUnit38ClassRunner.java:71)
at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
[editado]
Consegui colocar para funcionar…mas tive que criar uma versão uispec4j-2.4-LOBOMETAL.jar
Dou uma dica pra quem quizer brincar de fazer funcionar no linux :
// Black magic - do not touch this (system.setProperty seem to load dynamic libraries)
if ("Linux".equalsIgnoreCase(System.getProperty("os.name"))) {
System.setProperty("awt.toolkit", "sun.awt.motif.MToolkit");
}
Pois é… tem “black magic” no código da ferramenta de testes, mas enfim…