Organization of This Book
This book contains eleven chapters. The first three chapters are concerned primarily with testing concepts and the testing process. Chapters 4 through 10 detail techniques for various kinds of testing that can be done. Chapter 11 is a summary. Each chapter ends with a summary and a set of exercises. You are encouraged to read through the exercises and work on the ones that interest you or are relevant to your job as a tester. For most of the exercises, there are no correct answers, although for most of them some answers are better than others. We hope the exercises will be useful in helping you apply our techniques to your own project.
Chapter 1 (this chapter) provides an introduction to this book. We have presented an overview of testing concepts, a synopsis of how testing object-oriented software is different from testing other kinds of software, and a brief overview of our approach.
Chapter 2 describes the testing perspective. We adopt that perspective to address various aspects of the testing process, to review various products of the development process, and to examine the basic concepts of object-orientation.
Chapter 3 describes the testing process and how it relates to the development process. We view testing as being separate from development because in a sense they have competing goals. However, the two processes are intertwined.
Chapter 4 describes how to test models. A key element of successful development is to test early and test often. We favor testing analysis and design models since they are representations of the software. While this testing adds to the total project effort, the work done in the testing of models can be reused, refined, and extended to test code when it is developed.
Chapter 5 discusses testing classes that have fairly simple interfaces and implementations. Its primary focus is on the basic elements of testing classes. Class testing in an object-oriented context corresponds roughly to unit testing in a traditional context. The chapter's major emphasis is on identifying what must be tested in a class and how to test it. We present some ways to implement test drivers.
Chapter 6 expands the techniques developed in Chapter 5 to test classes whose specification and/or implementation requires interactions with other classes and/or objects. (This corresponds roughly to traditional integration testing in an object-oriented context.) Testing such classes can be quite challenging, especially in the presence of dynamic binding. We present techniques for managing the large number of test cases that could be developed.
Chapter 7 describes ways of testing classes in an inheritance hierarchy. The focus of our techniques is to reuse test driver code and reuse test cases to the extent possible. We provide an algorithm for determining the minimum amount of testing needed for subclasses that have already been tested. We also describe techniques for testing abstract classes.
Chapter 8 discusses testing concurrency. Concurrency is being used in the implementation of more and more systems through the use of threads and/or distributed computing.
Chapter 9 discusses the testing of systems. Testing a system developed using an object-oriented programming language is for the most part the same as testing a system developed using any other paradigm because system testing is normally based on a system's specification rather than its implementation. However, we have some advice and approaches in terms of adequacy.
Chapter 10 discusses various topics regarding testing components, frameworks, and product lines.
Chapter 11 briefly reviews the major points in earlier chapters and addresses the question, "Where do we go from here?"