Pergunta

Eu comecei a olhar para a idéia de desenvolvimento inteiro de testes de unidade / orientado a testes, e quanto mais eu penso sobre isso, mais ele parece preencher um papel semelhante ao verificação de tipo estático. Ambas as técnicas proporcionam um tempo de compilação, verificação de resposta rápida para certos tipos de erros em seu programa. No entanto, me corrija se eu estiver errado, mas parece que um conjunto de teste de unidade com cobertura total seria testar a verificação de tipo tudo estática iria testar, e então alguns. Ou formulada de outra forma, verifica tipo estático só vão parte do caminho para "provar" que o seu programa está correto, enquanto que testes de unidade permitirá que você "provar" tanto quanto você quiser (até certo ponto).

Então, há alguma razão para usar uma linguagem com a verificação de tipo estático se você estiver usando o teste de unidade, bem como? Uma pergunta um pouco semelhante foi perguntado aqui , mas eu gostaria de entrar em mais detalhes . Quais as vantagens específicas, se houver, não verificação de tipo estático têm sobre testes de unidade? Algumas questões como otimizações de compilador e intellisense vêm à mente, mas existem outras soluções para esses problemas? Existem outras vantagens / desvantagens eu não tenha pensado?

Foi útil?

Solução

Gostaria de pensar que o teste de unidade automatizado será importante para dinâmico digitado idiomas, mas isso não significa que ele iria substituir a verificação de tipo estático no contexto que você aplica. Na verdade, alguns daqueles que usam tipagem dinâmica pode ser realmente usá-lo, porque eles fazem não quer as dificuldades de verificações de segurança constante do tipo.

As vantagens linguagens digitadas dinamicamente oferecem mais estática digitado línguas vão muito além de testar e segurança de tipos é apenas um aspecto. linguagens estilos e diferenças de design mais dinâmico e estático de programação digitado também variam muito.

Além disso, testes de unidade que são escritos muito vigorosamente reforçar a segurança de tipo significaria que o software não deve ser digitado dinamicamente afinal de contas, ou o desenho a ser aplicado deve ser escrito em uma linguagem de tipagem estática, não um dinâmico.

Outras dicas

Há um fato imutável sobre a qualidade do software.

Se não é possível compilar, não podemos enviar

Nesta regra, linguagens de tipagem estática vai ganhar mais línguas tipagem dinâmica.

Ok, sim esta regra não é imutável. Web Apps pode enviar sem compilar (eu implantado muitos aplicativos de teste da web que não compilar). Mas o que é fundamentalmente verdadeiro é

Quanto mais cedo você pegar um erro, o mais barato é a correção

Uma linguagem de tipagem estática irá evitar erros reais de acontecer em um dos primeiros momentos possíveis no ciclo de desenvolvimento de software. Uma linguagem dinâmica não. Testes Unitários, se você está completa para um nível humano de super pode tomar o lugar de uma linguagem de tipagem estática.

No entanto por que se preocupar? Há um monte de pessoas incrivelmente inteligentes lá fora escrever todo um sistema de verificação de erros para você na forma de um compilador. Se você está preocupado sobre a obtenção de erros mais cedo usar uma linguagem de tipagem estática.

Por favor, não tome este post como uma tareia de linguagens dinâmicas. Eu uso linguagens dinâmicas diária e amá-los. Eles são incrivelmente expressivo e flexível e permitir incrivelmente fanscinating program.s No entanto, em caso de erro no início relatando que fazem perder a linguagens de tipagem estática.

Para qualquer projeto de tamanho razoável, você simplesmente não pode responder por todas as situações com apenas testes de unidade.

Assim, a minha resposta é "não", e até mesmo se você gerenciar a conta para todas as situações, que você derrotou, assim, todo o propósito de usar uma linguagem dinâmica em primeiro lugar.

Se você quiser programa de tipo seguro, melhor usar uma linguagem de tipo seguro.

Tendo cobertura de código 100% não significa que você tenha testado completamente sua aplicação. Considere o seguinte código:

if (qty > 3)
{
    applyShippingDiscount();
}
else
{
    chargeFullAmountForShipping();
}

posso obter cobertura de código 100% se eu bombear em valores de qty = 1 e qty = 4.

Agora imagine minha condição empresarial era que "... para ordens de 3 ou mais itens que eu sou para aplicar um desconto para os custos de envio ..". Então, eu precisaria estar escrevendo testes que trabalharam nos limites. Assim, gostaria de projetar testes em que qty foi de 2,3 e 4. Ainda tenho 100% de cobertura, mas mais importante eu encontrei um bug em minha lógica.

E esse é o problema que eu tenho com foco na cobertura de código sozinho. Eu acho que na melhor das hipóteses você acabar com uma situação onde o desenvolvedor cria alguns testes iniciais com base nas regras de negócios. Então, a fim de elevar o número de cobertura que eles fazem referência seu código quando novos casos de teste de design.

digitação manifesto (que eu suponho que você quer dizer) é uma forma de especificação, teste de unidade é muito mais fraco, uma vez que só fornece exemplos. A diferença importante é que uma especificação declara que tem de realizar, em qualquer caso, enquanto um teste cobre apenas exemplos. Você nunca pode ter certeza que seus testes cobrir todas as condições de contorno.

