Software is becoming increasingly complex and there is a growing need for systemic strategies for testing and maintaining software. This course will examine the fundamentals of software testing and the main phases in the software testing process. Problems that arise from testing different types of software, such as object-oriented, component-based, concurrent, distributed, Graphical User Interfaces and web software will be discussed, and the relevant program analysis techniques used will be studied. Topics include, but are not limited to, a general overview of the software testing process, approaches to automatic test case generation, test oracles, coverage analysis to decide when to stop testing, test prioritization, mutation testing, and regression testing. In addition, students will gain hands-on experience with using popular software testing tools.