Deveria haver testes de unidade para expressões regulares complexas?

34

Devo escrever testes de unidade para expressões regulares complexas no meu aplicativo?

  • Por um lado: eles são fáceis de testar porque o formato de entrada e saída geralmente é simples e bem definido, e podem se tornar tão complexos que os testes específicos são valiosos.
  • Por outro lado: eles próprios raramente fazem parte da interface de alguma unidade. Talvez seja melhor testar apenas a interface e fazer isso de maneira a testar implicitamente as regexes.

EDITAR:

Concordo com o Doc Brown, que em seus comentários de notas que este é um caso especial da unidade de teste de componentes internos .

Porém, como as regexes de componentes internos têm algumas características especiais:

  1. Um regex de linha única pode ser realmente complexo sem realmente ser um módulo separado.
  2. Regexes mapeiam entrada para saída sem efeitos colaterais e, portanto, são realmente fáceis de testar separadamente.
Lii
fonte
12
"eles próprios raramente fazem parte da interface de alguma unidade". - se suas classes tiverem um código interessante escondido embaixo da interface, divida suas classes. Este é um exemplo de como pensar em tess pode melhorar o design.
Nathan Cooper
3
A mesma pergunta de uma maneira mais geral: quais componentes internos devem ser testados em unidade? Veja programmers.stackexchange.com/questions/16732/…
Doc Brown
Relacionado a Sorta, consulte Regex101. Eles têm uma seção para escrever testes de unidade para o seu regex. Por exemplo: regex101.com/r/tR3mJ2/2
David diz Reinstate Monica
3
Isenção de responsabilidade - este comentário é minha humilde opinião: 1 em primeiro lugar, acredito que os regexps complexos são pura maldade - veja também blog.codinghorror.com/… 2 o valor real de testar essas expressões ocorre quando você as examina em um grande banco de dados dados blog.codinghorror.com/testing-with-the-force 3 eu tenho uma estranha sensação de que estes testes não são unidades de testes exatamente
Boris Treukhov

Respostas:

101

Testando o dogmatismo à parte, a verdadeira questão é se ele fornece valor ao teste de unidade de expressões regulares complexas. Parece bastante claro que ele fornece valor (independentemente de o regex fazer parte de uma interface pública) se o regex for suficientemente complexo, pois permite encontrar e reproduzir bugs e impedir regressões.

JacquesB
fonte
25
+1, mas se uma expressão regular é suficiente complexo que este é um problema, então ele provavelmente faz sentido para movê-lo para uma unidade de "wrapper" com métodos apropriados ( isValid, parse, tryParse, ou outros enfeites, dependendo exatamente como ele está sendo usado), então que o código do cliente não precisa saber que está implementado no momento usando uma regex. A unidade do wrapper teria testes detalhados, que - novamente - não precisariam conhecer a implementação atual. Esses testes, é claro, estão de fato testando o regex, mas de uma maneira independente da implementação.
Ruakh 7/16
11
Um reg ex é um programa, embora em uma linguagem especializada e muito concisa. Como tal, o teste é apropriado para expressões não triviais ... E certamente o código que está chamando a expressão deve ser testado, o que pode implicitamente testar o reservado.
Keshlam #
6
@ruakh Bem dito. O benefício para uma classe de wrapper para uma regex é que você pode substituí-la ordenadamente por código comum, se isso for necessário. Código com entrada / saída complexa sempre deve ter teste de unidade, porque é extremamente difícil depurar sem. Se você precisar consultar a documentação para entender os efeitos do código, ele deve ter testes de unidade. Se for apenas um mapeamento 1: 1 rápido, como conversão de tipo, não há problema. Regexes ultrapassam esse ponto de exigir documentos muito rapidamente.
Aaron3468
4
@Lii: Regexes não merece nenhum tratamento especial. A regex é a unidade nesse caso, então testamos a unidade.
JacquesB
11
@ruakh Eu estava prestes a escrever uma resposta para esse efeito. Concordo que o uso de regex é um detalhe de implementação. O que importa é que as coisas validem quando deveriam e não conseguem validar quando deveriam. Teste as FooValidatorentradas e saídas e não se preocupe com o modo como está sendo feito. ++
RubberDuck
21

O Regex pode ser uma ferramenta poderosa, mas não é uma ferramenta em que você pode confiar para continuar funcionando se fizer alterações menores em regexes complexas.

Portanto, crie muitos testes que documentem os casos que devem ser abordados. E crie muitos testes que documentam os casos em que ele deve falhar, se for usado para validação.

Sempre que precisar alterar suas regexes, adicione os novos casos como testes, modifique sua regex e espere o melhor.

Se eu estivesse em uma organização que em geral não usasse testes de unidade, ainda escreveria um programa de teste que testaria qualquer regex que usaríamos. Eu faria isso no meu próprio tempo, se fosse necessário, meu cabelo não precisa perder mais cor.

Bent
fonte
3

Expressões regulares são código junto com o restante do seu aplicativo. Você deve testar se o código em geral faz o que você espera que ele faça. Isso tem vários propósitos:

  • Teste são documentação executável. Isso demonstra claramente o que você precisa que o código faça. Se for testado, é importante.
  • Os futuros mantenedores podem ter certeza de que, se o modificarem, os testes garantirão que o comportamento não seja alterado.

