You are on page 1of 53

Introduction to Software Testing 2nd

Edition Paul Ammann


Visit to download the full and correct content document:
https://textbookfull.com/product/introduction-to-software-testing-2nd-edition-paul-amm
ann/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Introduction to Software Engineering 2nd Edition Ronald


J. Leach

https://textbookfull.com/product/introduction-to-software-
engineering-2nd-edition-ronald-j-leach/

Introduction to Software for Chemical Engineers 2nd


Edition Mariano Martín Martín (Editor)

https://textbookfull.com/product/introduction-to-software-for-
chemical-engineers-2nd-edition-mariano-martin-martin-editor/

Automotive Software Architectures An Introduction 2nd


2nd Edition Miroslaw Staron

https://textbookfull.com/product/automotive-software-
architectures-an-introduction-2nd-2nd-edition-miroslaw-staron/

Software Defined Networks A Comprehensive Approach 2nd


Edition Paul Göransson

https://textbookfull.com/product/software-defined-networks-a-
comprehensive-approach-2nd-edition-paul-goransson/
Automotive Software Architectures: An Introduction, 2nd
ed. 2nd Edition Miroslaw Staron

https://textbookfull.com/product/automotive-software-
architectures-an-introduction-2nd-ed-2nd-edition-miroslaw-staron/

Introduction to software engineering Second Edition


Leach

https://textbookfull.com/product/introduction-to-software-
engineering-second-edition-leach/

Introduction to Medical Software Foundations for


Digital Health Devices and Diagnostics 2nd Edition
Papademetris

https://textbookfull.com/product/introduction-to-medical-
software-foundations-for-digital-health-devices-and-
diagnostics-2nd-edition-papademetris/

Pragmatic Software Testing 1st Edition Rex Black

https://textbookfull.com/product/pragmatic-software-testing-1st-
edition-rex-black/

Engineering Software Products: An Introduction to


Modern Software Engineering 1st Edition Ian Sommerville

https://textbookfull.com/product/engineering-software-products-
an-introduction-to-modern-software-engineering-1st-edition-ian-
sommerville/
Introduction to Software Testing

This extensively classroom-tested text takes an innovative approach to


explaining software testing that defines it as the process of applying a few
precise, general-purpose criteria to a structure or model of the software.
The text incorporates cutting-edge developments, including techniques to
test modern types of software such as OO, web applications, and
embedded software. This revised second edition significantly expands
coverage of the basics, thoroughly discussing test automaton frameworks,
and adds new, improved examples and numerous exercises. Key features
include:
The theory of coverage criteria is carefully, cleanly explained to help
students understand concepts before delving into practical
applications.
Extensive use of the JUnit test framework gives students practical
experience in a test framework popular in industry.
Exercises feature specifically tailored tools that allow students to check
their own work.
Instructor’s manual, PowerPoint slides, testing tools for students, and
example software programs in Java are available from the book’s
website.

Paul Ammann is Associate Professor of Software Engineering at George


Mason University. He earned the Volgenau School’s Outstanding
Teaching Award in 2007. He led the development of the Applied
Computer Science degree, and has served as Director of the MS Software
Engineering program. He has taught courses in software testing, applied
object-oriented theory, formal methods for software engineering, web
software, and distributed software engineering. Ammann has published
more than eighty papers in software engineering, with an emphasis on
software testing, security, dependability, and software engineering
education.

Jeff Offutt is Professor of Software Engineering at George Mason


University. He leads the MS in Software Engineering program, teaches
software engineering courses at all levels, and developed new courses on
several software engineering subjects. He was awarded the George Mason
University Teaching Excellence Award, Teaching with Technology, in
2013. Offutt has published more than 165 papers in areas such as model-
based testing, criteria-based testing, test automaton, empirical software
engineering, and software maintenance. He is Editor-in-Chief of the
Journal of Software Testing, Verification and Reliability; helped found the
IEEE International Conference on Software Testing; and is the founder of
the μJava project.
INTRODUCTION TO
SOFTWARE
TESTING

Paul Ammann
George Mason University

Jeff Offutt
George Mason University
University Printing House, Cambridge CB2 8BS, United Kingdom One Liberty
Plaza, 20th Floor, New York, NY 10006, USA 477 Williamstown Road, Port
Melbourne, VIC 3207, Australia 4843/24, 2nd Floor, Ansari Road, Daryaganj,
Delhi – 110002, India 79 Anson Road, #06-04/06, Singapore 079906

Cambridge University Press is part of the University of Cambridge.

It furthers the University’s mission by disseminating knowledge in the pursuit of


education, learning, and research at the highest international levels of excellence.

www.cambridge.org
Information on this title: www.cambridge.org/9781107172012
DOI: 10.1017/9781316771273

© Paul Ammann and Jeff Offutt 2017

This publication is in copyright. Subject to statutory exception and to the


provisions of relevant collective licensing agreements, no reproduction of any part
may take place without the written permission of Cambridge University Press.

First published 2017

Printed in the United States of America by Sheridan Books, Inc.

A catalogue record for this publication is available from the British Library.

Library of Congress Cataloguing in Publication Data


Names: Ammann, Paul, 1961– author. — Offutt, Jeff, 1961– author.
Title: Introduction to software testing / Paul Ammann, George Mason
University, Jeff Offutt, George Mason University.
Description: Edition 2. — Cambridge, United Kingdom; New York, NY, USA:
Cambridge University Press, [2016]
Identifiers: LCCN 2016032808 — ISBN 9781107172012 (hardback)
Subjects: LCSH: Computer software–Testing.
Classification: LCC QA76.76.T48 A56 2016 — DDC 005.3028/7–dc23
LC record available at https://lccn.loc.gov/2016032808

ISBN 978-1-107-17201-2 Hardback

Additional resources for this publication at https://cs.gmu.edu/~offutt/softwaretest/.

Cambridge University Press has no responsibility for the persistence or accuracy of


URLs for external or third-party Internet Web sites referred to in this publication
and does not guarantee that any content on such Web sites is, or will remain,
accurate or appropriate.
Contents

List of Figures
List of Tables
Preface to the Second Edition

Part 1 Foundations

1 Why Do We Test Software?


1.1 When Software Goes Bad
1.2 Goals of Testing Software
1.3 Bibliographic Notes

2 Model-Driven Test Design


2.1 Software Testing Foundations
2.2 Software Testing Activities
2.3 Testing Levels Based on Software Activity
2.4 Coverage Criteria
2.5 Model-Driven Test Design
2.5.1 Test Design
2.5.2 Test Automation
2.5.3 Test Execution
2.5.4 Test Evaluation
2.5.5 Test Personnel and Abstraction
2.6 Why MDTD Matters
2.7 Bibliographic Notes

3 Test Automation
3.1 Software Testability
3.2 Components of a Test Case
3.3 A Test Automation Framework
3.3.1 The JUnit Test Framework
3.3.2 Data-Driven Tests
3.3.3 Adding Parameters to Unit Tests
3.3.4 JUnit from the Command Line
3.4 Beyond Test Automation
3.5 Bibliographic Notes

4 Putting Testing First


4.1 Taming the Cost-of-Change Curve
4.1.1 Is the Curve Really Tamed?
4.2 The Test Harness as Guardian
4.2.1 Continuous Integration
4.2.2 System Tests in Agile Methods
4.2.3 Adding Tests to Legacy Systems
4.2.4 Weaknesses in Agile Methods for Testing
4.3 Bibliographic Notes

5 Criteria-Based Test Design


5.1 Coverage Criteria Defined
5.2 Infeasibility and Subsumption
5.3 Advantages of Using Coverage Criteria
5.4 Next Up
5.5 Bibliographic Notes

Part 2 Coverage Criteria

6 Input Space Partitioning


