Uważam, że jest to nieporozumienie w każdy możliwy sposób.
Kod testowy testujący kod produkcyjny wcale nie jest podobny. Pokażę w Pythonie:
def multiply(a, b):
"""Multiply ``a`` by ``b``"""
return a*b
Wtedy prosty test byłby:
def test_multiply():
assert multiply(4, 5) == 20
Obie funkcje mają podobną definicję, ale obie robią bardzo różne rzeczy. Tutaj nie ma duplikatu kodu. ;-)
Zdarza się również, że ludzie piszą zduplikowane testy, zasadniczo mając jedno stwierdzenie na funkcję testową. To jest szaleństwo i widziałem, jak ludzie to robią. To jest złą praktyką.
def test_multiply_1_and_3():
"""Assert that a multiplication of 1 and 3 is 3."""
assert multiply(1, 3) == 3
def test_multiply_1_and_7():
"""Assert that a multiplication of 1 and 7 is 7."""
assert multiply(1, 7) == 7
def test_multiply_3_and_4():
"""Assert that a multiplication of 3 and 4 is 12."""
assert multiply(3, 4) == 12
Wyobraź sobie, że robisz to dla ponad 1000 efektywnych wierszy kodu. Zamiast tego testujesz według „funkcji”:
def test_multiply_positive():
"""Assert that positive numbers can be multiplied."""
assert multiply(1, 3) == 3
assert multiply(1, 7) == 7
assert multiply(3, 4) == 12
def test_multiply_negative():
"""Assert that negative numbers can be multiplied."""
assert multiply(1, -3) == -3
assert multiply(-1, -7) == 7
assert multiply(-3, 4) == -12
Teraz, gdy funkcje są dodawane / usuwane, muszę jedynie rozważyć dodanie / usunięcie jednej funkcji testowej.
Być może zauważyłeś, że nie zastosowałem for
pętli. Jest tak, ponieważ powtarzanie niektórych rzeczy jest dobre. Gdybym zastosował pętle, kod byłby znacznie krótszy. Ale gdy asercja nie powiedzie się, może zaciemnić wyjście wyświetlając niejednoznaczny komunikat. Jeśli to nastąpi wtedy twoje testy będą mniej przydatne i będzie potrzebować debuggera aby sprawdzić, gdzie rzeczy nie udać.