Introduction to Software Testing Paul Ammann all chapter instant download
Introduction to Software Testing Paul Ammann all chapter instant download
https://ebookgate.com/product/introduction-to-software-testing-1st-
edition-paul-ammann/
ebookgate.com
https://ebookgate.com/product/software-testing-4th-edition-paul-c-
jorgensen/
ebookgate.com
https://ebookgate.com/product/introduction-to-nondestructive-testing-
a-training-guide-2nd-edition-paul-e-mix/
ebookgate.com
https://ebookgate.com/product/introduction-to-nondestructive-testing-
a-training-guide-second-edition-paul-e-mixauth/
ebookgate.com
Software Testing 1st Edition Ali Mili
https://ebookgate.com/product/software-testing-1st-edition-ali-mili/
ebookgate.com
https://ebookgate.com/product/software-testing-third-edition-brian-
hambling/
ebookgate.com
https://ebookgate.com/product/how-to-reduce-the-cost-of-software-
testing-1st-edition-matthew-heusser/
ebookgate.com
https://ebookgate.com/product/software-testing-interview-questions-
computer-science-1st-edition-s-koirala/
ebookgate.com
https://ebookgate.com/product/well-testing-project-management-paul-j-
nardone/
ebookgate.com
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
www.cambridge.org
Information on this title: www.cambridge.org/9781107172012
DOI: 10.1017/9781316771273
A catalogue record for this publication is available from the British Library.
Part 1 Foundations 1
1 Why Do We Test Software? 3
1.1 When Software Goes Bad 4
1.2 Goals of Testing Software 8
1.3 Bibliographic Notes 17
3 Test Automation 35
3.1 Software Testability 36
3.2 Components of a Test Case 36
v
vi Contents
ix
x List of Figures
xii
List of Tables xiii
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 have used the book.
xiv
Preface to the Second Edition xv
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 founda-
tional 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 discus-
sion 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 recti-
fies 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 auto-
mated 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 edi-
tion. 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,
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.
xvi Preface to the Second Edition
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!
2 Our MS program is practical in nature, not research-oriented. The majority of students are part-time
students with five to ten years of experience in the software industry. SWE 637 begat this book when
we realized Beizer’s classic text [Beizer, 1990] was out of print.
xviii Preface to the Second Edition
the importance of software quality, and second to get them started with test automa-
tion (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 soft-
ware 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.
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.
Preface to the Second Edition xix
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 sec-
ond 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 Uni-
versity Australia; Robyn Lutz, Iowa State University; Upsorn Praphamontripong,
George Mason University; Alper Sen, Bogazici University; Marjan Sirjani, Reyk-
javik 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 review-
ers 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 Alshde-
fat, Alexandre Bartel, Don Braffitt, Andrew Brooks, Josh Dehlinger, Gordon
Fraser, Rob Fredericks, Weiyi Li, Hassan Mirian, Alan Moraes, Miika Nurmi-
nen, 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.
xx Preface to the Second Edition
Foundations
1
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 indus-
try 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
3
4 Foundations
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 evi-
dent 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 pre-
sented in the context of a particular software artifact (for example, a requirements
document or code) or a particular phase of the lifecycle (for example, require-
ments 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 clas-
sical 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 actual
tests 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 mathemat-
ics. 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 pre-
sented 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.
Definition 1.2 Software Error: An incorrect internal state that is the manifes-
tation of some fault.
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
1 Why Do We Test Software? 5
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 irregu-
lar 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 cru-
cial 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 soft-
ware 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, we need
to clarify the concept of the state. A program state is defined during execution of a
program as the current value of all live variables and the current location, as given
by the program counter. The program counter (PC) is the next statement in the
program to be executed and can be described with a line number in the file (PC = 5)
or the statement as a string (PC = “if (x > y)”). Most of the time, what we mean by
a statement is obvious, but complex structures such as for loops have to be treated
specially. The program line “for (i=1; i<N; i++)” actually has three statements that
can result in separate states. The loop initialization (“i=1”) is separate from the loop
test (“i<N”), and the loop increment (“i++”) occurs at the end of the loop body. As
an illustrative example, consider the following Java method:
/**
* Counts zeroes in an array
*
* @param x array to count zeroes in
* @return number of occurrences of 0 in x
* @throws NullPointerException if x is null
*/
public static int numZero (int[] x)
{
int count = 0;
for (int i = 1; i < x.length; i++)
{
if (x[i] == 0) count++;
}
return count;
}
6 Foundations
Sidebar
Programming Language Independence
This book strives to be independent of language, and most of the concepts in the book are.
At the same time, we want to illustrate these concepts with specific examples. We choose
Java, and emphasize that most of these examples would be very similar in many other
common languages.
The fault in this method is that it starts looking for zeroes at index 1 instead of
index 0, as is necessary for arrays in Java. For example, numZero ([2, 7, 0]) correctly
evaluates to 1, while numZero ([0, 7, 2]) incorrectly evaluates to 0. In both tests the
faulty statement is executed. Although both of these tests result in an error, only
the second results in failure. To understand the error states, we need to identify the
state for the method. The state for numZero() consists of values for the variables x,
count, i, and the program counter (PC). For the first example above, the state at the
loop test on the very first iteration of the loop is (x = [2, 7, 0], count = 0, i = 1, PC = “i <
x.length”). Notice that this state is erroneous precisely because the value of i should
be zero on the first iteration. However, since the value of count is coincidentally
correct, the error state does not propagate to the output, and hence the software
does not fail. In other words, a state is in error simply if it is not the expected state,
even if all of the values in the state, considered in isolation, are acceptable. More
generally, if the required sequence of states is s 0, s1 , s2 , . . . , and the actual sequence
of states is s 0 , s2 , s 3, . . . , then state s2 is in error in the second sequence. The fault
model described here is quite deep, and this discussion gives the broad view without
going into unneeded details. The exercises at the end of the section explore some of
the subtleties of the fault model.
In the second test for our example, the error state is (x = [0, 7, 2], count = 0, i
= 1, PC = “i < x.length”). In this case, the error propagates to the variable count and
is present in the return value of the method. Hence a failure results.
The term bug is often used informally to refer to all three of fault, error, and
failure. This book will usually use the specific term, and avoid using “bug.” A
favorite story of software engineering teachers is that Grace Hopper found a moth
stuck in a relay on an early computing machine, which started the use of bug as
a problem with software. It is worth noting, however, that the term bug has an
old and rich history, predating software by at least a century. The first use of bug
to generally mean a problem we were able to find is from a quote by Thomas
Edison:
It has been just so in all of my inventions. The first step is an intuition, and comes
with a burst, then difficulties arise–this thing gives out and [it is] then that ‘Bugs’–
as such little faults and difficulties are called–show themselves and months of intense
watching, study and labor are requisite.
— Thomas Edison
A very public failure was the Mars lander of September 1999, which crashed
due to a misunderstanding in the units of measure used by two modules created by
separate software groups. One module computed thruster data in English units and
1 Why Do We Test Software? 7
forwarded the data to a module that expected data in metric units. This is a very
typical integration fault (but in this case enormously expensive, both in terms of
money and prestige).
One of the most famous cases of software killing people is the Therac-25 radi-
ation therapy machine. Software faults were found to have caused at least three
deaths due to excessive radiation. Another dramatic failure was the launch failure
of the first Ariane 5 rocket, which exploded 37 seconds after liftoff in 1996. The
low-level cause was an unhandled floating point conversion exception in an iner-
tial guidance system function. It turned out that the guidance system could never
encounter the unhandled exception when used on the Ariane 4 rocket. That is, the
guidance system function was correct for Ariane 4. The developers of the Ariane 5
quite reasonably wanted to reuse the successful inertial guidance system from the
Ariane 4, but no one reanalyzed the software in light of the substantially differ-
ent flight trajectory of the Ariane 5. Furthermore, the system tests that would have
found the problem were technically difficult to execute, and so were not performed.
The result was spectacular–and expensive!
The famous Pentium bug was an early alarm of the need for better testing,
especially unit testing. Intel introduced its Pentium microprocessor in 1994, and
a few months later, Thomas Nicely, a mathematician at Lynchburg College in Vir-
ginia, found that the chip gave incorrect answers to certain floating-point division
calculations.
The chip was slightly inaccurate for a few pairs of numbers; Intel claimed (proba-
bly correctly) that only one in nine billion division operations would exhibit reduced
precision. The fault was the omission of five entries in a table of 1,066 values (part
of the chip’s circuitry) used by a division algorithm. The five entries should have
contained the constant +2, but the entries were not initialized and contained zero
instead. The MIT mathematician Edelman claimed that “the bug in the Pentium
was an easy mistake to make, and a difficult one to catch,” an analysis that misses
an essential point. This was a very difficult mistake to find during system testing,
and indeed, Intel claimed to have run millions of tests using this table. But the table
entries were left empty because a loop termination condition was incorrect; that is,
the loop stopped storing numbers before it was finished. Thus, this would have been
a very simple fault to find during unit testing; indeed analysis showed that almost
any unit level coverage criterion would have found this multimillion dollar mistake.
The great northeast blackout of 2003 was started when a power line in Ohio
brushed against overgrown trees and shut down. This is called a fault in the power
industry. Unfortunately, the software alarm system failed in the local power com-
pany, so system operators could not understand what happened. Other lines also
sagged into trees and switched off, eventually overloading other power lines, which
then cut off. This cascade effect eventually caused a blackout throughout southeast-
ern Canada and eight states in the northeastern part of the US. This is considered the
biggest blackout in North American history, affecting 10 million people in Canada
and 40 million in the USA, contributing to at least 11 deaths and costing up to $6
billion USD.
Some software failures are felt widely enough to cause severe embarrassment
to the company. In 2011, a centralized students data management system in Korea
miscalculated the academic grades of over 29,000 middle and high school students.
8 Foundations
This led to massive confusion about college admissions and a government inves-
tigation into the software engineering practices of the software vendor, Samsung
Electronics.
A 1999 study commissioned by the U.S. National Research Council and the U.S.
President’s commission on critical infrastructure protection concluded that the cur-
rent base of science and technology is inadequate for building systems to control
critical software infrastructure. A 2002 report commissioned by the National Insti-
tute of Standards and Technology (NIST) estimated that defective software costs
the U.S. economy $59.5 billion per year. The report further estimated that 64% of
the costs were a result of user mistakes and 36% a result of design and development
mistakes, and suggested that improvements in testing could reduce this cost by about
a third, or $22.5 billion. Blumenstyk reported that web application failures lead to
huge losses in businesses; $150,000 per hour in media companies, $2.4 million per
hour in credit card sales, and $6.5 million per hour in the financial services market.
Software faults do not just lead to functional failures. According to a Symantec
security threat report in 2007, 61 percent of all vulnerabilities disclosed were due to
faulty software. The most common are web application vulnerabilities that can be
attacked by some common attack techniques using invalid inputs.
These public and expensive software failures are getting more common and
more widely known. This is simply a symptom of the change in expectations of
software. As we move further into the 21st century, we are using more safety crit-
ical, real-time software. Embedded software has become ubiquitous; many of us
carry millions of lines of embedded software in our pockets. Corporations rely more
and more on large-scale enterprise applications, which by definition have large user
bases and high reliability requirements. Security, which used to depend on cryp-
tography, then database security, then avoiding network vulnerabilities, is now
largely about avoiding software faults. The Web has had a major impact. It fea-
tures a deployment platform that offers software services that are very competitive
and available to millions of users. They are also distributed, adding complexity,
and must be highly reliable to be competitive. More so than at any previous time,
industry desperately needs to apply the accumulated knowledge of over 30 years of
testing research.
Level 2 The purpose of testing is to show that the software does not work.
Level 3 The purpose of testing is not to prove anything specific, but to reduce the
risk of using the software.
Level 4 Testing is a mental discipline that helps all IT professionals develop higher-
quality software.
Level 0 is the view that testing is the same as debugging. This is the view that
is naturally adopted by many undergraduate Computer Science majors. In most CS
programming classes, the students get their programs to compile, then debug the
programs with a few inputs chosen either arbitrarily or provided by the professor.
10 Foundations
This model does not distinguish between a program’s incorrect behavior and a mis-
take within the program, and does very little to help develop software that is reliable
or safe.
In Level 1 testing, the purpose is to show correctness. While a significant step
up from the naive level 0, this has the unfortunate problem that in any but the most
trivial of programs, correctness is virtually impossible to either achieve or demon-
strate. Suppose we run a collection of tests and find no failures. What do we know?
Should we assume that we have good software or just bad tests? Since the goal of
correctness is impossible, test engineers usually have no strict goal, real stopping
rule, or formal test technique. If a development manager asks how much testing
remains to be done, the test manager has no way to answer the question. In fact,
test managers are in a weak position because they have no way to quantitatively
express or evaluate their work.
In Level 2 testing, the purpose is to show failures. Although looking for failures
is certainly a valid goal, it is also inherently negative. Testers may enjoy finding the
problem, but the developers never want to find problems–they want the software to
work (yes, level 1 thinking can be natural for the developers). Thus, level 2 testing
puts testers and developers into an adversarial relationship, which can be bad for
team morale. Beyond that, when our primary goal is to look for failures, we are still
left wondering what to do if no failures are found. Is our work done? Is our software
very good, or is the testing weak? Having confidence in when testing is complete is
an important goal for all testers. It is our view that this level currently dominates the
software industry.
The thinking that leads to Level 3 testing starts with the realization that test-
ing can show the presence, but not the absence, of failures. This lets us accept
the fact that whenever we use software, we incur some risk. The risk may be
small and the consequences unimportant, or the risk may be great and the con-
sequences catastrophic, but risk is always there. This allows us to realize that the
entire development team wants the same thing–to reduce the risk of using the
software. In level 3 testing, both testers and developers work together to reduce
risk. We see more and more companies move to this testing maturity level every
year.
Once the testers and developers are on the same “team,” an organization can
progress to real Level 4 testing. Level 4 thinking defines testing as a mental disci-
pline that increases quality. Various ways exist to increase quality, of which creating
tests that cause the software to fail is only one. Adopting this mindset, test engi-
neers can become the technical leaders of the project (as is common in many other
engineering disciplines). They have the primary responsibility of measuring and
improving software quality, and their expertise should help the developers. Beizer
used the analogy of a spell checker. We often think that the purpose of a spell
checker is to find misspelled words, but in fact, the best purpose of a spell checker
is to improve our ability to spell. Every time the spell checker finds an incorrectly
spelled word, we have the opportunity to learn how to spell the word correctly.
The spell checker is the “expert” on spelling quality. In the same way, level 4 test-
ing means that the purpose of testing is to improve the ability of the developers
1 Why Do We Test Software? 11
to produce high-quality software. The testers should be the experts who train your
developers!
As a reader of this book, you probably start at level 0, 1, or 2. Most software
developers go through these levels at some stage in their careers. If you work in
software development, you might pause to reflect on which testing level describes
your company or team. The remaining chapters in Part I should help you move to
level 2 thinking, and to understand the importance of level 3. Subsequent chapters
will give you the knowledge, skills, and tools to be able to work at level 3. An
ultimate goal of this book is to provide a philosophical basis that will allow read-
ers to become “change agents” in their organizations for level 4 thinking, and test
engineers to become software quality experts. Although level 4 thinking is cur-
rently rare in the software industry, it is common in more mature engineering
fields.
These considerations help us decide at a strategic level why we test. At a more
tactical level, it is important to know why each test is present. If you do not know
why you are conducting each test, the test will not be very helpful. What fact is each
test trying to verify? It is essential to document test objectives and test requirements,
including the planned coverage levels. When the test manager attends a planning
meeting with the other managers and the project manager, the test manager must be
able to articulate clearly how much testing is enough and when testing will complete.
In the 1990s, we could use the “date criterion,” that is, testing is “complete” when
the ship date arrives or when the budget is spent.
Figure 1.1 dramatically illustrates the advantages of testing early rather than
late. This chart is based on a detailed analysis of faults that were detected and fixed
during several large government contracts. The bars marked ‘A’ indicate what per-
centage of faults appeared in that phase. Thus, 10% of faults appeared during the
requirements phase, 40% during design, and 50% during implementation. The bars
marked ‘D’ indicated the percentage of faults that were detected during each phase.
About 5% were detected during the requirements phase, and over 35% during sys-
tem testing. Lastly is the cost analysis. The solid bars marked ‘C’ indicate the relative
cost of finding and fixing faults during each phase. Since each project was different,
this is averaged to be based on a “unit cost.” Thus, faults detected and fixed during
requirements, design, and unit testing were a single unit cost. Faults detected and
fixed during integration testing cost five times as much, 10 times as much during
system testing, and 50 times as much after the software is deployed.
If we take the simple assumption of $1000 USD unit cost per fault, and 100
faults, that means we spend $39,000 to find and correct faults during requirements,
design, and unit testing. During integration testing, the cost goes up to $100,000.
But system testing and deployment are the serious problems. We find more faults
during system testing at ten times the cost, for a total of $360,000. And even though
we only find a few faults after deployment, the cost being 50 X unit means we spend
$250,000! Avoiding the work early (requirements analysis and unit testing) saves
money in the short term. But it leaves faults in software that are like little bombs,
ticking away, and the longer they tick, the bigger the explosion when they finally
go off.
12 Foundations
To put Beizer’s level 4 test maturity level in simple terms, the goal of testing is
to eliminate faults as early as possible. We can never be perfect, but every time we
eliminate a fault during unit testing (or sooner!), we save money. The rest of this
book will teach you how to do that.
EXERCISES
Chapter 1.
1. What are some factors that would help a development organization move
from Beizer’s testing level 2 (testing is to show errors) to testing level 4
(a mental discipline that increases quality)?
2. What is the difference between software fault and software failure?
3. What do we mean by “level 3 thinking is that the purpose of testing is to reduce
risk?” What risk? Can we reduce the risk to zero?
4. The following exercise is intended to encourage you to think of testing in a
more rigorous way than you may be used to. The exercise also hints at the
strong relationship between specification clarity, faults, and test cases 1.
(a) Write a Java method with the signature
public static Vector union (Vector a, Vector b)
The method should return a Vector of objects that are in either of the two
argument Vectors.
(b) Upon reflection, you may discover a variety of defects and ambiguities
in the given assignment. In other words, ample opportunities for faults
exist. Describe as many possible faults as you can. (Note: Vector is a Java
Collection class. If you are using another language, interpret Vector as a list.)
(c) Create a set of test cases that you think would have a reasonable chance of
revealing the faults you identified above. Document a rationale for each
test in your test set. If possible, characterize all of your rationales in some
concise summary. Run your tests against your implementation.
1 Liskov’s Program Development in Java, especially chapters 9 and 10, is a great source for students who
wish to learn more about this.
1 Why Do We Test Software? 13
(d) Rewrite the method signature to be precise enough to clarify the defects
and ambiguities identified earlier. You might wish to illustrate your
specification with examples drawn from your test cases.
5. Below are four faulty programs. Each includes test inputs that result in failure.
Answer the following questions about each program.
/** /**
* Find last index of element * Find last index of zero
* *
* @param x array to search * @param x array to search
* @param y value to look for *
* @return last index of y in x; -1 if absent * @return last index of 0 in x; -1 if absent
* @throws NullPointerException if x is null * @throws NullPointerException if x is null
*/ */
public int findLast (int[] x, int y) public static int lastZero (int[] x)
{ {
for (int i=x.length-1; i > 0; i--) for (int i = 0; i < x.length; i++)
{ {
if (x[i] == y) if (x[i] == 0)
{ {
return i; return i;
} }
} }
return -1; return -1;
} }
// test: x = [2, 3, 5]; y = 2; Expected = 0 // test: x = [0, 1, 0]; Expected = 2
// Book website: FindLast.java // Book website: LastZero.java
// Book website: FindLastTest.java // Book website: LastZeroTest.java
/** /**
* Count positive elements * Count odd or positive elements
* *
* @param x array to search * @param x array to search
* @return count of positive elements in x * @return count of odd/positive values in x
* @throws NullPointerException if x is null * @throws NullPointerException if x is null
*/ */
public int countPositive (int[] x) public static int oddOrPos(int[] x)
{ {
int count = 0; int count = 0;
for (int i=0; i < x.length; i++) for (int i = 0; i < x.length; i++)
{ {
if (x[i] >= 0) if (x[i]%2 == 1 || x[i] > 0)
{ {
count++; count++;
} }
} }
return count; return count;
} }
// test: x = [-4, 2, 0, 2]; Expected = 2 // test: x = [-3, -2, 0, 1, 4]; Expected = 3
// Book website: CountPositive.java // Book website: OddOrPos.java
// Book website: CountPositiveTest.java // Book website: OddOrPosTest.java
14 Foundations
(a) Explain what is wrong with the given code. Describe the fault precisely
by proposing a modification to the code.
(b) If possible, give a test case that does not execute the fault. If not, briefly
explain why not.
(c) If possible, give a test case that executes the fault, but does not result in
an error state. If not, briefly explain why not.
(d) If possible give a test case that results in an error, but not a failure. If not,
briefly explain why not. Hint: Don’t forget about the program counter.
(e) For the given test case, describe the first error state. Be sure to describe
the complete state.
(f) Implement your repair and verify that the given test now produces the
expected output. Submit a screen printout or other evidence that your
new program works.
6. Answer question (a) or (b), but not both, depending on your background.
(a) If you do, or have, worked for a software development company, what
level of test maturity do you think the company worked at? (0: test-
ing=debugging, 1: testing shows correctness, 2: testing shows the program
doesn’t work, 3: testing reduces risk, 4: testing is a mental discipline about
quality).
(b) If you have never worked for a software development company, what
level of test maturity do you think that you have? (0: testing=debugging,
1: testing shows correctness, 2: testing shows the program doesn’t work,
3: testing reduces risk, 4: testing is a mental discipline about quality).
7. Consider the following three example classes. These are OO faults taken
from Joshua Bloch’s Effective Java, Second Edition. Answer the following
questions about each.
{
Object result = super.clone();
// Location "B"
((Truck) result).y = this.y; // throws ClassCastException
return result;
}
// other methods omitted
}
//Test: Truck suv = new Truck (4); Truck co = suv.clone()
// Expected: suv.x = co.x; suv.getClass() = co.getClass()
class Point
{
private int x; private int y;
public Point (int x, int y) { this.x=x; this.y=y; }
(a) Explain what is wrong with the given code. Describe the fault precisely by
proposing a modification to the code.
(b) If possible, give a test case that does not execute the fault. If not, briefly
explain why not.
(c) If possible, give a test case that executes the fault, but does not result in an
error state. If not, briefly explain why not.
(d) If possible give a test case that results in an error, but not a failure. If not,
briefly explain why not. Hint: Don’t forget about the program counter.
(e) In the given code, describe the first error state. Be sure to describe the
complete state.
(f) Implement your repair and verify that the given test now produces the
expected output. Submit a screen printout or other evidence that your new
program works.
Quality Assurance [Beizer, 1984] and Hetzel’s The Complete Guide to Software Test-
ing [Hetzel, 1988] cover various aspects of management and process for software
testing. Several books cover specific aspects of testing [Howden, 1987, Marick, 1995,
Roper, 1994]. The STEP project at Georgia Institute of Technology resulted in a
comprehensive survey of the practice of software testing by Department of Defense
contractors in the 1980s [DeMillo et al., 1987].
The information for the Pentium bug and Mars lander was taken from sev-
eral sources, including by Edelman, Moler, Nuseibeh, Knutson, and Peterson
[Edelman, 1997, Knutson and Carmichael, 2000, Moler, 1995, Nuseibeh, 1997,
Peterson, 1997]. The well-written official accident report [Lions, 1996] is our favorite
source for understanding the details of the Ariane 5 Flight 501 Failure. The infor-
mation for the Therac-25 accidents was taken from Leveson and Turner’s deep
analysis [Leveson and Turner, 1993]. The details on the 2003 Northeast Black-
out was taken from Minkel’s analysis in Scientific American [Minkel, 2008] and
Rice’s book [Rice, 2008]. The information about the Korean education informa-
tion system was taken from two newspaper articles [Min-sang and Sang-soo, 2011,
Korea Times, 2011].
The 1999 study mentioned was published in an NRC / PITAC report
[PITAC, 1999, Schneider, 1999]. The data in Figure 1.1 were taken from a NIST
report that was developed by the Research Triangle Institute [RTI, 2002]. The
figures on web application failures are due to Blumenstyk [Blumenstyk, 2006]. The
figures about faulty software leading to security vulnerabilities are from Symantec
[Symantec, 2007].
Finally, Rick Hower’s QATest website is a good resource for current, elemen-
tary, information about software testing: www.softwareqatest.com.
2
Designers are more efficient and effective if they can raise their level of abstraction.
This chapter introduces one of the major innovations in the second edition of Intro-
duction to Software Testing. Software testing is inherently complicated and our
ultimate goal, completely correct software, is unreachable. The reasons are formal
(as discussed below in section 2.1) and philosophical. As discussed in Chapter 1, it’s
not even clear that the term “correctness” means anything when applied to a piece
of engineering as complicated as a large computer program. Do we expect correct-
ness out of a building? A car? A transportation system? Intuitively, we know that
all large physical engineering systems have problems, and moreover, there is no way
to say what correct means. This is even more true for software, which can quickly
get orders of magnitude more complicated than physical structures such as office
buildings or airplanes.
Instead of looking for “correctness,” wise software engineers try to evaluate soft-
ware’s “behavior” to decide if the behavior is acceptable within consideration of a
large number of factors including (but not limited to) reliability, safety, maintain-
ability, security, and efficiency. Obviously this is more complex than the naive desire
to show the software is correct.
So what do software engineers do in the face of such overwhelming complexity?
The same thing that physical engineers do–we use mathematics to “raise our level of
abstraction.” The Model-Driven Test Design (MDTD) process breaks testing into
a series of small tasks that simplify test generation. Then test designers isolate their
task, and work at a higher level of abstraction by using mathematical engineering
structures to design test values independently of the details of software or design
artifacts, test automation, and test execution.
A key intellectual step in MDTD is test case design. Test case design can be the
primary determining factor in whether tests successfully find failures in software.
Tests can be designed with a “human-based” approach, where a test engineer uses
domain knowledge of the software’s purpose and his or her experience to design
tests that will be effective at finding faults. Alternatively, tests can be designed to sat-
isfy well-defined engineering goals such as coverage criteria. This chapter describes
19
20 Foundations
the task activities and then introduces criteria-based test design. Criteria-based test
design will be discussed in more detail in Chapter 5, then specific criteria on four
mathematical structures are described in Part II. After these preliminaries, the
model-driven test design process is defined in detail. The book website has sim-
ple web applications that support the MDTD in the context of the mathematical
structures in Part II.
Of course the central issue is that for a given fault, not all inputs will “trigger”
the fault into creating incorrect output (a failure). Also, it is often very difficult to
relate a failure to the associated fault. Analyzing these ideas leads to the fault/failure
model, which states that four conditions are needed for a failure to be observed.
Figure 2.1 illustrates the conditions. First, a test must reach the location or loca-
tions in the program that contain the fault (Reachability). After the location is
executed, the state of the program must be incorrect (Infection). Third, the infected
state must propagate through the rest of the execution and cause some output or
final state of the program to be incorrect (Propagation). Finally, the tester must
observe part of the incorrect portion of the final program state (Revealability). If
the tester only observes parts of the correct portion of the final program state, the
failure is not revealed. This is shown in the cross-hatched intersection in Figure 2.1.
Issues with revealing failures will be discussed in Chapter 4 when we present test
automation strategies.
Collectively, these four conditions are known as the fault/failure model, or the
RIPR model.
It is important to note that the RIPR model applies even when the fault is miss-
ing code (so-called faults of omission). In particular, when execution passes through
the location where the missing code should be, the program counter, which is part
of the program state, necessarily has the wrong value.
2 Model-Driven Test Design 21
From a practitioner’s view, these limitations mean that software testing is com-
plex and difficult. The common way to deal with complexity in engineering is to
use abstraction by abstracting out complicating details that can be safely ignored by
modeling the problem with some mathematical structures. That is a central theme
of this book, which we begin by analyzing the separate technical activities involved
in creating good tests.
Test
Manager
n
desig Test instantiate Executable
Designs Tests
Test
Engineer
Test Test
Engineer Engineer
execute
P Computer Output Evaluate
be carried out by one person or by several, and the process is monitored by a test
manager.
One of a test engineer’s most powerful tools is a formal coverage criterion. For-
mal coverage criteria give test engineers ways to decide what test inputs to use
during testing, making it more likely that the tester will find problems in the program
and providing greater assurance that the software is of high quality and reliability.
Coverage criteria also provide stopping rules for the test engineers. The technical
core of this book presents the coverage criteria that are available, describes how
they are supported by tools (commercial and otherwise), explains how they can best
be applied, and suggests how they can be integrated into the overall development
process.
Software testing activities have long been categorized into levels, and the
most often used level categorization is based on traditional software process steps.
Although most types of tests can only be run after some part of the software is
implemented, tests can be designed and constructed during all software devel-
opment steps. The most time-consuming parts of testing are actually the test
design and construction, so test activities can and should be carried out throughout
development.
Requirements Acceptance
Analysis Test Test
Subsystem Integration
Design Test
Detailed Module
Design Test
Implementation Unit
Test
Figure 2.3. Software development activities and testing levels – the “V Model”.
Figure 2.3, often called the “V model,” illustrates a typical scenario for testing
levels and how they relate to software development activities by isolating each step.
Information for each test level is typically derived from the associated development
activity. Indeed, standard advice is to design the tests concurrently with each devel-
opment activity, even though the software will not be in an executable form until the
implementation phase. The reason for this advice is that the mere process of design-
ing tests can identify defects in design decisions that otherwise appear reasonable.
Early identification of defects is by far the best way to reduce their ultimate cost.
Note that this diagram is not intended to imply a waterfall process. The synthesis
and analysis activities generically apply to any development process.
The requirements analysis phase of software development captures the cus-
tomer’s needs. Acceptance testing is designed to determine whether the completed
software in fact meets these needs. In other words, acceptance testing probes
whether the software does what the users want. Acceptance testing must involve
users or other individuals who have strong domain knowledge.
The architectural design phase of software development chooses components
and connectors that together realize a system whose specification is intended to
meet the previously identified requirements. System testing is designed to determine
whether the assembled system meets its specifications. It assumes that the pieces
work individually, and asks if the system works as a whole. This level of testing usu-
ally looks for design and specification problems. It is a very expensive place to find
lower-level faults and is usually not done by the programmers, but by a separate
testing team.
The subsystem design phase of software development specifies the structure and
behavior of subsystems, each of which is intended to satisfy some function in the
overall architecture. Often, the subsystems are adaptations of previously developed
24 Foundations
Although most of the literature emphasizes these levels in terms of when they
are applied, a more important distinction is on the types of faults that we are looking
for. The faults are based on the software artifact that we are testing, and the software
artifact that we derive the tests from. For example, unit and module tests are derived
to test units and modules, and we usually try to find faults that can be found when
executing the units and modules individually.
One final note is that OO software changes the testing levels. OO software blurs
the distinction between units and modules, so the OO software testing literature
has developed a slight variation of these levels. Intra-method testing evaluates indi-
vidual methods. Inter-method testing evaluates pairs of methods within the same
class. Intra-class testing evaluates a single entire class, usually as sequences of calls
to methods within the class. Finally, inter-class testing evaluates more than one class
at the same time. The first three are variations of unit and module testing, whereas
inter-class testing is a type of integration testing.
RAUM XX.
SITZUNGSSAAL.
Der Sitzungssaal ist von der Firma F. O. Schmidt nach dem
Originale im Schlosse Eszterháza bei Ödenburg im Stile Louis XV.
dekoriert. An der rechten Seitenwand eine Marmorbüste Seiner
Majestät des Kaisers, von Otto König, an der linken Seitenwand ein
lebensgroßes Porträt des Erzherzogs Rainer, gemalt von Siegmund
L’Allemand.
RAUM XXI.
ORIENTALISCHES ZIMMER.
Das orientalische Zimmer, rechts neben der Eingangstür zur
Bibliothek gelegen, soll die Ausstattung eines Wohnraumes im
Oriente zur Anschauung bringen. In die Wände sind Holzschränke
mit geschnitzten Füllungen eingesetzt und zwei mit Holzgittern
verschlossene Fenster eingebrochen. Unter dem Fenster eine
maurische Wandétagère. Die Bänke in den Fensternischen sind mit
Daghestan-Teppichen und tambourierten Seidenpolstern belegt, der
Fußboden mit einem Smyrna-Teppiche, in dessen Mitte ein Taburett
mit Kaffeeservice. Von der Stalaktitendecke hängt eine messingene
Moschee-Ampel aus Damaskus herab.
Unter den oberen Arkaden, oberhalb der Stiege, befindet sich
das Denkmal für den Gründer und ersten Direktor des Museums, R.
v. Eitelberger († 1885), entworfen von H. Klotz, in Erzguß ausgeführt
von der Metallwarenfabrik Artur Krupp in Berndorf; im Stiegenhause
die Marmorbüste des Erbauers des Museums, H. Freiherrn von
Ferstel ( † 1883), von V. Tilgner, die Marmorbüste des Industriellen
Ed. v. Haas ( † 1880) und ein Medaillonbild des Professors der
Kunstgewerbeschule, Ferd. Laufberger ( † 1881), entworfen von A.
Kühne und J. Storck.
BIBLIOTHEK.
Die Bibliothek des Österreichischen Museums enthält als
Fachbibliothek solche Werke, welche sowohl durch Abbildungen als
durch historische, künstlerische oder wissenschaftliche
Erläuterungen die Zwecke des Museums zu fördern geeignet sind.
Sie besteht aus zwei Abteilungen, aus der eigentlichen
Büchersammlung und aus der Sammlung von Kunstblättern.
Die letztere umfaßt eine reichhaltige Sammlung von
Ornamentstichen aus der Zeit vom XV. bis XVIII. Jahrhundert[26] und
eine Vorbildersammlung, bestehend aus Einzelabbildungen von
vorzugsweise kunstgewerblichen Arbeiten aller Art in
Originalzeichnungen, Kupferstichen, Holzschnitten, Lithographien
und photomechanischen Druckverfahren.
Eine spezielle Erwähnung verdient die stattliche Anzahl von
Fachzeitschriften, welche in einem eigenen Zeitschriftenlesesaale
(dem ehemaligen Vorlesesaale) dem Publikum auf die bequemste
Art zugänglich sind, ferner die bedeutende Sammlung von
kunsttheoretischen und kunsttechnischen Schriften, von Schreib-
und Zeichenbüchern aus dem XVI. bis XVIII. Jahrhundert, von
Kostümwerken und die kostbare Kollektion von Original-Stick- und
Spitzenmusterbüchern aus dem XVI. und XVII. Jahrhundert. Weiters
enthält die Büchersammlung eine große Zahl von Abbildungswerken
aus den Gebieten der Architektur, Skulptur und Malerei und eine
lange Reihe der besten Vorlagenwerke für sämtliche Zweige des
Kunstgewerbes.
Den Grundstock der Kunstblättersammlung bildet die im August
1863 erworbene Kollektion von Ornamentstichen aus dem Besitze
des Kunsthändlers W. Drugulin in Leipzig, bestehend aus 5000
Blättern nebst 87 Kunstbüchern aus dem XVI. bis XVIII. Jahrhundert.
RAUM XXII.
In diesem Raume ist eine Anzahl von japanischen Wandbildern
(Kakemonos) teils religiösen, teils weltlichen Inhaltes aufgehängt.
RAUM XXIII.
An den Wänden die Türen eines altjapanischen Tempels, die aus
Holz geschnitzt und vergoldet sind, ferner bemalte
Holzschnitzereien, die als Füllungen in diesem Tempel gedient
haben. Auf Postamenten chinesische und japanische Vasen, neben
ihnen an der Wand Teller und Schüsseln. In Vitrinen Keramik
chinesischer und japanischer Herkunft.
RAUM XXIV.
In den beiden großen Vitrinen Lackarbeiten in Schwarzlack und
Goldlack. An den Wänden in Vitrinen Figuren japanischer
Gottheiten, teils aus Holz geschnitzt und vergoldet, teils aus Lack,
und Objekte des täglichen Gebrauches aus verschiedenen
Materialien, wie kleine Hausaltärchen, Schalen, Schüsseln,
Kästchen etc.
Beim Fenster in einer Vitrine eine Kollektion von Netzhes
(Medizinbüchsen), Kämmen und Inros.
Bei den Fenstern je ein japanischer Reisekoffer.
RAUM XXV.
In diesem Raum ist an der Wand ein Behang in Webetechnik
ausgeführt und aus 11 Stücken zusammengesetzt chinesischer
Herkunft angebracht, davor eine buddhistische Gottheit und große
chinesische Fischbehälter mit Malerei aus Porzellan aufgestellt.
In der Vitrine beim Fenster chinesisches Porzellan.
RAUM XXVI.
In den Vitrinen an der Wand eine Kollektion teilweise alter
japanischer Waffen und chinesischer Porzellanfiguren. In der
Mittelvitrine Porzellane aus Satsuma.
Neben den Vitrinen japanische Lackkästchen.
XXVII. Porzellanzimmer. A. Keramische Sammlung. B.
Glassammlung. C. Vorlesesaal.
D. ZUBAU.
RAUM XXVII.
ALT-WIENER PORZELLANZIMMER, so genannt wegen des
reichen Porzellandekors aus der frühen Zeit der Wiener
Porzellanfabrik.
Die Türen und Türfüllungen, die Fenster und Fensterleibungen,
der Kaminaufsatz und die Lambrien sind aus Eichenholz und belegt
mit zahlreichen Porzellanplättchen, die in ornamentalen vergoldeten
Rähmchen aus Vergoldermasse gefaßt sind und, strenge
symmetrisch gehalten, aus dem Ende der Regierungszeit Karls VI.
stammen. Die Möbel haben vergoldete Holzgestelle, sind mit reicher
Schnitzerei verziert und mit Porzellanplättchen mit bunten
chinesischen Blumen verziert. Sie zeigen schon den Rokokostil
ebenso wie die ornamentalen vergoldeten Holzschnitzereien an den
Wänden. Auch die Bilderrahmen sind in diesem Stile gehalten, und
später etwas verändert worden, vielleicht zur selben Zeit, in der die
reich geschnitzte Wanduhr ausgeführt wurde, wohl in den achtziger
Jahren des XVIII. Jahrhunderts.
Die Wände und Möbel sind mit altem goldgelbem Brokat
überzogen.
Über das Porzellan in diesem Zimmer vgl. Seite 172.
KERAMIK.
Die keramische Sammlung ist im neuen Museumszubau im
ersten Stock aufgestellt und gibt ein anschauliches Bild der
Entwicklung dieses Industriezweiges von der Antike bis in die
Gegenwart.
Der Töpferton, ein Verwitterungsprodukt tonerdehaltiger
Gesteine, ist teils seiner natürlichen Beschaffenheit nach, teils
infolge künstlicher Beimengungen ein Material von außerordentlich
mannigfaltigen Qualitäten, dessen Verwendung in die Frühzeit
menschlicher Kultur zurückreicht. Verschiedenheiten des
keramischen Produktes ergeben sich aus der Beschaffenheit und
Zusammensetzung des Tones, der Stärke des Brandes, sowie aus
der Art des Überzuges, der Glasur.
Die wichtigsten Etappen in der Entwicklung der europäischen
Keramik bilden die Erfindung der Töpferscheibe, die Anwendung der
Zinnglasur und damit die Herstellung der echten Fayence und die
Entdeckung des Kaolintones, wodurch die Herstellung keramischer
Erzeugnisse ermöglicht wurde, welche dem ostasiatischen Porzellan
in allen wesentlichen Eigenschaften gleich kommen.
Die Aufstellung beginnt links vom Haupteingange mit der
Sammlung antiker Vasen und Terrakotten.[27]
ANTIKE KERAMIK.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebookgate.com