Co jest uważane za najlepsze podejście do testu jednostkowego złożonej jednostki, takiej jak kompilator?Jednostka testująca kompilator
Przez lata napisałem kilka kompilatorów i interpretatorów i uważam, że ten rodzaj kodu jest dość trudny do przetestowania w dobry sposób.
Jeśli weźmiemy coś w rodzaju generowania abstrakcyjnego drzewa składniowego. jak byś przetestował to używając TDD?
Małe konstrukcje mogą być łatwe do przetestowania. np. coś w rodzaju:
string code = @"public class Foo {}";
AST ast = compiler.Parse(code);
Ponieważ to nie wygeneruje dużej ilości węzłów ast.
Ale jeśli rzeczywiście chcesz przetestować, że kompilator może wygenerować AST na coś takiego sposobu:
[TestMethod]
public void Can_parse_integer_instance_method_in_class()
{
string code = @"public class Foo { public int method(){ return 0;}}";
AST ast = compiler.Parse(code);
Co byś dochodzenia w sprawie? Ręczne definiowanie AST, które reprezentuje dany kod i stwierdzenie, że wygenerowany AST jest zgodny z ręcznie zdefiniowanym AST, wydaje się strasznie kłopotliwe, a nawet może być podatne na błędy.
Jaka jest najlepsza taktyka dla złożonych scenariuszy TDD?
To tylko jeden z wielu przykładów, dlaczego testy jednostkowe są bezużyteczne i gorsze, a nacisk należy położyć na testy integracyjne. TDD jest dla CRUD, a nie dla poważnych rzeczy. W przypadku kompilatorów losowe generowanie kodu jest zdecydowanie najlepszą możliwą metodą. Np .: http://www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf –
Możesz być także zainteresowany wyższym podejściem do bezpiecznej konstrukcji kompilatora: http://compcert.inria.fr/doc /index.html - formalna specyfikacja jest zdecydowanie lepszą gwarancją jakości niż jakiekolwiek możliwe testy. –
@peer, o jakich "metodach" mówisz? Jeśli generowany jest parser (pomyśl "bison" i podobne), będziesz miał monolityczną gramatykę i nieczytelny stos wygenerowanego kodu. Nic do przetestowania poza gramatyką jako całością. Jeśli jest to ręczny parser rekursywny, to jeszcze trudniej jest przeprowadzić test jednostkowy (zobacz, powiedzmy, kod źródłowy Clang i spróbuj wymyślić, jak wyśmiewać ASTContext i strumień wejściowy dla każdego małego wpisu parsera). Testowanie jednostkowe jest naprawdę bezcelowe w odniesieniu do każdego dość skomplikowanego kodu. –