Introdução
Tanto aqui como em outros lugares na web, existem toneladas de artigos promovendo testes automatizados em geral e testes de unidade em particular. Os artigos descrevem os benefícios do teste, usá-lo para eliminar código frágil, aumentar a qualidade, migrar de sistemas antigos para novos, refatoração. E, ao mesmo tempo, quase não há menção de suas deficiências em lugar nenhum, e não há "balas de prata" na engenharia!
Na verdade, existem "balas de prata", mas foram inventadas pelos primeiros engenheiros e são percebidas por nós como chatas banalidades: "lave as mãos antes de comer", "limpe os pés", "estruture o código", " não escreva sem indentação "," localize state ", etc. No entanto, os testes não são uma "bala de prata", mas uma das ferramentas mais eficazes e amplamente utilizadas, o que significa que tem desvantagens.
Neste post tentarei estruturar e anotar exatamente as deficiências dos testes, principalmente os testes de unidade. Vou tentar não escrever sobre o mérito, pois já existem tantos materiais sobre isso, é só esticar a mão. É claro que, em algum lugar, inevitavelmente esquecerei algo importante e em algum lugar exagerarei demais. Portanto, considere este artigo mais como um convite para conversar do que algo acabado. Do meu ponto de vista, o assunto está maduro e, portanto, gostaria muito de discuti-lo em detalhes.
Por que programação funcional? Portanto, testamos quase exclusivamente as funções.
Adeus às ilusões ou 33 banalidades
Em geral, não é segredo que mesmo 100% de cobertura de teste não garante o comportamento correto do programa. Por exemplo, vamos dar uma olhada no código:
def f( a, b):
x = 0
if a:
x += 2
else:
x += 0
if b:
x += 2
else:
x += 0
return x
#
assert f(True, False) == 2
assert f(False, True) == 2
Passamos por todos os ramos, está tudo bem, mas já provamos que a função f sempre retorna um dois?
, , 100% , , , , , . - - . - , "" .
property-base testing: QuickCheck Haskell, GAST Clean, Kotlintest, QCheck Ocaml, Hypothesis Python' . . , : , .
, -, , . Geant4 "" (), " " ( ) ( 5 , ).
, , - - . , 20 000 , , — 50 000 . , .
, property-based testing — , , . QuickCheck John Hughes — Building on developers' intuitions (...) | Lambda Days 19. , ...
, — : , , . , .
, , : ?
propertyDoubleEq :: Double -> bool
propertyDoubleEq x = (x == x)
, - - , , , .
2 + 2 = 5? ?
, , , . Jef239.
, - , , . - , , , copy-paste:
string monthName(unsigned int n) {
static vector<string> months = {"", "", ... };
return months[n % months.size()];
}
void testMonthNames() {
assert( monthName(0) == "");
...
}
, , "" . , , : , .
, - " ". , , , . , .
, , , . , , - !
, — , .
- —
, — , . , — , - , :
- . , - , "" , , .
- . , . , , , , .
- , , (. 1). , , . , !
, , , , . . , , , . , , .
- . , . , . -, , , .
— , .
, , - — , , .
- —
, , . , , .
- , , , . , , , , - . :
. , , — , .. . write-check-correct loop — , .
, Ocaml — , , - "" — () . -, , .
. - , - .
CI - - CI , - , . , , , PR .
, - -. , .
- —
, -, - , . , , , , . , , , , . - WindowMaker, Quake I, Heroes 2 , , . , TeX, , .
, -. , . , — " , ".
, - , , . , , - . This does not add business value, right?
, — , - - , , : . — , , Python 2 Python 3 Boost, . , !
: , , - . .
, "" — , , .
, . , . , , mutation testing, - .
, , - , , — , , , . , , . , , , - .
, - — , , . " – , , ".
" ", , , IDE , . , , - , . , , , , , . , , - , .
, , . , , . !