6.1 Input Domain Modeling
6.1.1 Interface-Based Input Domain Modeling
6.1.2 Functionality-Based Input Domain Modeling
6.1.3 Designing Characteristics
6.1.4 Choosing Blocks and Values
6.1.5 Checking the Input Domain Model
6.2 Combination Strategies Criteria
6.3 Handling Constraints Among Characteristics
6.4 Extended Example: Deriving an IDM from JavaDoc
6.4.1 Tasks in Designing IDM-Based Tests
6.4.2 Designing IDM-Based Tests for Iterator
6.5 Bibliographic Notes

7 Graph Coverage
7.1 Overview
7.2 Graph Coverage Criteria
7.2.1 Structural Coverage Criteria
7.2.2 Touring, Sidetrips, and Detours
7.2.3 Data Flow Criteria
7.2.4 Subsumption Relationships Among Graph Coverage
Criteria
7.3 Graph Coverage for Source Code
7.3.1 Structural Graph Coverage for Source Code
7.3.2 Data Flow Graph Coverage for Source Code
7.4 Graph Coverage for Design Elements
7.4.1 Structural Graph Coverage for Design Elements
7.4.2 Data Flow Graph Coverage for Design Elements
7.5 Graph Coverage for Specifications
7.5.1 Testing Sequencing Constraints
7.5.2 Testing State Behavior of Software
7.6 Graph Coverage for Use Cases
7.6.1 Use Case Scenarios
7.7 Bibliographic Notes

8 Logic Coverage
8.1 Semantic Logic Coverage Criteria (Active)
8.1.1 Simple Logic Expression Coverage Criteria
8.1.2 Active Clause Coverage
8.1.3 Inactive Clause Coverage
8.1.4 Infeasibility and Subsumption
8.1.5 Making a Clause Determine a Predicate
8.1.6 Finding Satisfying Values
8.2 Syntactic Logic Coverage Criteria (DNF)
8.2.1 Implicant Coverage
8.2.2 Minimal DNF
8.2.3 The MUMCUT Coverage Criterion
8.2.4 Karnaugh Maps
8.3 Structural Logic Coverage of Programs
8.3.1 Satisfying Predicate Coverage
8.3.2 Satisfying Clause Coverage
8.3.3 Satisfying Active Clause Coverage
8.3.4 Predicate Transformation Issues
8.3.5 Side Effects in Predicates
8.4 Specification-Based Logic Coverage
8.5 Logic Coverage of Finite State Machines
8.6 Bibliographic Notes

9 Syntax-Based Testing
9.1 Syntax-Based Coverage Criteria
9.1.1 Grammar-Based Coverage Criteria
9.1.2 Mutation Testing
9.2 Program-Based Grammars
9.2.1 BNF Grammars for Compilers
9.2.2 Program-Based Mutation
9.3 Integration and Object-Oriented Testing
9.3.1 BNF Integration Testing
9.3.2 Integration Mutation
9.4 Specification-Based Grammars
9.4.1 BNF Grammars
9.4.2 Specification-Based Mutation
9.5 Input Space Grammars
9.5.1 BNF Grammars
9.5.2 Mutating Input Grammars
9.6 Bibliographic Notes

Part 3 Testing in Practice

10 Managing the Test Process


10.1 Overview
10.2 Requirements Analysis and Specification
10.3 System and Software Design
10.4 Intermediate Design
10.5 Detailed Design
10.6 Implementation
10.7 Integration
10.8 System Deployment
10.9 Operation and Maintenance
10.10 Implementing the Test Process
10.11 Bibliographic Notes

11 Writing Test Plans


11.1 Level Test Plan Example Template
11.2 Bibliographic Notes

12 Test Implementation
12.1 Integration Order
12.2 Test Doubles
12.2.1 Stubs and Mocks: Variations of Test Doubles
12.2.2 Using Test Doubles to Replace Components
12.3 Bibliographic Notes

13 Regression Testing for Evolving Software


13.1 Bibliographic Notes

14 Writing Effective Test Oracles


14.1 What Should Be Checked?
14.2 Determining Correct Values
14.2.1 Specification-Based Direct Verification of Outputs
14.2.2 Redundant Computations
14.2.3 Consistency Checks
14.2.4 Metamorphic Testing
14.3 Bibliographic Notes

List of Criteria
Bibliography
Index
Figures

1.1 Cost of late testing


2.1 Reachability, Infection, Propagation, Revealability (RIPR) model
2.2 Activities of test engineers
2.3 Software development activities and testing levels – the “V Model”
2.4 Model-driven test design
2.5 Example method, CFG, test requirements and test paths
3.1 Calc class example and JUnit test
3.2 Minimum element class
3.3 First three JUnit tests for Min class
3.4 Remaining JUnit test methods for Min class
3.5 Data-driven test class for Calc
3.6 JUnit Theory about sets
3.7 JUnit Theory data values
3.8 AllTests for the Min class example
4.1 Cost-of-change curve
4.2 The role of user stories in developing system (acceptance) tests
6.1 Partitioning of input domain D into three blocks
6.2 Subsumption relations among input space partitioning criteria
7.1 Graph (a) has a single initial node, graph (b) multiple initial nodes,
and graph (c) (rejected) with no initial nodes
7.2 Example of paths
7.3 A Single-Entry Single-Exit graph
7.4 Test case mappings to test paths
7.5 A set of test cases and corresponding test paths
7.6 A graph showing Node Coverage and Edge Coverage
7.7 Two graphs showing prime path coverage
7.8 Graph with a loop
7.9 Tours, sidetrips, and detours in graph coverage
7.10 An example for prime test paths
7.11 A graph showing variables, def sets and use sets
7.12 A graph showing an example of du-paths
7.13 Graph showing explicit def and use sets
7.14 Example of the differences among the three data flow coverage
criteria
7.15 Subsumption relations among graph coverage criteria
7.16 CFG fragment for the if-else structure
7.17 CFG fragment for the if structure without an else
7.18 CFG fragment for the if structure with a return
7.19 CFG fragment for the while loop structure
7.20 CFG fragment for the for loop structure
7.21 CFG fragment for the do-while structure
7.22 CFG fragment for the while loop with a break structure
7.23 CFG fragment for the case structure
7.24 CFG fragment for the try-catch structure
7.25 Method patternIndex() for data flow example
7.26 A simple call graph
7.27 A simple inheritance hierarchy
7.28 An inheritance hierarchy with objects instantiated
7.29 An example of parameter coupling
7.30 Coupling du-pairs
7.31 Last-defs and first-uses
7.32 Quadratic root program
7.33 Def-use pairs under intra-procedural and inter-procedural data flow
7.34 Def-use pairs in object-oriented software
7.35 Def-use pairs in web applications and other distributed software
7.36 Control flow graph using the File ADT
7.37 Elevator door open transition
7.38 Watch–Part A
7.39 Watch–Part B
7.40 An FSM representing Watch, based on control flow graphs of the
methods
7.41 An FSM representing Watch, based on the structure of thesoftware
7.42 An FSM representing Watch, based on modeling state variables
7.43 ATM actor and use cases
7.44 Activity graph for ATM withdraw funds
8.1 Subsumption relations among logic coverage criteria
8.2 Fault detection relationships
8.3 Thermostat class
8.4 PC true test for Thermostat class
8.5 CC test assignments for Thermostat class
8.6 Calendar method
8.7 FSM for a memory car seat–Nissan Maxima 2012
9.1 Method Min and six mutants
9.2 Mutation testing process
9.3 Partial truth table for (a ∧ b)
9.4 Finite state machine for SMV specification
9.5 Mutated finite state machine for SMV specification
9.6 Finite state machine for bank example
9.7 Finite state machine for bank example grammar
9.8 Simple XML message for books
9.9 XML schema for books
12.1 Test double example: Replacing a component
Tables