Como há um obstáculo extra a ser superado com o código em um idioma diferente incorporado ao restante, você provavelmente deve dar essa atenção extra em benefício da manutenção.

Thorbjørn Ravn Andersen
fonte
1

Em resumo, você deve testar sua inscrição, ponto final. Se você testar seu regex com testes automatizados que o executam isoladamente, como parte de uma caixa preta maior ou se você apenas mexe com ele manualmente, é secundário ao ponto em que você precisa garantir que ele funcione.

A principal vantagem dos testes de unidade é que eles economizam tempo. Eles permitem que você teste a coisa quantas vezes quiser agora ou em qualquer momento no futuro. Se houver algum motivo para acreditar que o seu regex será refatorado, ajustado, obterá mais restrições etc., sim, você provavelmente deseja alguns testes de regressão para ele ou, quando o alterar, precisará ir durante uma hora de reflexão sobre todos os casos extremos, para que você não o quebre. Isso, ou você aprende a viver com medo do seu código e simplesmente nunca o altera.

sara
fonte
3
Uma regra prática que eu vim a perceber; se eu precisava de documentos para escrever e inspecionar o código, precisarei de um teste de unidade. Eles me salvaram muitas dores de cabeça, capturando ponteiros nulos, nenhum tipo e saída incorreta. Eles também oferecem ao usuário final a capacidade de reparar seu código de acordo com as especificações com o mínimo de esforço possível, quando inevitavelmente quebra.
Aaron3468
-1

Por outro lado: eles próprios raramente fazem parte da interface de alguma unidade. Talvez seja melhor testar apenas a interface e fazer isso de maneira a testar implicitamente as regexes.

Eu acho que com isso você mesmo respondeu. Regexes em uma unidade provavelmente são um detalhe de implementação.

O que vale para testar seu SQL provavelmente também vale para expressões regulares. Quando você altera um pedaço de SQL, provavelmente o executa manualmente através de algum cliente SQL para ver se ele produz o que você espera. O mesmo vale para quando eu altero uma regex. Eu uso alguma ferramenta de regex com alguma entrada de amostra para ver se ela faz o que eu esperava.

O que acho útil é um comentário próximo ao regex com uma amostra de texto que ele deve corresponder.

Christiaan
fonte
" Quando você altera um pedaço de SQL, provavelmente o executa manualmente através de algum cliente SQL para ver se ele produz o que você espera. " Mas isso meio que responde à pergunta da outra maneira ... Se eu precisar ou achar útil testar as regexes manualmente, então eu deveria fazer um teste de unidade para isso. Exatamente isso é o que torna difícil decidir!
Lii 07/05
Isso realmente depende. O que você deseja para seus testes de unidade é a capacidade de fazer alterações. Com que frequência você altera uma regex específica? Se a resposta for muitas vezes, crie um teste para ela.
Christiaan
8
Como todas as outras coisas são iguais, é melhor ter um teste automatizado do que um "teste manual".
Robert Harvey
11
Por que você não testaria uma regex usando automação?
Tony Ennis
11
É parte de um método e tudo o que eu estava tentando dizer é que não há necessidade de testar especificamente a regex se você já testar esse método. Mas se você fizer isso, provavelmente será melhor extrair o regex em uma função separada que você testa isoladamente.
Christiaan
-5

Se você precisar perguntar, a resposta é sim.

Suponha que algum FNG apareça e pense que ele pode "melhorar" sua regex. Agora, ele é um FNG, tão automaticamente um idiota. Exatamente o tipo de pessoa que nunca deve tocar seu precioso código em nenhuma circunstância! Mas talvez ele esteja relacionado ao PHB ou algo assim, então não há nada que você possa fazer.

Só que você sabe que o PHB vai arrastá-lo chutando e gritando de volta para este projeto para "talvez dar ao cara algumas dicas sobre como você fez essa bagunça" quando tudo der errado. Então, escreva todos os casos que considerou cuidadosamente ao construir sua bela obra-prima da expressão.

E como você os anotou, você tem dois terços do caminho para ter um conjunto de casos de teste, já que - vamos ser sinceros - os casos de teste de regex ficam fáceis de executar depois que você constrói a estrutura.

Portanto, agora você tem um conjunto de condições de borda, alternativas e resultados esperados. E, de repente, os casos de teste são a documentação, conforme prometido em todas essas postagens do blog Agile também. Você apenas aponta para o FNG que, se a "melhoria" dele não passa nos casos de teste existentes, não há muita melhoria, é? E onde estão os novos casos de teste propostos que demonstram algum problema com o código original, que , como funciona, ele não precisa ser modificado, nunca !!!

Austin Hastings
fonte
3
o que é FNG? Isso não parece uma resposta ruim para mim, mas a definição falta para FNG (googlin para ele apenas resultados givesn que não estão relacionados, então talvez esta resposta foi apenas downvoted por causa da FNG?)
GameDeveloper
11
Eu suspeito que o Google o levou ao lugar certo. ;-) ( pt.wikipedia.org/wiki/FNG_syndrome )
Austin Hastings
A menos que você seja um gênio absoluto da programação, haverá programadores mais experientes considerando o que você faz como você olha para o novo cara. Você pode considerar ser mais humilde.
Thorbjørn Ravn Andersen