As pessoas também tendem a esquecer o valor de tipos declarados como documentação. Por exemplo, se um método Java retorna um List<String>, então eu saber instantaneamente o que eu recebo, não há necessidade de ler a documentação, casos de teste ou até mesmo o próprio código método. Da mesma forma para os parâmetros: se o tipo é declarado então eu sei o que o espera método

.

O valor de declarar o tipo de variáveis ??locais é muito mais baixo desde que em código bem-escrito o escopo da existência da variável deve ser pequena. Você ainda pode usar tipagem estática, porém: em vez de declarar o tipo que você deixe o compilador inferir-lo. Linguagens como Scala ou mesmo C # permitir que você faça exatamente isso.

Alguns estilos de testes de se aproximar de uma especificação, por exemplo, QuickCheck ou do Scala variante ScalaCheck gerar testes baseados em especificações, tentando adivinhar os limites importantes.

Eu faria palavra de uma forma diferente - se você não tem uma linguagem estaticamente digitada, você tinha melhor tem testes de unidade muito completas, se você planeja fazer qualquer coisa "real" com que código.

Dito isso, tipagem estática (ou melhor, digitação explícita) tem algumas vantagens significativas sobre os testes de unidade que me fazem preferem geralmente. Ele cria muito mais compreensível APIs e permite a visualização rápida do "esqueleto" de um aplicativo (ou seja, os pontos de entrada para cada módulo ou seção de código) de uma maneira que é muito mais difícil com uma linguagem dinamicamente digitado.

Para resumir: na minha opinião, dada, testes de unidade completas sólidos, a escolha entre uma linguagem dinamicamente digitado e uma linguagem estaticamente digitada é principalmente um de gosto. Algumas pessoas preferem um; outros preferem o outro. Use a ferramenta certa para o trabalho. Mas isso não significa que eles são idênticos - linguagens estaticamente tipadas sempre terá uma vantagem em certas formas e linguagens dinamicamente tipadas sempre terá uma vantagem em certas maneiras diferentes. Os testes de unidade percorrer um longo caminho no sentido de minimizar as desvantagens de línguas dinamicamente digitados, mas não eliminá-los completamente.

Não.

Mas isso não é a questão mais importante, a pergunta mais importante é: que importa que não pode

?

Considere a finalidade de verificação de tipo estático: evitando uma classe de defeitos de código (bugs). No entanto, este tem de ser ponderado no contexto da maior domínio de todos os defeitos de código. O que mais importa não é uma comparação ao longo de uma tira estreita, mas uma comparação entre a profundidade e amplitude de qualidade de código, facilidade de escrever código correto, etc. Se você pode vir até com um estilo de desenvolvimento / processo que permite que sua equipe para produzir maior qualidade código mais eficiente, sem verificação de tipo estático, então vale a pena é isso. Isso é verdade mesmo no caso em que você tem buracos em seus testes que a verificação de tipo estático iria pegar.

Suponho que poderia se você é muito completo. Mas por que se preocupar? Se o idioma já está verificando para garantir tipos estáticos estão corretas, não haveria nenhum ponto em testá-las (desde que você obtê-lo gratuitamente).

Além disso, se você estiver usando linguagens estáticas digitado com um IDE, o IDE pode fornecê-lo com erros e avisos, mesmo antes de compilar para teste. Não estou certo há qualquer unidade automatizada testando aplicações que podem fazer o mesmo.

Tendo em conta todos os benefícios da dinâmica, línguas ligação tardia, eu suponho que é um dos valores oferecidos pelos testes de unidade. Você ainda precisará de código com cuidado e intencionalmente, mas esse é o requisito # 1 para qualquer tipo de codificação IMHO. Ser capaz de escrever testes claras e simples ajuda a provar a clareza e simplicidade de seu projeto e sua implementação. Ele também fornece pistas úteis para aqueles que vêem o seu código mais tarde. Mas eu não acho que eu iria contar com ele para detectar tipos incompatíveis. Mas na prática eu não encontrar esse tipo de verificação realmente chama muitos erros reais de qualquer maneira. Não é apenas um tipo de erro que eu encontrar ocorrendo em código real, se você tem um estilo de codificação clara e simples em primeiro lugar.

Para javascript, eu esperaria que JSLint vai encontrar quase todas as questões de verificação de tipo. principalmente por sugerindo alternativo de codificação estilos para diminuir a sua exposição.

Tipo de verificação ajuda a cumprir os contratos entre componentes de um sistema. O teste de unidade (como o nome indica) verifica a interno lógica de componentes.

Para uma única unidade de código, eu acho que a unidade de teste realmente pode fazer tipo estático verificação desnecessária. Mas em um sistema complexo, testes automatizados não pode verificar todas as maneiras multidão que diferentes componentes do sistema podem interagir. Para isso, o uso de Interfaces (que são, em certo sentido, uma espécie de "contrato" entre os componentes) torna-se uma ferramenta útil para reduzir potenciais erros. E as interfaces exigem verificação de tipo de tempo de compilação.

Eu realmente gosto de programação em linguagens dinâmicas, então eu certamente não estou atacando tipagem dinâmica. Este é apenas um problema que recentemente me ocorreu. Infelizmente eu realmente não tenho qualquer experiência na utilização de uma linguagem dinâmica para um sistema grande e complexo, então eu estaria interessado em ouvir de outras pessoas se este problema é real, ou meramente teórica.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top