6.1 First partitioning of triang()’s inputs (interface-based)


6.2 Second partitioning of triang()’s inputs (interface-based)
6.3 Possible values for blocks in the second partitioning in Table 6.2
6.4 Geometric partitioning of triang()’s inputs (functionality-based)
6.5 Correct geometric partitioning of triang()’s inputs (functionality-
based)
6.6 Possible values for blocks in geometric partitioning in Table 6.5
6.7 Examples of invalid block combinations
6.8 Table A for Iterator example: Input parameters and
characteristics
6.9 Table B for Iterator example: Partitions and base case
6.10 Table C for Iterator example: Refined test requirements
6.11 Table A for Iterator example: Input parameters and
characteristics (revised)
6.12 Table C for Iterator example: Refined test requirements
(revised)
7.1 Defs and uses at each node in the CFG for patternIndex()
7.2 Defs and uses at each edge in the CFG for patternIndex()
7.3 du-path sets for each variable in patternIndex()
7.4 Test paths to satisfy all du-paths coverage on patternIndex()
7.5 Test paths and du-paths covered in patternIndex()
8.1 DNF fault classes
8.2 Reachability for Thermostat predicates
8.3 Clauses in the Thermostat predicate on lines 28-30
8.4 Correlated active clause coverage for Thermostat
8.5 Correlated active clause coverage for cal() preconditions
8.6 Predicates from memory seat example
9.1 Java’s access levels
10.1 Testing objectives and activities during requirements analysis and
specification
10.2 Testing objectives and activities during system and software design
10.3 Testing objectives and activities during intermediate design
10.4 Testing objectives and activities during detailed design
10.5 Testing objectives and activities during implementation
10.6 Testing objectives and activities during integration
10.7 Testing objectives and activities during system deployment
10.8 Testing objectives and activities during operation and maintenance
Preface to the Second Edition

Much has changed in the field of testing in the eight years since the first
edition was published. High-quality testing is now more common in
industry. Test automation is now ubiquitous, and almost assumed in large
segments of the industry. Agile processes and test-driven development are
now widely known and used. Many more colleges offer courses on
software testing, both at the undergraduate and graduate levels. The ACM
curriculum guidelines for software engineering include software testing in
several places, including as a strongly recommended course [Ardis et al.,
2015].
The second edition of Introduction to Software Testing incorporates new
features and material, yet retains the structure, philosophy, and online
resources that have been so popular among the hundreds of teachers who
haveused the book.

What is new about the second edition?

The first thing any instructor has to do when presented with a new edition
of a book is analyze what must be changed in the course. Since we have
been in that situation many times, we want to make it as easy as possible
for our audience. We start with a chapter-to-chapter mapping.

First Second
Topic
Edition Edition
Part I: Foundations
Why do we test software?
Chapter 01 (motivation)
Chapter 02 Model-driven test design
Chapter 1 Chapter 03 (abstraction)
Chapter 04 Test automation (JUnit)
Chapter 05 Putting testing first (TDD)
Criteria-based test design (criteria)
Part II: Coverage Criteria
Chapter 2 Chapter 07 Graph coverage
Chapter 3 Chapter 08 Logic coverage
Chapter 4 Chapter 09 Syntax-based testing
Chapter 5 Chapter 06 Input space partitioning
Part III: Testing in Practice
Managing the test process
Chapter 10
Writing test plans
Chapter 11
Test implementation
Chapter 6 Chapter 12
Regression testing for evolving
Chapter 13
software
Chapter 14
Writing effective test oracles
Chapter 7 N/A Technologies
Chapter 8 N/A Tools
Chapter 9 N/A Challenges

The most obvious, and largest change, is that the introductory chapter 1
from the first edition has been expanded into five separate chapters. This is
a significant expansion that we believe makes the book much better. The
new part 1 grew out of our lectures. After the first edition came out, we
started adding more foundational material to our testing courses. These
new ideas were eventually reorganized into five new chapters. The new
chapter 011 has much of the material from the first edition chapter 1,
including motivation and basic definitions. It closes with a discussion of
the cost of late testing, taken from the 2002 RTI report that is cited in
every software testing research proposal. After completing the first edition,
we realized that the key novel feature of the book, viewing test design as
an abstract activity that is independent of the software artifact being used
to design the tests, implied a completely different process. This led to
chapter 02, which suggests how test criteria can fit into practice. Through
our consulting, we have helped software companies modify their test
processes to incorporate this model.
A flaw with the first edition was that it did not mention JUnit or other
test automation frameworks. In 2016, JUnit is used very widely in
industry, and is commonly used in CS1 and CS2 classes for automated
grading. Chapter 03 rectifies this oversight by discussing test automation
in general, the concepts that make test automation difficult, and explicitly
teaches JUnit. Although the book is largely technology-neutral, having a
consistent test framework throughout the book helps with examples and
exercises. In our classes, we usually require tests to be automated and
often ask students to try other “*-Unit” frameworks such as HttpUnit as
homework exercises. We believe that test organizations cannot be ready to
apply test criteria successfully before they have automated their tests.
Chapter 04 goes to the natural next step of test-driven development.
Although TDD is a different take on testing than the rest of the book, it’s
an exciting topic for test educators and researchers precisely because it
puts testing front and center—the tests become the requirements. Finally,
chapter 05 introduces the concept of test criteria in an abstract way. The
jelly bean example (which our students love, especially when we share), is
still there, as are concepts such as subsumption.
Part 2, which is the heart of the book, has changed the least for the
second edition. In 2014, Jeff asked Paul a very simple question: “Why are
the four chapters in part 2 in that order?” The answer was stunned silence,
as we realized that we had never asked which order they should appear in.
It turns out that the RIPR model, which is certainly central to software
testing, dictates a logical order. Specifically, input space partitioning does
not require reachability, infection, or propagation. Graph coverage criteria
require execution to “get to” some location in the software artifact under
test, that is, reachability, but not infection or propagation. Logic coverage
criteria require that a predicate not only be reached, but be exercised in a
particular way to affect the result of the predicate. That is, the predicate
must be infected. Finally, syntax coverage not only requires that a location
be reached, and that the program state of the “mutated” version be
different from the original version, but that difference must be visible after
execution finishes. That is, it must propagate. The second edition orders
these four concepts based on the RIPR model, where each chapter now has
successively stronger requirements. From a practical perspective, all we
did was move the previous chapter 5 (now chapter 06) in front of the graph
chapter (now chapter 07).
Another major structural change is that the second edition does not
include chapters 7 through 9 from the first edition. The first edition
material has become dated. Because it is used less than other material in
the book, we decided not to delay this new edition of the book while we
tried to find time to write this material. We plan to include better versions
of these chapters in a third edition.
We also made hundreds of changes at a more detailed level. Recent
research has found that in addition to an incorrect value propagating to the
output, testing only succeeds if our automated test oracle looks at the right
part of the software output. That is, the test oracle must reveal the failure.
Thus, the old RIP model is now the RIPR model. Several places in the
book have discussions that go beyond or into more depth than is strictly
needed. The second edition now includes “meta discussions,” which are
ancillary discussions that can be interesting or insightful to some students,
but unnecessarily complicated for others.
The new chapter 06 now has a fully worked out example of deriving an
input domain model from a widely used Java library interface (in section
06.4). Our students have found this helps them understand how to use the
input space partitioning techniques. The first edition included a section on
“Representing graphs algebraically.” Although one of us found this
material to be fun, we both found it hard to motivate and unlikely to be
used in practice. It also has some subtle technical flaws. Thus, we removed
this section from the second edition. The new chapter 08 (logic) has a
significant structural modification. The DNF criteria (formerly in section
3.6) properly belong at the front of the chapter. Chapter 08 now starts with
semantic logic criteria (ACC and ICC) in 08.1, then proceeds to syntactic
logic criteria (DNF) in 08.2. The syntactic logic criteria have also changed.
One was dropped (UTPC), and CUTPNFP has been joined by MUTP and
MNFP. Together, these three criteria comprise MUMCUT.
Throughout the book (especially part 2), we have improved the
examples, simplified definitions, and included more exercises. When the
first edition was published we had a partial solution manual, which
somehow took five years to complete. We are proud to say that we learned
from that mistake: we made (and stuck by!) a rule that we couldn’t add an
exercise without also adding a solution. The reader might think of this rule
as testing for exercises. We are glad to say that the second edition book
website debuts with a complete solution manual.
The second edition also has many dozens of corrections (starting with
the errata list from the first edition book website), but including many
more that we found while preparing the second edition. The second edition
also has a better index. We put together the index for the first edition in
about a day, and it showed. This time we have been indexing as we write,
and committed time near the end of the process to specifically focus on the
index. For future book writers, indexing is hard work and not easy to turn
over to a non-author!

