Formal Approaches to Software Testing