What is still the same in the second edition?

The things that have stayed the same are those that were successful in the
first edition. The overall observation that test criteria are based on only
four types of structures is still the key organizing principle of the second
edition. The second edition is also written from an engineering viewpoint,
assuming that users of the book are engineers who want to produce the
highest quality software with the lowest possible cost. The concepts are
well grounded in theory, yet presented in a practical manner. That is, the
book tries to make theory meet practice; the theory is sound according to
the research literature, but we also show how the theory applies in practice.
The book is also written as a text book, with clear explanations, simple
but illustrative examples, and lots of exercises suitable for in-class or out-
of-class work. Each chapter ends with bibliographic notes so that
beginning research students can proceed to learning the deeper ideas
involved in software testing. The book website
(https://cs.gmu.edu/~offutt/softwaretest/) is rich in materials with solution
manuals, listings of all example programs in the text, high quality
PowerPoint slides, and software to help students with graph coverage,
logic coverage, and mutation analysis. Some explanatory videos are also
available and we hope more will follow. The solution manual comes in
two flavors. The student solution manual, with solutions to about half the
exercises, is available to everyone. The instructor solution manual has
solutions to all exercises and is only available to those who convince the
authors that they are using a book to teach a course.

Using the book in the classroom

The book chapters are built in a modular, component-based manner. Most


chapters are independent, and although they are presented in the order that
we use them, inter-chapter dependencies are few and they could be used in
almost any order. Our primary target courses at our university are a fourth-
year course (SWE 437) and a first-year graduate course (SWE 637).
Interested readers can search on those courses (“mason swe 437” or
“mason swe 637”) to see our schedules and how we use the book. Both
courses are required; SWE 437 is required in the software engineering
concentration in our Applied Computer Science major, and SWE 637 is
required in our MS program in software engineering2. Chapters 01 and 03
can be used in an early course such as CS2 in two ways. First, to sensitize
early students to the importance of software quality, and second to get
them started with test automation (we use JUnit at Mason). A second-year
course in testing could cover all of part 1, chapter 06 from part 2, and all or
part of part 3. The other chapters in part 2 are probably more than what
such students need, but input space partitioning is a very accessible
introduction to structured, high-end testing. A common course in north
American computer science programs is a third-year course on general
software engineering. Part 1 would be very appropriate for such a course.
In 2016 we are introducing an advanced graduate course on software
testing, which will span cutting-edge knowledge and current research. This
course will use some of part 3, the material that we are currently
developing for part 4, and selected research papers.

Teaching software testing

Both authors have become students of teaching over the past decade. In the
early 2000s, we ran fairly traditional classrooms. We lectured for most of
the available class time, kept organized with extensive PowerPoint slides,
required homework assignments to be completed individually, and gave
challenging, high-pressure exams. The PowerPoint slides and exercises in
the first edition were designed for this model.
However, our teaching has evolved. We replaced our midterm exam
with weekly quizzes, given in the first 15 minutes of class. This distributed
a large component of the grade through the semester, relieved much of the
stress of midterms, encouraged the students to keep up on a weekly basis
instead of cramming right before the exam, and helped us identify students
who were succeeding or struggling early in the term.
After learning about the “flipped classroom” model, we experimented
with recorded lectures, viewed online, followed by doing the “homework”
assignments in class with us available for immediate help. We found this
particularly helpful with the more mathematically sophisticated material
such as logic coverage, and especially beneficial to struggling students. As
the educational research evidence against the benefits of lectures has
mounted, we have been moving away from the “sage on a stage” model of
talking for two hours straight. We now often talk for 10 to 20 minutes,
then give in-class exercises3 where the students immediately try to solve
problems or answer questions. We confess that this is difficult for us,
because we love to talk! Or, instead of showing an example during our
lecture, we introduce the example, let the students work the next step in
small groups, and then share the results. Sometimes our solutions are
better, sometimes theirs are better, and sometimes solutions differ in
interesting ways that spur discussion.
There is no doubt that this approach to teaching takes time and cannot
acccomodate all of the PowerPoint slides we have developed. We believe
that although we cover less material, we uncover more, a perception
consistent with how our students perform on our final exams.
Most of the in-class exercises are done in small groups. We also
encourage students to work out-of-class assignments collaboratively. Not
only does evidence show that students learn more when they work
collaboratively (“peer-learning”), they enjoy it more, and it matches the
industrial reality. Very few software engineers work alone.
Of course, you can use this book in your class as you see fit. We offer
these insights simply as examples for things that work for us. We
summarize our current philosophy of teaching simply: Less talking, more
teaching.

Acknowledgments

It is our pleasure to acknowledge by name the many contributers to this


text. We begin with students at George Mason who provided excellent
feedback on early draft chapters from the second edition: Firass Almiski,
Natalia Anpilova, Khalid Bargqdle, Mathew Fadoul, Mark Feghali,
Angelica Garcia, Mahmoud Hammad, Husam Hilal, Carolyn Koerner,
Han-Tsung Liu, Charon Lu, Brian Mitchell, Tuan Nguyen, Bill Shelton,
Dzung Tran, Dzung Tray, Sam Tryon, Jing Wu, Zhonghua Xi, and Chris
Yeung.
We are particularly grateful to colleagues who used draft chapters of the
second edition. These early adopters provided valuable feedback that was
extremely helpful in making the final document classroom-ready. Thanks
to: Moataz Ahmed, King Fahd University of Petroleum & Minerals; Jeff
Carver, University of Alabama; Richard Carver, George Mason
University; Jens Hannemann, Kentucky State University; Jane Hayes,
University of Kentucky; Kathleen Keogh, Federation University Australia;
Robyn Lutz, Iowa State University; Upsorn Praphamontripong, George
Mason University; Alper Sen, Bogazici University; Marjan Sirjani,
Reykjavik University; Mary Lou Soffa, University of Virginia; Katie
Stolee, North Carolina State University; and Xiaohong Wang, Salisbury
University.
Several colleagues provided exceptional feedback from the first edition:
Andy Brooks, Mark Hampton, Jian Zhou, Jeff (Yu) Lei, and six
anonymous reviewers contacted by our publisher. The following
individuals corrected, and in some cases developed, exercise solutions:
Sana’a Alshdefat, Yasmine Badr, Jim Bowring, Steven Dastvan, Justin
Donnelly, Martin Gebert, JingJing Gu, Jane Hayes, Rama Kesavan,
Ignacio Martín, Maricel Medina-Mora, Xin Meng, Beth Paredes, Matt
Rutherford, Farida Sabry, Aya Salah, Hooman Safaee, Preetham
Vemasani, and Greg Williams. The following George Mason students
found, and often corrected, errors in the first edition: Arif Al-Mashhadani,
Yousuf Ashparie, Parag Bhagwat, Firdu Bati, Andrew Hollingsworth,
Gary Kaminski, Rama Kesavan, Steve Kinder, John Krause, Jae Hyuk
Kwak, Nan Li, Mohita Mathur, Maricel Medina Mora, Upsorn
Praphamontripong, Rowland Pitts, Mark Pumphrey, Mark Shapiro, Bill
Shelton, David Sracic, Jose Torres, Preetham Vemasani, Shuang Wang,
Lance Witkowski, Leonard S. Woody III, and Yanyan Zhu. The following
individuals from elsewhere found, and often corrected, errors in the first
edition: Sana’a Alshdefat, Alexandre Bartel, Don Braffitt, Andrew Brooks,
Josh Dehlinger, Gordon Fraser, Rob Fredericks, Weiyi Li, Hassan Mirian,
Alan Moraes, Miika Nurminen, Thomas Reinbacher, Hooman Rafat
Safaee, Hossein Saiedian, Aya Salah, and Markku Sakkinen. Lian Yu of
Peking University translated the the first edition into Mandarin Chinese.
We also want to acknowledge those who implicitly contributed to the
second edition by explicitly contributing to the first edition: Aynur
Abdurazik, Muhammad Abdulla, Roger Alexander, Lionel Briand, Renee
Bryce, GeorgeP. Burdell, Guillermo Calderon-Meza, Jyothi Chinman,
Yuquin Ding, Blaine Donley, Patrick Emery, Brian Geary, Hassan Gomaa,
Mats Grindal, Becky Hartley, Jane Hayes, Mark Hinkle, Justin
Hollingsworth, Hong Huang, Gary Kaminski, John King, Yuelan Li, Ling
Liu, Xiaojuan Liu, Chris Magrin, Darko Marinov, Robert Nilsson, Andrew
J. Offutt, Buzz Pioso, Jyothi Reddy, Arthur Reyes, Raimi Rufai, Bo
Sanden, Jeremy Schneider, Bill Shelton, Michael Shin, Frank Shukis, Greg
Williams, Quansheng Xiao, Tao Xie, Wuzhi Xu, and Linzhen Xue.
While developing the second edition, our graduate teaching assistants at
George Mason gave us fantastic feedback on early drafts of chapters: Lin
Deng, Jingjing Gu, Nan Li, and Upsorn Praphamontripong. In particular,
Nan Li and Lin Deng were instrumental in completing, evolving, and
maintaining the software coverage tools available on the book website.
We are grateful to our editor, Lauren Cowles, for providing unwavering
support and enforcing the occasional deadline to move the project along,
as well as Heather Bergmann, our former editor, for her strong support on
this long-running project.
Finally, of course none of this is possible without the support of our
families. Thanks to Becky, Jian, Steffi, Matt, Joyce, and Andrew for
helping us stay balanced.
Just as all programs contain faults, all texts contain errors. Our text is no
different. And, as responsibility for software faults rests with the
developers, responsibility for errors in this text rests with us, the authors.
In particular, the bibliographic notes sections reflect our perspective of the
testing field, a body of work we readily acknowledge as large and
complex. We apologize in advance for omissions, and invite pointers to
relevant citations.

1 To help reduce confusion, we developed the convention of using two digits for
second edition chapters. Thus, in this preface,chapter 01 implies the second
edition, whereas chapter 1 implies the first.
2 Our MS program is practical in nature, not research-oriented. The majority of
students are part-time students with five to tenyears of experience in the software
industry. SWE 637 begat this book when we realized Beizer’s classic text
[Beizer, 1990] was out ofprint.
3 These in-class exercises are not yet a formal part of the book website. But we
often draw them from regular exercises in the text. Interested readers can extract
recent versions from our course web pages with a search engine.
PART I

Foundations
1

Why Do We Test Software?

The true subject matter of the tester is not testing, but the design of test cases.

The purpose of this book is to teach software engineers how to test. This
knowledge is useful whether you are a programmer who needs to unit test
your own software, a full-time tester who works mostly from requirements
at the user level, a manager in charge of testing or development, or any
position in between. As the software industry moves into the second
decade of the 21st century, software quality is increasingly becoming
essential to all businesses and knowledge of software testing is becoming
necessary for all software engineers.
Today, software defines behaviors that our civilization depends on in
systems such as network routers, financial calculation engines, switching
networks, the Web, power grids, transportation systems, and essential
communications, command, and control services. Over the past two
decades, the software industry has become much bigger, is more
competitive, and has more users. Software is an essential component of
exotic embedded applications such as airplanes, spaceships, and air traffic
control systems, as well as mundane appliances such as watches, ovens,
cars, DVD players, garage door openers, mobile phones, and remote
controllers. Modern households have hundreds of processors, and new cars
have over a thousand; all of them running software that optimistic
consumers assume will never fail! Although many factors affect the
engineering of reliable software, including, of course, careful design and
sound process management, testing is the primary way industry evaluates
software during development. The recent growth in agile processes puts
increased pressure on testing; unit testing is emphasized heavily and test-
driven development makes tests key to functional requirements. It is clear
that industry is deep into a revolution in what testing means to the success
of software products.
Fortunately, a few basic software testing concepts can be used to design
tests for a large variety of software applications. A goal of this book is to
present these concepts in such a way that students and practicing engineers
can easily apply them to any software testing situation.
This textbook differs from other software testing books in several
respects. The most important difference is in how it views testing
techniques. In his landmark book Software Testing Techniques, Beizer
wrote that testing is simple—all a tester needs to do is “find a graph and
cover it.” Thanks to Beizer’s insight, it became evident to us that the
myriad of testing techniques present in the literature have much more in
common than is obvious at first glance. Testing techniques are typically
presented in the context of a particular software artifact (for example, a
requirements document or code) or a particular phase of the lifecycle (for
example, requirements analysis or implementation). Unfortunately, such a
presentation obscures underlying similarities among techniques.
This book clarifies these similarities with two innovative, yet
simplifying, approaches. First, we show how testing is more efficient and
effective by using a classical engineering approach. Instead of designing
and developing tests on concrete software artifacts like the source code or
requirements, we show how to develop abstraction models, design tests at
the abstract level, and then implement actualtests at the concrete level by
satisfying the abstract designs. This is the exact process that traditional
engineers use, except whereas they usually use calculus and algebra to
describe the abstract models, software engineers usually use discrete
mathematics. Second, we recognize that all test criteria can be defined
with a very short list of abstract models: input domain characterizations,
graphs, logical expressions, and syntactic descriptions. These are directly
reflected in the four chapters of Part II of this book.
This book provides a balance of theory and practical application,
thereby presenting testing as a collection of objective, quantitative
activities that can be measured and repeated. The theory is based on the
published literature, and presented without excessive formalism. Most
importantly, the theoretical concepts are presented when needed to support
the practical activities that test engineers follow. That is, this book is
intended for all software developers.
1.1 WHEN SOFTWARE GOES BAD

As said, we consider the development of software to be engineering. And


like any engineering discipline, the software industry has its shares of
failures, some spectacular, some mundane, some costly, and sadly, some
that have resulted in loss of life. Before learning about software disasters,
it is important to understand the difference between faults, errors, and
failures. We adopt the definitions of software fault, error, and failure from
the dependability community.

Definition 1.1 Software Fault: A static defect in the software.

Definition 1.2 Software Error: An incorrect internal state that is the


manifestation of some fault.

Definition 1.3 Software Failure: External, incorrect behavior with


respect to the requirements or another description of the expected
behavior.

Consider a medical doctor diagnosing a patient. The patient enters the


doctor’s office with a list of failures (that is, symptoms). The doctor then
must discover the fault, or root cause of the symptoms. To aid in the
diagnosis, a doctor may order tests that look for anomalous internal
conditions, such as high blood pressure, an irregular heartbeat, high levels
of blood glucose, or high cholesterol. In our terminology, these anomalous
internal conditions correspond to errors.
While this analogy may help the student clarify his or her thinking about
faults, errors, and failures, software testing and a doctor’s diagnosis differ
in one crucial way. Specifically, faults in software are design mistakes.
They do not appear spontaneously, but exist as a result of a decision by a
human. Medical problems (as well as faults in computer system hardware),
on the other hand, are often a result of physical degradation. This
distinction is important because it limits the extent to which any process
can hope to control software faults. Specifically, since no foolproof way
exists to catch arbitrary mistakes made by humans, we can never eliminate
all faults from software. In colloquial terms, we can make software
development foolproof, but we cannot, and should not attempt to, make it
damn-foolproof.
For a more precise example of the definitions of fault, error, and failure,
Another random document with
no related content on Scribd:
Mississippi river. We can now look across a gorge from the coaches
of the Pennsylvania Railroad, beyond Altoona, and see the grade of
the old Portage Railway.

Fig. 28. Broad Street Station, Philadelphia: Pennsylvania


Railroad
The canal almost put out of business the Conestoga wagons on
the dusty pike which had seen so much travel by way of Carlisle and
Bedford. But the people did not stop with a canal. Like the men of
New York, they wanted something even better than that. They
wished to have a railroad all the way, and in 1846 the Pennsylvania
Railroad Company was incorporated. By this time it was very well
known that railroads were successful both in America and in
England, and that steam was better than horses.
Over the Allegheny Front a route was found where the grades
were not too steep for locomotives. The grade, of course, had been
the one great hindrance to the whole project, and when this difficulty
was overcome there was no reason why passengers should not be
carried from Philadelphia to Pittsburg, or a load of iron from Pittsburg
to Philadelphia, without changing cars. In the year 1854 the
Pennsylvania people triumphed, for they had conquered the
mountains and could run trains from the banks of the Delaware to
the Ohio river.
If we leave Philadelphia by the great Broad street station of the
Pennsylvania Railroad, we shall pass out among the pleasant homes
of West Philadelphia and through the fine farms of the Pennsylvania
lowlands, until we come, in about an hour and a half, to the staid old
city of Lancaster. We have been here before, to learn of turnpikes
and Conestoga freighters.
The next stop, if we are on an express train, will be at
Harrisburg, a little more than a hundred miles from Philadelphia. We
have now come from the Delaware to the Susquehanna, and are
close to the mountains. Before we go in among them let us see
Harrisburg. It is a city of fifty thousand people, and lies along the
east bank of the Susquehanna, which here is a great river a mile
wide, having gathered its tribute of waters from hundreds of
branching streams in Pennsylvania and New York.

Fig. 29. Bridge, Pennsylvania Railroad, above Harrisburg


Not far to the east a small stream runs parallel to the main river,
and the larger part of Harrisburg is on higher ground between the
two. On the highest part of this ridge is the state capitol, a great
building but recently finished. Harrisburg is at the right point for the
state government. It is not in the center of the state, to be sure, but it
is at the rear of the lowlands which reach in from the sea, and is just
outside the great gateway where roads from all the northern,
western, and central uplands come out on the plain. It is a
convenient center for coal and iron, and hence one sees along the
river below the city many blast furnaces, rolling mills, and factories.
To the northeast rich, open lands stretch along the base of Blue
mountain, and railroads join Harrisburg to Reading, Allentown,
Bethlehem, and Easton. To the southwest bridges cross the
Susquehanna, and roads run to Carlisle, Hagerstown, and other
cities of the Great Valley (Chapter XI).
Thus the Pennsylvania Railroad, running northwest from
Philadelphia, crosses at Harrisburg other roads that run to the
southwest. As hamlets often gather about “four corners” in the
country, so cities grow up where the great roads of the world cross
each other.

Fig. 30. Pennsylvania


Railroad Shops, Altoona
Leaving Harrisburg behind, we pass the splendid new bridge of
the Pennsylvania Railroad, across the Susquehanna (Fig. 29), and
go through the gap in Blue mountain. Soon we turn away from the
main river and enter the winding valley of the Juniata. The grades
are easy, the roadbed is smooth, and by deep cuts through the rocks
the curves have been made less abrupt. It is only when one looks
out of the car window that the land is found to be rugged and
mountainous.
All the greater valleys and ridges of the mountain belt of
Pennsylvania run northeast and southwest. The last of these to be
crossed on our journey is Bald Eagle valley, from which the
Allegheny Front rises to the northwest.
In this valley, near the place where the Portage Railway began to
scale the heights, and a little more than a hundred miles from
Pittsburg, the Pennsylvania Railroad Company in 1850 founded a
town and called it Altoona. Here they started shops, which have now
grown to notable importance. The town became a city eighteen
years after it was begun, and has to-day about forty thousand
inhabitants. In the railway shops alone may be found nine thousand
men repairing and building locomotives, passenger coaches, and
freight cars. The Pennsylvania Railroad Company is now founding a
great school in Altoona, where young men may be taught to become
skillful and efficient in railway service.

Fig. 31. Horseshoe Curve, Pennsylvania Railroad


Altoona looks new, and with its endless freight yards, its noisy
shops, and its sooty cover of smoke from burning soft coal, it is very
different from quiet Lancaster, which was old when forests covered
the site of Altoona.
On our way to Pittsburg we are soon pulling up the Allegheny
Front by a great loop, or bend, which enables the tracks to reach the
summit more than a thousand feet above Altoona. Nestling within the
great bend is a reservoir of water to supply the houses and shops of
the city lying below. Passing the highest point, we find ourselves
descending the valley of the Conemaugh river to Johnstown, and
surrounded by the high lands of the Allegheny plateau.
Johnstown is much older than Altoona, for it was settled in 1791,
but it has not grown so fast, and has only about as many inhabitants
as the city of railroad shops. Most people know of Johnstown
because of the flood which ruined the place in 1889. Several miles
above the town was a reservoir more than two miles long and in
several places one hundred feet deep. After the heavy rains of that
spring the dam broke on the last day of May, and the wild rush of
waters destroyed the town. Homes, stores, shops, and mills were
torn away and carried down the river. Clara Barton of the Red Cross,
who went to Johnstown as soon as she could get there, says that the
few houses that were not crushed and strewn along the valley were
turned upside down.
More than two thousand men, women, and children lost their
lives, and those that were left were in mourning and poverty. The
whole land sent in its gifts of money, clothing, and food, and the town
was built up again into a prosperous city. Near the city are found
coal, iron, limestone, and fire clay, and these things make it easy to
establish iron works. The Cambria Steel Company gives work to ten
thousand men in its shops, mines, and furnaces.
The main line of the Pennsylvania Railroad runs down the
rugged Conemaugh valley through Johnstown, and is its chief
means of traffic. As we go on to the west we near Pittsburg, but first
we pass through a number of stirring towns. At one place fire bricks
are made, and the clay for molding them and the coal for burning
them are found in the same hill. In another town there are coal mines
and glass works. Farther west the Pennsylvania road has more
repair shops, and Braddock is the great Carnegie town. We shall see
why many thriving young cities have grown up in this region when
we take up Pittsburg, about which they are all clustered.
At Pittsburg we pull into one of the finest railway stations in the
United States. We may stop in the city of coal and iron, or we may
go on to the west, over one of the main arms of the Pennsylvania
Railroad system. If we take the northern branch, it will carry us
across Ohio to Fort Wayne in Indiana and to Chicago. If we board a
train on the southern arm, we shall go through Columbus and
Indianapolis, and be set down on the farther side of the Mississippi
river at St. Louis.
North and south from the great east and west trunk lines run
many shorter roads, or “spurs.” On the east there is a network of
short roads in New Jersey, and one of the busiest parts of the whole
system is that which joins Washington to Baltimore, Philadelphia,
and New York.
Fig. 32. Rock Cut, along the Line of the Pennsylvania
Railroad
West from Philadelphia for a long distance there are four tracks,
and on either side may be seen neat hedges, such as one finds
along the railways of England. In the mountains it is often hard to
make a roadbed wide enough for four tracks, and hence there may
be only three or even two in some places. No doubt four will in time
be built through to Pittsburg, for many millions of dollars are spent in
improving the road. Instead of having a long circuit around the hills,
tunnels and vast cuts in the bed rock are made so as to straighten
the line. Thus both passenger and freight trains are able to make
better time, and the road can carry the stores of iron and coal which
are found in the lands on either side.
Some of the freight yards are always crowded with cars, and at
Harrisburg the company is building separate tracks around the city,
so that through freight trains need not be delayed.
At New York the Pennsylvania Railroad now has its station on
the New Jersey side of the Hudson river, but it is building a tunnel
under the river. The company has already bought several city blocks
and has torn away the buildings. Here it will build one of the greatest
passenger stations in the world. The tunnel will run on to the east,
under the streets and shops of Manhattan, and under the East river.
Thus under New York and its surrounding waters trains can go to the
east end of Long Island.
Pennsylvania has told us the same story that we learned from
New York. We read it again: first, how the Indian’s path was beaten
deeper and wider by the hoofs of the pack horse, bearing goods to
sell and barter in the wilderness; then how strips of forest were cut
down to make room for the Conestoga wagons and the gay stages
that swept through from Philadelphia to Pittsburg. These in their turn
became old-fashioned when the canal and Portage Railway were
done, and now we sit in a car that is like a palace, and think canals
and Conestogas very old stories indeed. In future generations swift
air ships may take the wonder away from the Empire State Express,
and make us listen unmoved when a man, standing in the station at
Philadelphia, calls the limited train for Pittsburg, Cincinnati, and St.
Louis.
CHAPTER VIII
THE NATIONAL ROAD

The sea reaches inland almost to the northeast corner of the


state of Maryland. This long, wide arm of the ocean receives many
rivers and is known as Chesapeake bay. Near its north end is
Baltimore, one of the four great cities of our Atlantic coast. It is one
hundred and fifty miles from the open sea. If, instead of sailing up
the bay, we should turn toward the west, we could go up the
Potomac river, which is deep and wide. On our way we should pass
Washington’s estates at Mount Vernon, the old city of Alexandria,
and the national capital, Washington. We could not sail much farther
because there are falls in the Potomac which ships cannot pass. The
Potomac runs so close to Chesapeake bay that it is only forty miles
from Washington across to Baltimore.
Chesapeake bay is much like Delaware bay and the tidal
Hudson river, only it is larger than either. Baltimore is at a greater
distance from the open sea than Philadelphia is, and Philadelphia is
farther inland than New York, but each of these cities tried to get as
much of the western trade as it could.
The natural way for the men of Baltimore and Alexandria to go
across to the west was up the Potomac river and through its passes
in the mountains. But before they tried this they had settled much of
the low, flat land along the Potomac and about the Chesapeake in
Virginia and Maryland. This was often called “tide-water country,”
because the beds of the rivers are below sea level, and the streams
are deep enough for boats of some size.
Fig. 33. Tollhouse West of Brownsville, Pennsylvania
When the land was first settled and the colonists found that they
could go almost everywhere by boat, they paid small heed to making
roads. They could visit their neighbors on other plantations and they
could load their tobacco and take it to market by the rivers. Many
plantations were beside rivers of such great depth that sailing
vessels bound for London could come up to the farmer’s wharf and
get his crop of tobacco.
In early days the members of the legislature were not always
given so much per mile to pay the stage fares between their homes
and the capital, but they were allowed the cost of hiring boats
instead. Many ferries were needed, and laws about them were made
before rules were laid down for bridges and roads. Several
lawmakers at one time would have been fined for their absence from
the legislature of the colony had they not been excused because
there was no ferry to carry them over the river which they would
have had to cross.
Around Annapolis “rolling roads” were made. These were wide
paths made as smooth as possible, in order that large hogsheads of
tobacco might be rolled, each by two men, to the market in that old
town.
After a time the lowlands of the coast region began to fill up and
the people were pushing westward, just as they did in Pennsylvania
and New York. No man had so great a part in this westward
movement as the young surveyor, George Washington. In 1748 he
was sixteen years old, a tall, strong lad, full of courage and energy.
Lord William Fairfax, a rich English gentleman who had settled in
Virginia, had bought great tracts of forest land up the Potomac
behind the Blue Ridge mountains, and he was eager to have them
surveyed. Knowing that Washington had studied surveying, Fairfax
asked him to undertake the task. The boy consented; he went
beyond the Blue Ridge into the country along the Shenandoah,
camped in the woods, swam the rivers, toughened his muscles,
learned the ways of the red men, and three years later came back, a
grown man, ready for great things.
While Washington was getting his practice as a surveyor the
Ohio Company was formed to take up lands along the Ohio river,
and to keep the French from settling there. Lawrence, Washington’s
elder brother, was one of the chief men of this company. In 1753
Washington himself went west to the Ohio river. Day by day the
French were taking a firmer hold of that country, and Dinwiddie, the
old Scottish governor of Virginia, looked about for some one to carry
a warning letter to the commander of one of their new forts. The
messenger was also to keep his eyes open and report what the
French were doing on the upper waters of the Ohio. He chose
Washington, saying, “Faith, you’re a brave lad, and, if you play your
cards well, you shall have no cause to repent your bargain.”
Washington did not wait, but left on the day he received his
commission, late in October, 1753.
Christopher Gist, a famous frontiersman, was secured as guide,
and we can have no doubt that he and Washington formed a team,
ready to meet Frenchmen, red men, and the dangers of river and
forest. They made up their little party where the city of Cumberland,
Maryland, now stands. It is far up the Potomac, in the heart of the
mountains,—a long way beyond the Blue Ridge and the lands where
Washington had been surveying.
At this place a large stream called Wills creek cuts through one
of the mountain ridges by a deep gorge and enters the Potomac. On
a hill, where these streams come together, was Fort Cumberland,
the great outpost of Virginia and Maryland. A fine church now stands
on the ground of the old fort, in the heart of the busy city of
Cumberland. This was the starting point for Washington’s expedition
and for many later ones into the western wilderness.
Washington made his dangerous journey with success. He
brought back a letter from the French commander, but of much
greater value was the story of all that he had seen. The colonists
now knew just what they would have to do to keep possession of the
Ohio lands.
It was not long before Washington went again as commanding
officer of a small army, and in 1755 he served under General
Braddock in the famous battle which resulted in the defeat of the
English and the death of their general. Washington, as we know,
brought off the troops with honor to himself. In each of these
expeditions something was done toward cutting away the trees and
grading a road from Fort Cumberland to the head of the Ohio river at
Pittsburg.
Fig. 34. Milestone on the
Line of Braddock’s
Road, near Frostburg,
Maryland

On the line of Braddock’s road, a dozen miles west of


Cumberland, is a milestone, set up about a hundred and fifty years
ago. A photograph of it is shown above. It is a rough brown stone,
standing in a pasture half a mile outside the city of Frostburg, in
western Maryland. The stone was once taken away and broken, but
it has since been set up again and cemented into a base of concrete.
The view shows how it has been split up and down. On one side are
directions, and on the other are the words, “Our Country’s Rights We
Will Defend.”
Braddock’s journey from Alexandria to Fort Duquesne was an
uncomfortable one, to say nothing of its disastrous end. He bought a
carriage to ride in, but the road was not suited to a coach, as were
the roads he knew in old England. Beyond Cumberland, especially,
in spite of all the work his men could do upon it, it was so bad that he
was forced to take Washington’s advice and change the baggage
from wagons to pack horses.
Gradually, as time went on, these rough paths were beaten down
into smoother thoroughfares. The same causes that led to the
development of the North were working also at the South. Along the
Potomac, as in New York and in Pennsylvania, the stream of colonial
life flowed westward. First the pioneers settled the lowlands around
Chesapeake bay and along the deep rivers; then as their strength
and courage reached beyond the mountains they found the forests
and fertile soil behind the Blue Ridge. Farther within the rugged
highlands they built Fort Cumberland and sent out discoverers and
armies to the Ohio river. When the woods were cleared and towns
and states grew up on the Ohio, there was frequent occasion to
cross the mountains for trade, for travel, and to reach the seat of
government, which in 1801 was moved to Washington on the
Potomac.

Fig. 35. Old Road House, Brownsville, Pennsylvania


These glimpses of colonial journeys will help us to understand
why the National Road came to be built. About one hundred years
ago the government began to take a great interest in opening roads,
especially across the Appalachian mountains, to Ohio, Kentucky,
and other parts of the Mississippi valley. Washington, who died in
1799, had said much about this work, for he not only wanted western
trade to come to Virginia instead of going to New Orleans, but he
also felt that so long as the mountains kept the East and the West
apart we should never have one common country, held together by
friendly feelings.
The people of Baltimore, like those of New York and
Philadelphia, were eager to have the best road to the West, that their
business might be benefited. Not far from Baltimore is an old place
called Joppa, and several roads are still known as “Joppa roads.”
The town is older than Baltimore and was once the chief trading
town in the northern part of Maryland; but Baltimore was well
situated on an arm of the great bay, and by this time had gone far
ahead of its old rival.
A number of good roads had been built in Maryland, among
them a famous one leading out westward to Frederick. This was in
the direction of Hagerstown, and still farther west was Cumberland.
The United States government decided to build a great road to Ohio,
beginning at Cumberland. To get the benefit of this, the men of
Baltimore went to work to push the Frederick pike westward to the
beginning of the National Road.
So it came about in 1811 that the first contracts were let for
building parts of the National Road. We remember that the Erie
canal was not started until six years later. The act of Congress which
ordered the making of the road provided that a strip four rods wide
should be cleared of trees, that it should be built up in the middle
with broken stone, gravel, or other material good for roads, and that
all steep slopes should be avoided. The road was opened to the
public in 1818, one year after the Erie canal was begun. The original
plan was to make it seven hundred miles long, reaching from
Cumberland to the Mississippi river, but it was never carried out.
The Maryland roads, as we have seen, ran west from Baltimore
and Washington to Frederick, east of the Blue Ridge; to Hagerstown,
in the Great Valley; and to Cumberland, in the mountains.
Cumberland is a stirring town of about twenty thousand people, and
with its great business in coal, iron, and railroads it seems like a
larger city. Thence the National Road runs through the gap in Wills
mountain (Fig. 36) to Frostburg, a dozen miles west and fifteen
hundred feet higher. The road soon bears northward into
Pennsylvania and crosses the Monongahela river at Brownsville,
about forty miles south of Pittsburg. Coal is mined here, and boats
were running in those early days, as coal barges and steamboats
run to-day, down to the great iron city.
From Brownsville the pike leads over the hills and comes down
to the Ohio river at Wheeling, West Virginia. It then passes on
through Ohio, touching Columbus, the capital, on the way to Indiana
and the Mississippi.
We sometimes admire the cars marked with the sign of the
United States post office, which we see drawn by a swift locomotive
at a speed of sixty miles an hour; but when the government put its
mail coaches on the National Road from Washington to Wheeling, no
doubt they seemed quite as wonderful to the people of that time. And
it was only twenty-five years since the people of Utica had thought it
so remarkable that six letters had come to them in one mail! Soon
passenger coaches were rushing along at ten miles an hour, and
sometimes even faster. There were canvas-covered freight wagons,
each of which carried ten tons, had rear wheels ten feet high, and
was drawn by twelve horses. In those days life was full of stirring
interest on the National Road.
Fig. 36. Cumberland and the Gap in Wills Mountain
There were rates of toll for all sorts of animals and wagons. The
toll was higher for hogs than for sheep, and more was charged for
cattle than for hogs. If the wagons had very wide tires, no toll was
demanded. Drivers sometimes lied about the number of people in
their stages, so as to pay less toll. The stages were not owned by
the drivers but by companies, which bid for travelers and freight, as
railways do now. There were penalties for injuring milestones or
defacing bridges, showing that some people then were like some
people now. The companies had interesting names. There were the
“Good Intent,” “Ohio National Stage Lines,” the “Pilot,” “Pioneer,”
“June Bug,” and “Defiance.” Not one of them cared for mud or dust,
for horses or men, if only it could be the first to reach its destination.
There must have been dust enough, for twenty coaches with their
many horses sometimes followed one another in a close line.
Fig. 37. Bridge and Monument, National Road, near
Wheeling, West Virginia
Henry Clay was one of the chief advocates of this road, and a
monument built in his honor may be seen near the bridge, shown in
Fig. 37. It is a few miles east of Wheeling. At Brownsville a small
stream called Dunlap’s creek flows into the Monongahela from the
east. Over it is an iron bridge on the line of the National Road.
According to a story told in Brownsville, Henry Clay was once
overturned as he was riding through the creek before the bridge was
built. As he gathered himself up he was heard to say, “Clay and mud
shall not be mixed here again.” The story goes that he went on
immediately to Washington and got an order for the building of the
bridge.
Whether this be true or not, it is certain that he and many other
statesmen traveled over the National Road. They could not have
private cars, nor did they go in drawing-room coaches, as we can if
we choose. Anybody might chance to sit beside these men of
national fame, as day after day they rode through the valleys and
over the mountains, stopping at the wayside hotels for food and rest.
Some of the old hotels, tollhouses, and bridges, as they look to-
day, are shown in the illustrations in this chapter. The road itself was
long ago given up to the different states and counties through which
it runs, but it still tells to the traveler who goes over it many a story of
the life of a hundred years ago.
CHAPTER IX
THE BALTIMORE AND OHIO RAILROAD

Even after the Erie canal was built and long lines of boats were
carrying the grain and other products of the West to New York, the
men of Virginia and Maryland did not give up the notion of still
making the trade of the western country come their way. They
planned the Chesapeake and Ohio canal, to reach the Ohio river,
and thought that other canals across the state of Ohio would let them
into lake Erie. By the Ohio river they would connect with New
Orleans and the upper Mississippi river, and through lake Erie they
could reach the towns and farms that border lake Huron, lake
Michigan, and lake Superior.
A canal along the Potomac valley had been talked of several
years before the Revolution, when Richard Henry Lee laid a plan for
it before the Assembly of Virginia. Doubtless others thought of it too,
as of the Erie canal, long before it was made. At the end of the War
of the Revolution Washington made a long journey into the wild
woods of New York. He went to the source of the Susquehanna at
Otsego lake, visited the portage between the Mohawk and Wood
creek, and saw for himself that New York had a great chance for
navigation and trade. But he had a natural love for his own Virginia,
and he did not intend to let New York go ahead of his native state.
His journeys across the mountains as a surveyor and as a soldier
gave him a knowledge of the Ohio country, and as he had himself
taken up much good land there, he wished to have an easy way, by
land or water, from the sea to the rich Ohio valley. So he thought
much about a canal to run by the side of the Potomac, and he joined
with others who felt as he did to form the Potomac Company. They

You might also like