Book Software
Book Software
net/publication/347444165
CITATIONS READS
0 148
3 authors, including:
Some of the authors of this publication are also working on these related projects:
A Research on Process of Interaction Between Business Intelligence (BI) and SMES View project
All content following this page was uploaded by Vinayak Pujari on 18 December 2020.
SOFTWARE ENGINEERING
Asst Prof. Sachin Shankar Bhosale
Asst. Prof.. Vinayak Ishwar Pujari
Dr. Amol Vishnudas Patil
ISBN : 978-1-387-73178-7
Published by,
Lulu Publication
3101 Hillsborough St,
Raleigh, NC 27607,
United States.
Printed by,
Laxmi Book Publication,
258/34, RaviwarPeth,
Solapur, Maharashtra, India.
Contact No. : +91 9595 359 435
Website: http://www.lbp.world
Email ID: [email protected]
Acknowledgement
First and foremost, I would like to thank
Hon. Shri. Hirachand P.Butala,
President Shahajeewan Shikshan Sansta Khed,
Hon. Shri Mangesh P. Butala,
Secretory Shahajeewan Shikshan Sansta Khed,
Dr. G. B. Sarang, Prinipal I.C.S.College Khed,
Dr. A. M. Shaikh, I.C.S.College khed,
Mr.D.M.Shinde, I.C.S.College khed for standing beside me
throughout my career and writing this book. These all are my
inspiration and motivation for continuing to improve my
knowledge and move my career forward.
My co-Authors, Prof. Pujari V I and Dr. A. V. Patil, who
showed me the ropes in IT. Without that knowledge I wouldn’t
have shape this book, I’d really like to thank both of them for
providing me with the opportunity to become the lead author for
this book. I appreciate that they believed in me to provide the
leadership and knowledge to make this book a reality. I would
like to special thank my wife Mrs. Vijaya S. Bhosale to being
with me throughout completion of this book with all concerned.
I would like to express my gratitude to the many people
who saw me through this book; to all those who provided
support, talked things over, read, wrote, offered comments,
allowed me to quote their remarks and assisted in the editing,
proofreading and design.
Last and not least: I beg forgiveness of all those who have
been with me over the course of the years and whose names I
have failed to mention."
1|P a ge
INTRODUCTION TO SOFTWARE
ENGINEERING
3|P a ge
The job control language (JCL) raised a whole new class of
problems. The programmer had to write the program in a whole
new language to tell the computer and OS what to do. JCL was the
least popular feature of the 360.
"Structured Programming" burst on the scene in the middle
of this era.
PL/I, introduced by IBM to merge all programming
languages into one, failed.
Most customized applications continued to be done in-
house.
The Micro Era (1980-Present)
The price of computing has dropped dramatically making
ubiquitous computing possible. Now every programmer can have a
computer on his desk.
The old JCL has been replaced by the user-friendly GUI.
The software part of the hardware architecture that the
programmer must know about, such as the instruction set, has not
changed much since the advent of the IBM mainframe and the first
Intel chip.
The most-used programming languages today are between
15 and 40 years old. The Fourth Generation Languages never
achieved the dream of "programming without programmers" and
the idea is pretty much limited to report generation from databases.
There is an increasing clamor though for more and better
software research.
1.3 Software Characteristic
For a better understanding of the software, it is important
to examine the characteristics of software that make it different
from other things that human beings build. When hardware is built,
the human creative process (analysis, design, construction, testing)
is ultimately translated into a physical form. If we build a new
computer, our initial sketches, formal design drawings, and bread
boarded prototype evolve into a physical product (chips, circuit
4|P a ge
boards, power supplies, etc.). Since software is purely logical rather
than a physical system element, it therefore, has characteristics that
are entirely different than those of hardware:
1. Software is
developed or
engineered but it
is not
manufactured in
the classical
sense: Although some similarities exist between software
development and hardware manufacture, the two activities are
fundamentally different. In both activities, high quality is achieved
through good design, but the manufacturing phase for hardware can
introduce quality problems that are nonexistent (or easily corrected)
for software. The relationship, often called the "bathtub curve,"
indicates that hardware exhibits relatively high failure rates early in
its life (these failures are often attributable to design or
manufacturing defects); defects are corrected and the failure rate
drops to a steady-state level (ideally, quite low) for some period of
time. As time passes, however, the failure rate rises again as
hardware components suffer from the cumulative affects of dust,
vibration, abuse, temperature extremes, and many other
environmental maladies.
2. Consider the manner in which the control hardware for a
computer-based product is designed and built: The design engineer
draws a simple
schematic of the
digital circuitry,
does some
fundamental
analysis to assure
that proper function
will be achieved,
and then goes to the shelf where catalogs of digital components
exist. A software component should be designed and implemented
5|P a ge
so that it can be reused in different programs since it is a better
approach, according to finance and manpower. In the 1960s, we
built scientific subroutine libraries that were reusable in a broad
array of engineering and scientific applications. These subroutine
libraries reused well-defined algorithms in an effective manner but
had a limited domain of application. Today, we have extended our
view of reuse to encompass not only algorithms but also data
structure. Modern reusable components encapsulate both data and
the processing applied to the data, enabling the software engineer
to create new applications from reusable parts.
1.4 Types Of Software
The two main types of software are system software and
application software. Application software is programs that do work
users are directly interested in. System software includes operating
systems and any program that supports application software.
System software
System software controls a computer's internal functioning,
mainly through an operating System (OS), and also controls such
peripherals (attached devices) as monitors, printers, and storage
devices. The operating system allows all of the hardware and
software systems to work together. It manages the computer's
operations, controlling devices and overseeing other programs,
called applications.
An operating system consists of programs and routines that
coordinate operations and processes, translate the data from
various input and output devices, regulate data storage in memory,
allocate tasks to various processors, and provide functions that help
programmers to write software. In some specialized, or embedded,
computers the operating instructions are contained in their circuitry;
common examples are the microcomputers found in calculators,
wristwatches, automobile engines, and microwave ovens.
Application software
Application software directs the computer to execute
commands given by the user and may be said to include any
program that processes data for a user. Application software
includes:
6|P a ge
Games.
CAD/CAM software.
Database management.
Presentation software.
7|P a ge
1. System Software: - System Software is a collection of programs
written to service other programs. Some system Software (eg.
Compiler, editor)
2. Real-Time software : -software that monitor/analyzes/controls
real-world events as they occur is called real-time.
3. Business Software : - Business information processing is the
largest single software application area.
4. Engineering and Scientific Software : - Engineering and Scientific
software application area.
5. Artificial Intelligence Software: - Artificial Intelligence software
makes use of non-numerical algorithm to solve complex
problem that are not amenable to computation or
straightforward analysis.
1.6 What is Software Engineering
The need for systematic approaches to development and
maintenance of computer software systems became apparent in the
1960’s.During that decade, third-generation computing hardware
was inverted, and the software techniques of multiprogramming
and time-sharing were developed. To develop a software system,
initially, the user needs and constraints are identified.
Software engineering is the field of computer science that
deals with the building of software systems, which are large and
complex. It is a systematic, disciplined, quantifiable approach to the
development, maintenance of the software to ensure the best
solution most economically.
Software engineering is the technological and managerial
discipline concerned with systematic production and maintenance
of software products that are developed and modified on time and
within cost estimates
Engineering is the systematic application of scientific
knowledge in creating and building cost-effective solutions to
practical problems in the service of mankind.
8|P a ge
Software engineering is that form of engineering that
applies the principles of computer science and mathematics to
achieving cost-effective solutions to software problems.
Software engineering is that form of engineering that
applies the principles of computer science and mathematics to
achieving cost-effective solutions to software problems.
The practical application of scientific knowledge in the
design and construction of computer programs and the associated
documentation required to develop, operate, and maintain them. -
Boehm
Software engineering is the application of principles, skills,
and art to the design and construction of programs and systems of
programs. - Dennis
Software engineering is the technological and managerial
discipline concerned with the systematic production and
maintenance of software products that are developed and modified
on time and within cost estimates. – Fairley
Software engineering is the practical application of scientific
knowledge for the economical production and use of high-quality
software. - Pomberger and Blaschek
1.7 Software Engineering Concepts
The primary reason for this is that approaches to software
development are frequently ad hoc and programming-centered. The
ad hoc or programming-centered approach in developing is software
a programming exercise and it may work for small projects, but for
the problem domain that we are interested in, these approaches
generally do not work. If we have to control this software crisis,
some methodical approach is needed for software development.
This is where software engineering comes in. Software engineering
is defined as the systematic approach to the development,
operation, maintenance, and retirement of software.
Software engineering and traditional engineering disciplines
share the similar approach to development and maintenance of
technological artifacts. The fundamental sources of these
9|P a ge
differences are the lack of physical laws for software, the lack of
product visibility, and obscurity in the interfaces between software
modules.
Software engineering differs from traditional computer
programming in terms of engineering like techniques used to
specify, design, implement, validate and maintain software within
the time and budget constraints established for the project.
Another definition from the economic and human
perspective is given by combining the dictionary's definition of
engineering with its definition of software. This definition states:
Software Engineering is the application of science and
mathematics by which the capabilities of computer equipment are
made useful to man via computer programs, procedures, and
associated documentation.
The use of the terms systematic approach of mathematics
and science for the development of software means that software
engineering provides methodologies for developing software as
close to the scientific method as possible. That is, these
methodologies are repeatable, and if different people apply these
methodologies, similar software will be produced. In essence, the
goal of software engineering is to take software development closer
to science and away from being an art. Note also that the focus of
software engineering is not developing software per se, but
methods for developing software. That is, the focus is on developing
methods that can be used by various software projects.
The phrase useful to man emphasizes the needs of the user
and the software's interface with the user. This definition implies
that user needs should be given due importance in the development
of software, and the final program should give importance to the
user interface. With this definition of software engineering, let us
now discuss a few fundamental problems that software engineering
faces.
10 | P a g e
1.8 What does Software Engineering Involve?
It involves the elicitation of the system’s requirements, the
specification of the system, its architectural and detailed design. In
addition, the system needs to be verified and validated, a set of
activities that commonly take more than 50% of all development
resources. Testing techniques and tools, at different levels (unit,
integration, system) are needed. Software development being a
human intensive process, management and quality control
techniques are also required to run successful projects and
construct quality systems.
1.9 Importance of Software Engineering
In most systems, including telecommunication systems,
software is the overriding component in terms of cost and
complexity. Good software engineering practices and tools can
therefore make a substantial difference, even to the extent that
they may be the driving force of the project success.
1.10 Principle of software Engineering
Because the product of software engineering is not physical,
physical laws do not form a suitable foundation. Instead, software
engineering has had to evolve its principles based solely on
observations of thousands of projects. The following are probably
the 15 most important principles:
Make quality number one priority
High-quality software is possible
Give products to customers early
Determine the problem before writing requirements
Evaluate design alternatives
Use an appropriate process model
Use different languages for different phases
Minimize intellectual distance
Put technique before tools
Get it right before you make it faster
11 | P a g e
Inspect code
Good management is more important than good technology
People are the key to success
Follow hype with care
Take responsibility
1.11 Self-Test
1. Define software engineering and its principles.
2. Explain software engineering problems.
12 | P a g e
UNIT -2
13 | P a g e
SOFTWARE ENGINEERING
APPROACHES, PROBLEMS, CRISIS
AND MYTHS
14 | P a g e
transportation. These infrastructures depend increasingly on
networked information systems. Attacks against these systems can
threaten the economical or even physical well being of people and
organizations. There is widespread interconnection of information
systems via the Internet, which is becoming the world's largest
public electronic marketplace, while being accessible to untrusted
users. Attacks can be waged anonymously and from a safe distance.
If the Internet is to provide the platform for commercial
transactions, it is vital that sensitive information (like credit card
numbers or cryptographic keys) is stored and transmitted securely.
Developing secure software systems correctly is difficult and
error-prone. Many flaws and possible sources of misunderstanding
have been found in protocol or system specifications, sometimes
years after their publication (for example, the observations in (Lowe
1995) were made 17 years after the concerned well-known protocol
had been published in (Needham, Schroeder 1978). Much
vulnerability in fielded security-critical systems have been exploited,
sometimes leading to spectacular attacks. For example, as part of a
1997 exercise, an NSA hacker team demonstrated how to break into
U.S. Department of Defense computers and the U.S. electric power
grid system, among other things simulating a series of rolling power
outages and 911 emergency telephone overloads in Washington,
D.C., and other cities (Schneider 1999).
The problems that afflict software development can be
characterized from a number of different perspectives, but
managers responsible for software development tend to focus on
bottom line issues:
Schedule and cost estimates are often grossly inaccurate;
the productivity of software people hasn't kept pace with the
demand for software; the quality of software is sometimes less than
adequate. These problems are the most visible manifestations of
other software difficulties:
we have not taken time to collect data on the software
development process. With little historical data, estimation has
been produced in haste with predictably poor results;
15 | P a g e
customer dissatisfaction with the completed system is
encountered too frequently. Software development projects are
frequently undertaken with only a vague indication of the customer
requirements -communication between the customer and the
developer is often poor; software quality is often suspect. We have
only recently begun to understand the importance of systematic,
technically complete software testing. The software development
community is only just taken up quality assurance principles;
existing software can be difficult to maintain. Software maintenance
is the most expensive part of software development yet future
maintainability has not been emphasized as an important criteria for
software acceptance. So, that is the bad news. The good news is
that each of these problems can be corrected. A structured
approach to the development of software, together with continuing
improvement of the techniques and tools employed in the software
development process, provides the key.
2.3 Causes of the Problems
Problems associated with the software crisis have been
caused by the characteristics of software itself and by the failings of
the people charged with software development responsibility.
However, it is possible that we have expected too much in a short
space of time - after all our experience is only some 40 years old !
The major causes include: the logical nature of software provides a
challenge to the people who develop it. The intellectual challenge of
software development is considerable - we can not expect
individuals to always get the logic process correct; human error is
inevitable, we usually communicate with the machine through the
keyboard and not all typing errors will be picked up; middle and
upper-level managers with no background in software are often
given the responsibility for software development. There is an old
management axiom that states: 'A manager can manage any
project'. We should add: '...if they are willing to learn the milestones
that can be used to measure progress, apply effective methods of
control, disregard mythology, and become conversant in a rapidly
changing technology'. The manager must communicate with all
16 | P a g e
those involved in the software development: customers, software
developers, support staff, etc.;
software developers have little formal training in techniques
for software development. In some organizations anarchy still
reigns. Each individual approaches the task of writing programs with
experience derived from past efforts. Some people develop an
orderly and efficient approach to software development by trial and
error, but others develop bad habits that result in poor software
quality and maintainability; we all resist change, it is ironic however,
that while computing hardware experiences enormous change, the
software people responsible for tapping that potential often resist
change when it is introduced.
First reason for causes of problem is security requirements
are intrinsically subtle, because they have to take into account
interaction of the system with motivated adversaries that act
independently. Thus some security mechanisms, for example
security protocols, are notoriously hard to design correctly, even for
experts. Also, a system is only as secure as its weakest part or
aspect.
Secondly, risks are very hard to calculate because of a
positive reinforcement in the failure occurrence rates over repeated
system executions: security-critical systems are characterized by the
fact that the occurrence of a failure (that is, a successful attack) at
one system execution dramatically increases the likelihood that the
failure will occur at any following execution of a system with the
same part of the design. For some attacks (for example against web
sites), this problem is made worse by the existence of a mass
communication medium that is currently largely uncontrolled and
enables fast distribution of exploit information (again, the Internet).
Thirdly, many problems with security-critical systems arise
from the fact that their developers, who employ security
mechanisms, do not always have a strong background in computer
security. This is problematic since in practice, security is
compromised most often not by breaking dedicated mechanisms
17 | P a g e
such as encryption or security protocols, but by exploiting
weaknesses in the way they are being used.
Thus it is not enough to ensure correct functioning of used
security mechanisms; they cannot be "blindly" inserted into a
security-critical system, but the overall system development must
take security aspects into account. In the context of computer
security, "an expansive view of the problem is most appropriate to
help ensure that no gaps appear in the strategy".
Lastly, while functional requirements are generally analyzed
carefully in systems development, security considerations often
arise after the fact. Adding security as an afterthought, however,
often leads to problems (Gasser 1988, Anderson 2001). Also,
security engineers get few feedbacks about the secure functioning
of the developments in practice, since security violations are often
kept secret in fear of harm for a company's reputation.
It has remained true over the last 25 years that "no
complete method applicable to the construction of large general-
purpose systems exists yet" (Saltzer, Schroeder 1975) that would
ensure security, in spite of very active research and many useful
results addressing particular subgoals (Schneider 1999). Ad hoc
development has lead to many deployed systems that do not satisfy
relevant security requirements. Thus a sound methodology
supporting secure systems development is needed.
2.4 Software Crisis
The term software crisis has been frequently coined, the
Oxford English Dictionary defines crisis as:
'a decisive moment, a time of danger or great difficulty, a
turning point' yet for the software industry this crisis has been with
us for nearly 30 years - this is a contradiction. Authors have instead
proposed the term chronic affliction [Pressman, 1994]. Specifically,
the adjective chronic suggests longevity and reoccurrence - there
are no miracle cures, rather there are ways that we can reduce the
pain as we try to find a cure. Regardless of whether we use the term
software crisis or software affliction, the term alludes to a set of
18 | P a g e
problems that are encountered in the development of computer
software. The problems are not limited to software that doesn't
function properly. Rather, the affliction encompasses problems
associated with:
how we develop software; how we maintain the growing
volume of existing software
how we keep pace with the growing demand for software;
how we manage the software development process.
2.5 Software Myths
Myth is the most popular of all story forms, but it comes
with many hidden pitfalls. Myth uses the journey structure, which is
a very different kind of plotting technique than the one found in
some other genres where the hero has to dig under the surface to
get to the truth. Or writers think you can just rewrite the old myths.
But the old myths grew out of a local environment and a point of
view unique to that place and time.
2.6 Management Myths
Managers with software responsibility, like managers in
most disciplines, are often under pressure to maintain budgets,
keep schedules from slipping, and improve quality.
Myth: We already have a book that's full of standards and
procedures for building software. Won't that provide my people
with everything they need to know?
Reality: The book of standards may exist, but is it used? Are
software developers aware that it exists? Does it reflect modern
software development practice? Is it complete? In many cases the
answer to these questions is no.
Myth: My people have the latest software development tools; after
all we do buy them the latest computers.
Reality: It takes more than the latest computer to do high quality
software development. Computer-aided software engineering
(CASE) tools are more important than hardware for achieving good
quality and productivity, yet the majority of software developers still
do not use them.
19 | P a g e
Myth: If we get behind schedule we can add more programmers and
catch up.
Reality: Software development is not a mechanistic process like
manufacturing. In the words of Brook: '..Adding people to a late
software project makes it later'. As new people are added, those
who were originally working on it must spend time educating the
newcomers. People can be added but only in a planned and well co-
ordinated manner.
2.7 Customer Myths
Customers may not understand the nature of software
development; false expectations must be eliminated at the start.
Communication is essential.
Myth: A general statement of objectives is sufficient to start writing
programs - we can fill in the details later.
Reality: Poor up-front definition is the major cause of failed
software efforts. A formal and detailed description of the
information domain, function, performance, interfaces, design
constraints and validation criteria is essential. These characteristics
can be determined only after thorough communication between
customer and developer.
Myth: Project requirements continually change, but change can be
easily accommodated because software is flexible.
Reality: It is true that requirements do change, but the impact of
change varies with the time that it is introduced - the later in the
software development process, the more difficult change is to
accommodate.
2.8 Practitioner's Myths
Old ways and attitudes die-hard.
Myth: Once we write a program and get it to work, our job is done.
Reality: The majority of effort expended on a program will be after
the program has been delivered for the first time- maintenance.
Myth: Until I get the program running I have no way of assessing its
quality.
20 | P a g e
Reality: One of the most effective software quality assurance
mechanisms is the formal technical review. These can be
undertaken long before the program is running.
Myth: The only deliverable for a successful project is the working
program.
Reality: A working program is only one of the elements of the
project. Other elements include: project plans, requirements
specifications, system designs, test specifications, support
documentation etc. Documentation forms the foundation for
successful development and, more importantly, provides the
foundation for the software maintenance task.
2.9 Bringing Formality to the Software Development Process
Taking a high level view, we aim to transform our problem
domain from a complex, messy, irrational mass to a simple, ordered
model.
21 | P a g e
A model is a representation of part (or all) of a system; at a
given level of abstraction from a given perspective.
2.10 Self test
1. Explain software crisis and cause of software crisis.
2. Write a short note on:
i. Management myths
ii. Customer myths
iii. Role of software
22 | P a g e
UNIT -3
23 | P a g e
THE PROCESS, DESIGN CONCEPTS
AND MODELS
24 | P a g e
The TSP has been used with pure software teams and with mixed
teams of 2 to 20 hardware and software engineers and it has been shown
to sharply reduce the total cost of development and acquisition. TSP has
been used for both new development and enhancement and with both
commercial and imbedded real-time systems. A number of organizations
are using the TSP and this talk describes some of their experiences. Below
is a simple software production model using system dynamics, and next is
the output of a Raleigh-curve simulation of a software project.
Many persons work on producing software systems for many
users. The task description and the requirements frequently change even
during the program design phase, and their continue to change even after
the software system has long since been in use.
The major problems encountered in development of large
software systems were:
Correctness
Efficiency
Mastery of complexity
Interface specification
Reliability
Flexibility
Documentation
Maintainability
Project organization.
Inadequate theoretical foundation and too few methodological
aids were known in both the technical and the organizational realm.
Programmers’ qualifications did not suffice to adequately solve the
problems. The concept of process is the main step in the software
engineering approach. The process means "a particular method of doing
something, generally involving a number of steps or operations." In
software engineering, the phrase software process refers to the method of
developing software.
Software process teaches us how we can manage our planning
according to the constraints and Boundaries. A software process is a set of
activities, together with ordering constraints among them, such that if the
activities are performed properly and in accordance with the ordering
constraints, the desired result is produced. The desired result is, as stated
25 | P a g e
earlier, high-quality software at low cost. Clearly, a process does not scale
up i.e., cannot handle large software projects or cannot produce good-
quality software i.e., good-quality software is not the outcome is not a
suitable process.
In an organization whose major business is software development,
there are typically many processes simultaneously executing. Many of
these do not concern software engineering, though they do impact
software development. These could be considered non-software
engineering process models. Business process models, social process
models, and training models, are all examples of processes that come
under this. These processes also affect the software development activity
but are beyond the purview of software engineering.
The process that deals with the technical and management issues
of software development is called a software process. Clearly, many
different types of activities need to be performed to develop software. As
different type of activities are being performed, which are frequently done
by different people, it is better to view the software process as consisting
of many in component processes, each consisting of a certain type of
activity. Each of these component processes typically has a different
objective, though these processes obviously cooperate with each other to
satisfy the overall software engineering objective.
We know that in development process we have to pass through
various phases, and after each phase we expect some defined and
designed output. There are certain rules and logic and we must follow
them step by step. The phases are performed in an order specified by the
process model being followed. The main reason for having a phased
process is that it breaks the problem of developing software into
successfully performing a set of phases, each handling a different concern
of software development. This ensures that the cost of development is
lower than what it would have been if the whole problem was tackled
together. Furthermore, a phased process allows proper checking for quality
and progress at some defined points during the development (end of
phases). Without this, one would have to wait until the end to see what
software has been produced. Clearly, this will not work for large systems.
Hence, for managing the complexity, project tracking, and quality, all the
development processes consist of one set of phases. A phased
development process is central to the software engineering approach for
solving the software crisis.
26 | P a g e
3.2 Characteristics of a Software Process
The fundamental objectives of a process are the same as that of
software engineering namely, optimality and scalability. Optimality means
that the process should be able to produce high-quality software at low
cost, and scalability means that it should also be applicable for large
software projects. To achieve these objectives, a process should have some
properties.
1) Predictability
Predictability of a process determines how accurately the
outcome of following a process in a project can be predicted before the
project is completed. Predictability can be considered a fundamental
property of any process. Effective project management is essential for the
success of a project, and effective project management revolves around
the project plan. A project plan typically contains cost and schedule
estimates for the project, along with plans for quality assurance and other
activities. Any estimation about a project is based on the properties of the
project, and the capability or past experience of the organization. For
example, a simple way of estimating cost could be to say, "this project X is
very similar to the project Y that we did 3 years ago, hence X's cost will be
very close to Y's cost." However, even this simple method implies that the
process that will be used to develop project X will be same as the process
used for project Y, and the process is such that following the process the
second time will produce similar results as the first time. That is, this
assumes that the process is predictable. If it was not predictable, then
there is no guarantee that doing a similar project the second time using the
process will incur a similar cost.
It should be clear that if we want to use past experience to control
costs and ensure quality, we must use a process that is predictable. With
low predictability, the experience gained through projects is of little value.
A predictable process is also said to be under statistical control. A process
is under statistical control if following the same process produces similar
results.
2) Process Improvement
Process is also not a static entity it means we have to regularly
improve the process according to the need. Improving the quality and
reducing the cost of products are fundamental goals of any engineering
discipline. In the context of software, as the productivity and quality are
27 | P a g e
determined largely by the process, to satisfy the engineering objectives of
quality improvement and cost reduction, the software process must be
improved.
Having process improvement as a basic goal of the software
process implies that the software process used is such that it supports its
improvement. This requires that there be means for evaluating the existing
process and understanding the weaknesses in the process. Only when
support for these activities is available can process improvement be
undertaken. And, as in any evaluation, it is always preferable to have a
quantifiable evaluation rather than a subjective evaluation. Hence, it is
important that the process provides data that can be used to evaluate the
current process and its weaknesses.
Having process improvement as a fundamental objective requires
that the software process be a closed-loop process. That is, the process
must learn from previous experiences, and each project done using the
existing process must feed information back into the process itself, which
can then use this information for self-improvement. As stated earlier, this
activity is largely done by the process management component of the
software process. However, to support this activity, information from
various other processes will have to flow to the process management
process. In other words, to support this activity, other processes will also
have to take an active part.
3.3 Software Processes, Projects and Products:
A software process specifies a method of developing software. A
software project, on the other hand, is a development project in which a
software process is used. Software products are the outcomes of a
software project. Each software development project starts with some
needs and (hopefully) ends with some software that satisfies those needs.
A software process specifies the abstract set of activities that should be
performed to go from user needs to the final product. The actual act of
executing the activities for some specific user needs is a software project.
And all the outputs that are produced while the activities are being
executed are the products (one of which is the final software). One can
view the software process as an abstract type, and each project is done
using that process as an instance of this type. In other words, there can be
many projects for a process i.e., many projects can be done using a
process, and there can be many products produced in a project. This
relationship is shown in the following figure
28 | P a g e
Figure : Processes, projects, and products
The sequence of activities specified by the process is typically at
an abstract level because they have to be usable for a wide range of
projects. Hence, "implementing" them in a project is not straightforward.
To clarify this, let us take the example of traveling. A process for traveling
to a destination will be something like this: Set objectives for the travel
(tourism, business, meeting friends, etc.), determine the optimal means of
traveling which will depend on the objective, if driving is best determine
what type of vehicle is most desired; car, truck, or camper, get a detailed
map to reach the destination, plan details of the trip, get sufficient money,
rent the car, etc. If flying to the destination is best, then book flights,
reserve a car at the destination if needed, etc. In a sense, the process
provides a "checklist," with an ordering constraint e.g., renting a car as a
first step is sub optimal. If one has to go from New York to California (a
specific project), then even with this process, a considerable effort is
required to reach California. And this effort is not all passive; one has to be
alert and active to achieve this goal e.g., preparing a map and following the
map are not passive or trivial tasks.
3.4 Design Concept and Modeling
Design, it is a meaningful representation of something that is to be
built. It is based on user requirement as well as the quality of the design
should be good against some predefined criteria analysed during software
requirement specification.
Design provides a structured and refined view to the software
specification. Software requirement specification is a mean of translating
the ideas in the minds of the clients into a formal document. The
preparation of software requirement specification forces rigorous
specification of the requirement before the design begins. It also provide
flexibility to design. Design begins with the requirement model. During
29 | P a g e
design the requirement model transforms into four levels of design detail –
the data structure, the system architecture, the interface representation
and the component level detail. During each design activity basic design
concepts and principles are applied that gives high quality software.
3.5 Concepts
A design methodology is a systematic approach to creating a
design by application of a set of techniques and guidelines. The design
process often have two levels, at the first level the focus is one deciding
which modules are needed for the system, the specification of these
modules and how these module should be interconnected. This is called
System Design or Top Level Design. At the second level, the internal design
of the modules that is how the specification of the module can be satisfied
is decided upon. The design level is often called Detailed Design or Logic
Design.
A set of basic software design concepts evolved over the past
decades. Every concept provides the designer a base to produce good
quality software. It also provide the necessary framework for “getting it
right” that is how a software proved to be right.
3.6 Design Objectives
The beginning of the design phase marks a transaction from
describing what the solution looks like, “specifications” to how the problem
is going to be solved. The design document that we will develop during this
phase is the blueprint of the software. It describes how the solution to the
customer problem is to be built. Since solution to complex problems isn’t
usually found in the first try, iterations are most likely required. This is true
for software design as well. For this reason, any design strategy, design
method, or design language must be flexible and must easily accommodate
changes due to iterations in the design.
Complex problems aren’t usually solved in one step. Rather, they
are solved using the principle of “divide and conquer,” where the problem
is divided into a set of sub-problems that are solved more easily. The
partial solutions are than combined to become an overall problem solution.
Any technique or design needs to support and guide the partitioning
process in such a way that the resulting sub-problems are as independent
as possible from each other and can be combined easily for the solution to
the overall problem. Sub-problem independence and easy combination of
their solutions reduces the complexity of the problem. This is the objective
of the partitioning process. Partitioning or decomposition during design
involves three types of decisions: -
30 | P a g e
Define the boundaries along which to break; Determine into how
money pieces to break; and Identify the proper level of detail when design
should stop and implementation should start. Basic design principles that
enable the software engineer to navigate the design process suggest a set
of principles for software design, which have been adapted and extended
in the following list:
Free from the suffer from "tunnel vision." A good designer should
consider alternative approaches, judging each based on the requirements
of the problem, the resources available to do the job.
The design should be traceable to the analysis model. Because a
single element of the design model often traces to multiple requirements,
it is necessary to have a means for tracking how requirements have been
satisfied by the design model.
The design should not repeat the same thing. Systems are
constructed using a set of design patterns, many of which have likely been
encountered before. These patterns should always be chosen as an
alternative to reinvention. Time is short and resources are limited! Design
time should be invested in representing truly new ideas and integrating
those patterns that already exist.
The design should "minimize the intellectual distance" between
the software and the problem as it exists in the real world. That is, the
structure of the software design should (whenever possible) mimic the
structure of the problem domain.
The design should exhibit uniformity and integration. A design is
uniform if it appears that one person developed the entire thing. Rules of
style and format should be defined for a design team before design work
begins. A design is integrated if care is taken in defining interfaces between
design components.
The design activity begins when the requirements document for
the software to be developed is available. This may be the SRS for the
complete system, as is the case if the waterfall model is being followed or
the requirements for the next "iteration" if the iterative enhancement is
being followed or the requirements for the prototype if the prototyping is
being followed. While the requirements specification activity is entirely in
the problem domain, design is the first step in moving from the problem
domain toward the solution domain. Design is essentially the bridge
between requirements specification and the final solution for satisfying the
requirements.
31 | P a g e
The design of a system is essentially a blueprint or a plan for a
solution for the system. We consider a system to be a set of components
with clearly defined behavior that interacts with each other in a fixed
defined manner to produce some behavior or services for its environment.
A component of a system can be considered a system, with its own
components. In a software system, a component is a software module.
The design process for software systems, often, has two levels. At
the first level, the focus is on deciding which modules are needed for the
system, the specifications of these modules, and how the modules should
be interconnected. This is what is called the system design or top-level
design. In the second level, the internal design of the modules, or how the
specifications of the module can be satisfied, is decided. This design level is
often called detailed design or logic design. Detailed design essentially
expands the system design to contain a more detailed description of the
processing logic and data structures so that the design is sufficiently
complete for coding.
Because the detailed design is an extension of system design, the
system design controls the major structural characteristics of the system.
The system design has a major impact on the testability and modifiability of
a system, and it impacts its efficiency. Much of the design effort for
designing software is spent creating the system design.
The input to the design phase is the specifications for the system
to be designed. Hence, a reasonable entry criteria can be that the
specifications are stable and have been approved, hoping that the approval
mechanism will ensure that the specifications are complete, consistent,
unambiguous, etc. The output of the top-level design phase is the
architectural design or the system design for the software system to be
built. This can be produced with or without using a design methodology. A
reasonable exit criteria for the phase could be that the design has been
verified against the input specifications and has been evaluated and
approved for quality.
A design can be object-oriented or function-oriented. In function-
oriented design, the design consists of module definitions, with each
module supporting a functional abstraction. In object-oriented design, the
modules in the design represent data abstraction (these abstractions are
discussed in more detail later). In the function-oriented methods for design
and describe one particular methodology the structured design
methodology in some detail. In a function- oriented design approach, a
32 | P a g e
system is viewed as a transformation function, transforming the inputs to
the desired outputs. The purpose of the design phase is to specify the
components for this transformation function, so that each component is
also a transformation function. Hence, the basic output of the system
design phase, when a function oriented design approach is being followed,
is the definition of all the major data structures in the system, all the major
modules of the system, and how the modules interact with each other.
3.7 Design Principles
The design process is a sequence of steps that enables the
designer to describe all aspects of the software to be built upon. Basic
design principles enable the software engineer to navigate the design
process.
The principles adopted for software design are:
The design should be uniform that is rules and format should be
defined for a design team before design begins.
A design should be integrated so that if the individual component or
modules are combined then they should meet the user requirement.
The interfaces between the component should be defined carefully.
The design should minimize the intellectual distance between the
software and the problem as it exists in the real world.
The design should be traceable to the analysis model.
The design should be reviewed to minimize the conceptual error.
The design should be assessed for quality as it is being created, not
after the fact.
The design should be structured to degrade gently, even when
aberrant data, events or operating conditions are encountered.
The design should be flexible enough to accommodate the changes.
When all the design principles are properly applied, the software
engineer creates a design that exhibits both external and internal
quality factor.
3.8 Software engineering proccess models
Process model is a strategy which is used by software engineer or
a team of engineers that encompasses the process, methods, and tools.
Various models used in industry are:
Water fall model
Prototype model
Iterative enhancement model
Spiral model
33 | P a g e
3.9 Water fall model
This model was popularized in the 1970’s. The essence of this
model is that the process of software development consists of a set of
distinct phases. This phased model segments the software life cycle into a
series of successive activities.
34 | P a g e
b) Design - The purpose of the design phase is to plan a solution of the
problem specified by the requirements document. In this phase we
have to make sure that the steps designed for getting the solution are
complete and can achieve the goal. This focuses on high level design
(what programs are we going to need and how are they going to
interact), low level design (how the individual programs are going to
work), interface design (what are the interfaces going to look like) and
data design (what data are we going to need). The output of this phase
is the design document. At the end of system design all the major data
structures, file formats, output formats, and the major modules in the
system and their specifications are decided.
c) Implementation (Coding) - The designs are translated into code.
Computer programs may be written using a conventional
programming language to a fourth generation language (4GL) or an
application generator. The goal of the coding phase is to translate the
design of the system into code in a given programming language. For a
given design, the aim in this phase is to implement the design in the
best possible manner. During coding the focus should be on
developing programs that are easy to read and understand, and not
simply on developing programs that are easy to write. Simplicity and
clarity should be strived for during the coding phase.
d) Testing - Normally programs are written as a series of individual
modules. These should be subject to separate and detailed test. The
system is then tested as a whole - the separate modules are brought
together and tested as a complete system. Testing is a process to
maintain the quality control measure used during software
development. Its basic function is to detect errors in the software.
Testing is a process to maintain the quality control measure used
during software development. Its basic function is to detect errors in
the software. The system needs to be tested to ensure that interfaces
between modules work, the system works on the intended platform
and with the expected volume of data and that the system does what
the user requires.
3.9 Characteristics of Waterfall model
Specific activities, techniques and outcomes are associated with each
stage;
Progression between stages is orderly and proceeds in a linear fashion;
Viewed to be a process driven by technicians;
Monitoring and control takes place at the end of each stage;
35 | P a g e
3.10 Advantages and Limitations of Waterfall Model
Easy to explain the advantage to the user
Stages and activities are well defined
Ensures that information required is obtained as and when it needs to
be used
Helps to plan and schedule project
Verification at each stage ensures early detection of
errors/misunderstanding
Minimize the cost of rectifying errors.
Limitation of waterfall model:
This model is suitable to automate for which all requirements are
known before the design starts.
The waterfall model does not accommodate times.
Waterfall model is document driven.
It does not incorporate any kind of risk assessment.
3.11 Prototype Model
It is also known as evolutionary model. Prototyping is the process
of developing scaled down version of a system. It begins with requirements
gathering. Developers and client meet and define the overall objectives for
the software, identify whatever requirements are known, and outline areas
where further definition is mandatory. The prototype is a working model
that can be used for several purposes such as:
Validating the user’s requirements
Performing a feasibility study of a complex system
Arriving at the functional specifications of a system
Establishing a starting point of further evolution
36 | P a g e
Requirement
Analysis
Design Design Code Test
Code
Test
Requirement
Analysis
Figure : The prototyping model
The goal of a prototyping-based development process is to
counter the limitations of the waterfall model. The basic idea is that
instead of freezing the requirements before any design or coding can
proceed, a throwaway prototype is built to help understand the
requirements. This prototype is developed based on the currently known
requirements. Development of the prototype obviously undergoes design,
coding, and testing, but each of these phases is not done very formally or
thoroughly. By using this prototype, the client can get an actual feel of the
system, because the interactions with the prototype can enable the client
to better understand the requirements of the desired system. This results
in more stable requirements that change less frequently.
The development of the prototype starts when the preliminary
version of the requirements specification document has been developed.
At this stage, there is a reasonable understanding of the system and its
needs and of which needs are unclear or likely to change. After the
prototype has been developed, the end users and clients are given an
opportunity to use the prototype and use it. Based on their experience,
they provide feedback to the developers regarding the prototype: what is
correct, what needs to be modified, what is missing, what is not needed,
etc. Based on the feedback, the prototype is modified to incorporate some
of the suggested changes that can be done easily, and then the users and
the clients are again allowed to use the system. This cycle repeats until, in
the judgment of the prototypers and analysts, the benefit from further
changing the system and obtaining feedback is outweighed by the cost and
time involved in making the changes and obtaining the feedback. Based on
the feedback, the initial requirements are modified to produce the final
requirements specification, which is then used to develop the production
quality system. It is well suited for projects where requirements are hard to
determine and the confidence in obtained requirements is low. In such
37 | P a g e
projects, a waterfall model will have to freeze the requirements in order
for the development to continue, even when the requirements are not
stable.
3.12 Advantages and Limitations
It is a technique that allow for a reduced functionality or limited
performance
It serves as a mechanism for identifying software requirements.
It is well suited for projects where the requirements are hard to
determine.
It is an excellent technique for reducing risks associated with a project..
Limitations:
Limited functional capabilities
Low reliability
Untested performance
Prototyping tools are expensive
3.13 Prototype’s effect on software development cost
It reduces the cost of later phases of the product development.
The final system developed will be more closer to the actual requirement
because the user and developer gets involved in refining the system.
Requirement obtained after having the working experience with
the prototype tends to be more stable.
3.14 Iterative Enhancement Model
The iterative model combines the features of both waterfall and
prototype model. It supports the incremental building of the new system.
This model can be useful if the core of the application is well understood
and increments can be easily defined and negotiated .In client-oriented
projects, it is an advantage to the client can pay to the projects in
installments .The potential danger of this method is that the iteration may
never end the user may never really get the "final" product.
The basic idea of this model is that the software should be
developed in increments, each increment adding some functional
capability to the system until the full system is implemented. At each step,
extensions and design modifications can be made. An advantage of this
approach is that it can result in better testing because testing each
increment is likely to be easier than testing the entire system as in the
38 | P a g e
water- fall model. Furthermore, as in prototyping, the increments provide
feedback to the client that is useful for determining the final requirements
of the system.
In the first step of this model, a simple initial implementation is
done for a subset of the overall problem. This subset is one that contains
some of the key aspects of the problem that are easy to understand and
implement and which form a useful and usable system. A project control
list is created that contains, in order, all the tasks that must be performed
to obtain the final implementation. This project control list gives an idea of
how far the project is at any given step from the final system. Each step
consists of removing the next task from the list, designing the
implementation for the selected task, coding and testing the
implementation, performing an analysis of the partial system obtained
after this step, and updating the list as a result of the analysis. These three
phases are called the design phase, implementation phase, and analysis
phase. The process is iterated until the project control list is empty, at
which time the final implementation of the system will be available. One
effective use of this type of model is of product development, in which the
developers themselves provide the specifications and therefore have a lot
of control on what specifications go in the system and what stay out.
Design1 Designn
Design0
Implement1 Implementn
Implement0
Analysis1 Analysisn
Analysis0
Figure: The Iterative Enhancement Model
3.15 Spiral Model
This model proposed by Barry Boem in 1988.It incorporates the
elements of the prototype driven approach along with the classic software
life cycle. The four major activities of each spiral are represented by the
four quadrants:
PLANNING – determination of objectives, alternatives and constraints.
RISK ANALYSIS – analysis of alternatives and identification/resolving of
risks.
ENGINEERING - Development of the next level product
CUSTOMER EVALUTION - Assessment of the result of re-engineering.
39 | P a g e
The radial dimension represents the cumulative cost incurred in
accomplishing the steps done so far, and the angular dimension represents
the progress made in completing each cycle of the spiral. Each cycle in the
spiral begins with the identification of objectives for that cycle the different
alternatives that are possible for achieving the objectives, and the
constraints that exist. This is the first quadrant of the cycle (upper-left
quadrant). The next step in the cycle is to evaluate these different
alternatives based on the objectives and constraints. The focus of
evaluation in this step is based on the risk perception for the project. Risks
reflect the chances that some of the objectives of the project may not be
met. The next step is to develop strategies that resolve the uncertainties
and risks. This step may involve activities such as benchmarking,
simulation, and prototyping. Next, the software is developed, keeping in
mind the risks. Finally the next stage is planned.
The risk-driven nature of the spiral model allows it to
accommodate any mixture of a specification-oriented, prototype-oriented,
simulation-oriented, or some other type of approach. An important feature
of the model is that each cycle of the spiral is completed by a review that
covers all the products developed during that cycle, including plans for the
next cycle. The spiral model works for development as well as
enhancement projects.
40 | P a g e
3.16 Cocomo Model
Instead of having resource estimates as a function of one variable,
resources estimates can depend on many different factors, giving rise to
multivariable models. One approach for building multivariable models is to
start with an initial estimate determined by using the static single-variable
model equations, which depend on size, and then adjusting the estimates
based on other variables. This approach implies that size is the primary
factor for cost; other factors have a lesser effect. Here we will discuss one
such model called the Constructive Cost Model (COCOMO). This model also
estimates the total effort in terms of person-months of the technical
project staff. The effort estimate includes development, management, and
support tasks but does not include the cost of the secretarial and other
staff that might be needed in an organization. The basic steps in this model
are:
1. Obtain an initial estimate of the development effort from the estimate
of thousands of delivered lines of source code (KDLOC).
2. Determine a set of 15 multiplying factors from different attributes of
the project.
3. Adjust the effort estimate by multiplying the initial estimate with all
the multiplying factors.
The initial estimate (also called nominal estimate) is determined
by an equation of the form used in the static single-variable models, using
KDLOC as the measure of size. To determine the initial effort Ei in person-
months the equation used is of the type Ei = a * (KDLOC)b.
The value of the constants a and b depend on the project type. In
COCOMO, projects are categorized into three types -- organic,
semidetached, and embedded. Organic projects are in an area in which the
organization has considerable experience and requirements are less
stringent. A small team usually develops such systems. Examples of this
type of project are simple business systems, simple inventory management
systems, and data processing systems. Projects of the embedded type are
ambitious and novel; the organization has little experience and stringent
requirements for such aspects as interfacing and reliability. These systems
have tight constraints from the environment (software, hardware, and
people). Examples are embedded avionics systems and real-time command
systems. The semidetached systems fall between these two types.
Examples of semidetached systems include developing a new operating
system (OS), a database management system (DBMS), and a complex
inventory management system. The constants a and b for different systems
are given in Table 1.1.
41 | P a g e
There are 15 different attributes, called cost driver attributes, that
determine the multiplying factors. These factors depend on product,
computer, personnel, and technology attributes (called project attributes).
Examples of the attributes are required software reliability (RELY), product
complexity (CPLX), analyst capability (ACAP), application experience (AEXP),
use of modern tools (TOOL), and required development schedule (SCHD).
Each cost driver has a rating scale, and for each rating, a multiplying factor
is provided. For example, for the product attribute RELY the rating scale is
very low, low, nominal, high, and very high (and in some cases extra high).
The multiplying factors for these ratings are .75, .88, 1.00, 1.15, and 1.40,
respectively. So, if the reliability requirement for the project is judged to be
low then the multiplying factor is .75, while if it is judged to be very high
the factor is 1.40. The attributes and their multiplying factors for different
ratings are shown in Table 1.2. The COCOMO approach also provides
guidelines for assessing the rating for the different attributes.
Table 1.1: Constants for different project types
System a b
Organic 3.2 1.05
Semidetached 3.0 1.12
Embedded 2.8 1.20
Table 1.2: Effort multipliers for different cost drivers.
Very Very
Rating Cost Drivers Low Normal High
Low High
Product Attributes
RELY, required reliability .75 .88 1.00 1.15 1.40
DATA, database size .94 1.00 1.08 1.16
CPLX, product complexity .70 .85 1.00 1.15 1.30
Computer Attributes
TIME, execution time constraint 1.00 1.11 1.30
STOR, main storage constraint 1.00 1.06 1.21
VITR, virtual machine volatility .87 1.00 1.15 1.30
TURN, computer turnaround time .87 1.00 1.07 1.15
Personnel Attributes
ACAP, analyst capability 1.46 1.19 1.00 .86 .71
AEXP, application experience1 .29 1.13 1.00 .91 .82
PCAP, programmer capability 1.42 1.17 1.00 .86 .70
VEXP, virtual machine experience 1.21 1.10 1.00 .90
LEXP. programming language experience 1.14 1.07 1.00 .95
Project Attributes
MODP, modem programming practices 1.24 1.10 1.00 .91 .82
TOOL, use of SW tools 1.24 1.10 1.00 .91 .83
SCHED, development schedule 1.23 1.08 1.00 1.04 1.10
42 | P a g e
The multiplying factors for all 15 cost drivers are multiplied to get
the effort adjustment factor (EAF). The final effort estimate, E, is obtained
by multiplying the initial estimate by the EAF: E = EAF * Ei-------------- (3-1)
As we discussed earlier, the value of the constants for a cost
model depend or the process and thus have to be determined from past
data about the usage of that process. COCOMO has instead provided
"global" constant values. This might work because it requires some
characteristics about the process (e.g., it is well managed) and it provides
some means to fine-tune the estimate for a particular process. For
example, if the process relies less on tools, the estimate can be "corrected"
for this type of process by suitably choosing the value for the TOOL
attribute.
Still, there is little data to support that these constants are globally
applicable, and to apply COCOMO in an environment, these may need to
be tailored for the specific environment. One way is to start with the
COCOMO-supplied constants until data for some completed projects is
available. With this data, by keeping the exponent in the equations for
initial effort estimate fixed, the value of the other constant can be
determined through regression analysis so that the data best fits the
equation. This will be a simpler regression analysis as only one constant has
to be determined rather than two in the standard regression line fitting
discussed earlier. With more data, the value of the exponent can also be
fine-tuned. Changing both constants together requires a lot more data for
regression analysis to be significant. For a particular process or
environment, all the attributes might not be significant, and it might be
possible to merge some of them into a single attribute.
By this method, the overall cost of the project can be estimated.
For planning and monitoring purposes, estimates of the effort required for
the different phases are also desirable. In COCOMO, effort for a phase is
considered a defined percentage of the overall effort. The percentage of
total effort spent in a phase varies with the type and size of the project.
The percentages for an organic software project are given in Table 1.3.
Using this table, the estimate of the effort required for each phase
can be deter- mined from the total effort estimate. For example, if the total
effort estimate for an organic software system is 20 PM, then the
percentage effort for the coding and unit testing phase will be 40 + (38 -
40)/(32 -8) * 20 -39%. The estimate for the effort needed for this phase is
7.8 PM. This table does not list the cost of requirements as a percentage of
43 | P a g e
the total cost estimate because the project plan (and cost estimation) is
being done after the requirements are complete. In COCOMO the detailed
design and code and unit testing are sometimes combined into one phase
called the programming phase.
Table 1.3: Phase-wise distribution of effort
Size
Small Medium Large
Phase Intermediate
2 KDLOC 32 KDLOC 28 KDLOC
8 KDLOC
Product design 16 16 16 16
Detailed design 26 25 24 23
Code and unit test 42 40 38 36
Integration and test 16 19 22 25
For the other two types of software systems, the percentages are
slightly different, with the percentage for product design and integration
and testing increasing slightly and the percentage of coding decreasing
slightly.
COCOMO provides three levels of models of increasing
complexity: basic, intermediate, and detailed. The model described earlier
is the intermediate COCOMO model. The detailed model is the most
complex. It has different multiplying factors for the different phases for a
given cost driver. The set of cost drivers applicable to a system or module is
also not the same as the drivers for the system level. However, it might be
too detailed for many applications. We will follow the intermediate model
described earlier, even for detailed estimates. COCOMO also provides help
in determining the rating of different attributes and performing sensitivity
and trade-off analysis.
3.17 Self Test
1. Describe Waterfall model.
2. Differentiate between waterfall model & iterative model.
3. Write a short note on COCOMO model
44 | P a g e
UNIT - 4
45 | P a g e
PROJECT SCHEDULING AND
TRACING
46 | P a g e
more subjective assessments of complexity can be established early
in the planning process.
Project size is another important factor that can affect the
accuracy and efficacy of estimates. As size increases, the
interdependency among various elements of the software grows
rapidly. Problem decomposition, an important approach to
estimating, becomes more difficult because decomposed elements
may still be formidable.
The degree of structural uncertainty also has an effect on
estimation risk. In this context, structure refers to the degree to
which requirements have been solidified, the ease with which
functions can be compartmentalized, and the hierarchical nature of
the information that must be processed.
Risk is measured by the degree of uncertainty in the
quantitative estimates established for resources, cost, and schedule.
If project scope is poorly understood or project requirements are
subject to change, uncertainty and risk become dangerously high.
The software planner should demand completeness of function,
performance, and interface definitions (contained in a System
Specialization). The planner, and more important, the customer
should recognize that variability in software requirements means
instability in cost and schedule.
However, a project manager should not become obsessive
about estimation. Modern software engineering approaches take an
iterative view of development. In such approaches, it is possible to
revisit the estimate (as more information is known) and revise it
when the customer makes changes to requirements.
4.3 Cost Estimation
For a given set of requirements it is desirable to know how
much it will cost to develop the software to satisfy the given
requirements, and how much time development will take. These
estimates are needed before development is initiated. The primary
reason for cost and schedule estimation is to enable the client or
developer to perform a cost-benefit analysis and for project
47 | P a g e
monitoring and control. A more practical use of these estimates is in
bidding for software projects where the developers must give cost
estimates to a potential client for the development contract.
As we specify the system more fully and accurately, the
uncertainties are reduced and more accurate estimates can be
made. For example, once the requirement are completely specified,
more accurate cost estimates can be made compared to the
estimates after the feasibility study. Once the design is complete,
the estimate can be made still more accurately. The obtainable
accuracy of the estimates as varies with the different phases is
shown in the following figure.
49 | P a g e
higher the development cost. In fact, the cost increase with
reliability is not linear and is often exponential.
The goal of a cost model is to determine which of these
many parameters have a "significant" effect on cost and then to
discover the relationships between the cost and these
characteristics. These characteristics should be such that we can
measure or estimate them accurately. The most common approach
for determining the significant parameters and their relationship to
cost is to build models through regression analysis, where cost is the
dependent variable and the parameters are the independent
variables.
As this approach uses historical data to predict future data
points, this approach has one clear implication. This approach can
be applied only if the process is under statistical control. If this is not
the case, then the past is no reflection of the future, and a
regression-type model cannot be used. It also follows that the cost
models are process-dependent, as they should be; the cost of
developing a software is more if an inefficient process is followed.
The most common approach for estimating effort is to make
it a function of a single variable (this is also the simplest from the
point of view of model building). Often this variable is the project
size, and the equation of effort is considered
EFFORT = a * SlZE (b),
where a and b are constants. Values for these constants for
a particular process are determined through regression analysis,
which is applied to data about the projects that has been performed
in the past. For example, on analyzing the data of more than 60
projects done at IBM Federal Systems Division, ranging from 4000 to
467000 lines of delivered source code, it was found that if the size
estimate is in thousands of delivered lines of code (KDLOC), the total
effort, E, in person-months (PM) can be given by the equation
E=-5.2(KDLOC)X0.91.
A similar study on smaller projects showed that the data fits
a straight line quite well, and the equation is of the form ,
50 | P a g e
EFFORT=a * SIZE + b,
where a and b are again constants obtained by analysis of
data of past projects. These equations suggest that the project cost
increases linearly with the size of the final product for small systems
but has nonlinear growth for larger projects.
These models have used LOC as the size measure. Similar
models have been developed with function point as the size
measure. The process of constructing the model is the same-
regression analysis on function point size and cost of previously
completed projects. An advantage of using function points is that
the size in FP can be calculated, while size in LOC will require size
estimation can be done. However, function point calculation also
involves subjectivity. Due to this, the FP count is not uniquely
determined even at the end of the project, unlike the LOC count,
which makes the task of getting] accurate and consistent data on
past projects harder. Note that most of these models will not work
for very small projects because for such projects factors other than
size become far more important.
4.5 Process-Based Estimation
The most common technique for estimating a project is to
base the estimate on the process that will be used. That is, the
process is decomposed into a relatively small set of tasks and the
effort required to accomplish each task is estimated.
Like the problem-based techniques, process-based
estimation begins with a delineation of software functions obtained
from the project scope. A series of software process activities must
be performed for each function. Functions and related software
process activities may be represented as part of a table similar to
the one.
Once problem functions and process activities are decided,
the planner estimates the effort (e.g., person-months) that will be
required to accomplish each software process activity for each
software function. These data constitute the central matrix of the
table. Average labour rates (i.e., cost/unit effort) are then applied to
51 | P a g e
the effort estimated for each process activity. It is very likely the
labour rate will vary for each task. Senior staff heavily involved in
early activities are generally more expensive than junior, staff
involved in later design tasks, code generation, and early testing.
52 | P a g e
schedule estimation is to determine the total duration of the project
and the duration of the different phases. A schedule cannot be
simply obtained from the overall effort estimate by deciding on
average staff size and then determining the total time requirement
by dividing the total effort by the average staff size. Brooks has
pointed out that person and months (time) are not interchangeable.
Man and months are interchangeable only for activities that require
no communication among men, like sowing wheat or Leaping
cotton.
Once the project is underway control needs to be exerted to
ensure that the plan continues to represent the best prediction of
what will occur in the future:
based on what occurs during the development;
often necessitates revision of the plan.
Effective project planning will help to ensure that the systems
are delivered:
within cost;
within the time constraint;
to a specific standard of quality.
4.7 Design Tools and Techniques
During the design phase there are two things of interest: the
design of the system, producing which is the basic objective of this
phase, and the process of designing itself. It is for the latter that
principles and methods are needed. In addition, while designing, a
designer needs to record his thoughts and decisions and to
represent the design so that he can view it and play with it. For this,
design notations are used.
Design notations are largely meant to be used during the
process of design and are used to represent design or design
decisions. They are meant largely for the designer so that he can
quickly represent his decisions in a compact manner that he can
evaluate and modify. These notations are frequently graphical.
53 | P a g e
Once the designer is satisfied with the design he has
produced, the design is to be precisely specified in the form of a
document. To specify the design, specification languages are used.
Producing the design specification is the ultimate objective of the
design phase. The purpose of this design document is quite different
from that of the design notation. Whereas a design represented
using the design notation is largely to be used by the designer, a
design specification has to be so precise and complete that it can be
used as a basis of further development by other programmers.
Generally, design specification uses textual structures, with design
notation helping understanding.
4.8 Structure Charts
For a function-oriented design, the design can be
represented graphically by structure charts. The structure of a
program is made up of the modules of that program together with
the interconnections between modules. Every computer program
has a structure, and given a program its structure can be
determined. The structure chart of a program is a graphic
representation of its structure. In a structure chart a module is
represented by a box with the module name written in the box. An
arrow from module A to module B represents that module A invokes
module B. B is called the subordinate of A, and A is called the super
ordinate of B. The arrow is labeled by the parameters received by B
as input and the parameters returned by B as output, with the
direction of flow of the input and output parameters represented by
small arrows. The parameters can be shown to be data (unfilled
circle at the tail of the label) or control (filled circle at the tail). As an
example consider the structure of the following program, whose
structure is shown in Figure below.
54 | P a g e
In general, procedural information is not represented in a
structure chart, and the focus is on representing the hierarchy of
modules. However, there are situations where the designer may
wish to communicate certain procedural information explicitly, like
major loops and decisions. Such information can also be
represented in a structure chart. For example, let us consider a
situation where module A has subordinates B, C, and D, and A
repeatedly calls the modules C and D. This can be represented by a
looping arrow around the arrows joining the subordinates C and D
to A, as shown in Figure. All the subordinate modules activated
within a common loop are enclosed in the same looping arrow.
55 | P a g e
Figure : The Structure Chart of the Sort Program
56 | P a g e
subordinates. Such modules are called coordinate modules. The
structure chart representation of the different types of modules is
shown in Figure.
A module can perform functions of more than one type of
module. For example, the composite module in Figure 4.4 is an input
module from the point of view of its super ordinate, as it feeds the
data Y to the super ordinate. Internally, A is a coordinate module
and views its job as getting data X from one subordinate and passing
it to another subordinate, which converts it to Y. Modules in actual
systems are often composite modules.
58 | P a g e
Example of a Gantt Chart
Which tasks is ahead of schedule ? Which task is behind schedule ?
Alternative Gantt Chart incorporating features commonly present in
automated tools:
60 | P a g e
The critical path = total time for activities on this path is
greater than any other path through the network (delay in any task
on the critical path leads to a delay in the project).
Tasks on the critical path therefore need to be monitored
carefully. The technique can be broken down into 3 stages:
1. Planning:
identify tasks and estimate duration of times;
arrange in feasible sequence;
draw diagram.
2. Scheduling:
establish timetable of start and finish times.
3. Analysis:
establish float;
evaluate and revise as necessary.
4.3.1 Diagram Symbols
62 | P a g e
transformation function that transforms the given inputs into the
desired outputs, and the central problem of designing software
systems is considered to be properly designing this transformation
function. Due to this view of software, the structured design
methodology is primarily function-oriented and relies heavily on
functional abstraction and functional decomposition.
The concept of the structure of a program lies at the heart
of the structured design method. During design, structured design
methodology aims to control and influence the structure of the final
program. The aim is to design a system so that programs
implementing the design would have a nice hierarchical structure,
with functionally cohesive modules and as few interconnections
between modules as possible.
In properly designed systems it is often the case that a
module with subordinates does not actually perform much
computation. The bulk of actual computation is performed by its
subordinates, and the module itself largely coordinates the data
flow between the subordinates to get the computation done. The
subordinates in turn can get the bulk of their. work done by their
subordinates until the "atomic" modules, which have no
subordinates, are reached. Factoring is the process of decomposing
a module so that the bulk of its work is done by its subordinates. A
system is said to be completely factored if all the actual processing is
accomplished by bottom-level atomic modules and if non atomic
modules largely perform the jobs of control and coordination. SDM
attempts to achieve a structure that is close to being completely
factored.
The overall strategy is to identify the input and output
streams and the primary transformations that have to be performed
to produce the output. High-level modules are then created to
perform these major activities, which are later refined. There are
four major steps in this strategy:
Restate the problem as a data flow diagram
Identify the input and output data elements
First-level factoring
Factoring of input, output, and transform branches
63 | P a g e
To use the SD methodology, the first step is to construct the
data flow diagram for the problem. However, there is a fundamental
difference between the DFDs drawn during requirements analysis
and during structured design. In the requirements analysis, a DFD is
drawn to model the problem domain. The analyst has little control
over the problem, and hence his task is to extract from the problem
all the information and then represent it as a DFD.
During design activity, we are no longer modeling the
problem domain, but rather are dealing with the solution domain
and developing a model for the eventual system. That is, the DFD
during design represents how the data will flow in the system when
it is built. In this modeling, the major transforms or functions in the
software are decided, and the DFD shows the major transforms that
the software will have and how the data will flow through different
transforms. So, drawing a DFD for design is a very creative activity in
which the designer visualizes the eventual system and its processes
and data flows. As the system does not yet exist, the designer has
complete freedom in creating a DFD that will solve the problem
stated in the SRS. The general rules of drawing a DFD remain the
same; we show what transforms are needed in the software and are
not concerned with the logic for implementing them. Consider the
example of the simple automated teller machine that allows
customers to withdraw money. A DFD for this ATM is shown in the
following figure.
65 | P a g e
converted into a form on which the transformation can be applied
with ease. Similarly, the main transformation modules often
produce outputs that have to be converted into the desired physical
output. The goal of this second step is to separate the transforms in
the data flow diagram that convert the input or output to the
desired format from the ones that perform the actual
transformations.
For this separation, once the data flow diagram is ready, the
next step is to identify the highest abstract level of input and output.
The most abstract input data elements are those data elements in
the data flow diagram that are furthest removed from the physical
inputs but can still be considered inputs to the system. The most
abstract input data elements often have little resemblance to the
actual physical data. These are often the data elements obtained
after operations like error checking, data validation, proper
formatting, and conversion are complete.
Most abstract input (MAI) data elements are recognized by
starting from the physical inputs and traveling toward the outputs in
the data flow diagram, until the data elements are reached that can
no longer be considered incoming. The aim is to go as far as possible
from the physical inputs, without losing the incoming nature of the
data element. This process is performed for each input stream.
Identifying the most abstract data items represents a value
judgment on the part of the designer, but often the choice is
obvious.
Similarly, we identify the most abstract output data
elements (MAO) by starting from the outputs in the data flow
diagram and traveling toward the inputs. These are the data
elements that are most removed from the actual outputs but can
still be considered outgoing. The MAO data elements may also be
considered the logical output data items, and the transforms in the
data flow diagram after these data items are basically to convert the
logical output into a form in which the system is required to produce
the output.
66 | P a g e
There will usually be some transforms left between the
most abstract input and output data items. These central transforms
perform the basic transformation for the system, taking the most
abstract input and transforming it into the most abstract output.
The purpose of having central transforms deal with the most
abstract data items is that the modules implementing these
transforms can concentrate on performing the transformation
without being concerned with converting the data into proper
format, validating the data, and so forth. It is worth noting that if a
central transform has two outputs with a + between them, it often
indicates the presence of a major decision in the transform (which
can be shown in the structure chart).
Consider the data flow diagram shown in Figure (Word
count problem). The arcs in the data flow diagram are the most
abstract input and most abstract output. The choice of the most
abstract input is obvious. We start following the input. First, the
input file is converted into a word list, which is essentially the input
in a different form. The sorted word list is still basically the input, as
it is still the same list, in a different order. This appears to be the
most abstract input because the next data (i.e., count) is not just
another form of the input data. The choice of the most abstract
output is even more obvious; count is the natural choice (a data that
is a form of input will not usually be a candidate for the most
abstract output). Thus we have one central transform, count-the-
number-of-different-words, which has one input and one output
data item.
Consider now the data flow diagram of the automated
teller. The two most abstract inputs are the dollar amount and the
validated account number. The validated account number is the
most abstract input, rather than the account number read in, as it is
still the input-but with a guarantee that the account number is valid.
The two abstract outputs are obvious. The abstract inputs and
outputs are marked in the data flow diagram.
4.13 Self Test
1. Explain Project Scheduling.
2. Define Gantt Chart.
67 | P a g e
UNIT -5
68 | P a g e
RISK ANALYSIS
69 | P a g e
According to most definitions, risk refers only to the possible
negative effects of a certain action. Risk, however, is always also
connected with opportunities and benefits (‘no risk, no fun’). The
reason for this is that risk is a consequence of uncertainty, for
example of uncertainties in our assumptions or of uncertainty about
future developments and events. In some disciplines such as
portfolio theory, risk is actually defined as a measure of uncertainty
and thus refers to negative as well as to positive consequences. As
an example, shows risk versus return data for different investment
possibilities. Here, risk is defined as the volatility (standard
deviation) of the observed statistical price fluctuations. This
uncertainty, however, can have a positive or negative sign, so the
actual return can just as easily be lower or higher than its expected
value.
71 | P a g e
prioritizing them. Risk custodian is an individual who has
responsibility for monitoring, controlling and minimizing the
project’s residual risks. Risk diary is a logbook maintained by the risk
process manager which should, inter alia, contain a record of key
events in the planning and execution of the RAMP process, any
problems encountered and unforeseen risks which arose, the results
of the risk reviews and ways in which future risk reviews or the
RAMP process itself could be improved. Risk event is the occurrence
of an event which has the potential to affect the viability of a
project. The process of managing risks identified in the risk review
using the risk mitigation strategy and the risk response plan is
known as Risk management. Risk matrix is the presentation of
information about risks in a matrix format , enabling each risk to be
presented as the cell of a matrix whose rows are usually the stages
in the investment life-cycle and whose columns are different causes
of risk . A risk matrix is useful as a checklist of different types of risk,
which might arise over the life of a project, but it must always be
supplemented by other ways of discovering risks (see Appendix 3 for
a specimen risk matrix). Risk mitigation strategy is an overall plan for
mitigating the risks in the investment activity. An individual who
plan, lead and co-ordinate the RAMP process is known as Risk
process manager. Risk register is a list of risks identified in the risk
review process, including full descriptive detail and cross-references.
A plan (prepared towards the end of the risk review) for controlling
the risks once implementation begins is known as Risk response
plan. Risk review is an overall assessment of the risks involved in a
project, their magnitude and their optimal management. Risk
reviews can in principle be held at any stage in the life of a project
with each review building on the results of previous ones. Each risk
review should be preceded by a risk review plan. Risk reviews should
generate information for inclusion in the risk register, risk mitigation
strategy and risk response plan. The results of a risk review should
be set out in a risk review report.
There is risk in every program. Project managers need to
develop information about risk early in the project so they can
72 | P a g e
mitigate its impact on project objectives. Also, risk must be
addressed continuously because risks are evolving. Risk analysis; (1)
identifies and quantifies the likelihood of risk events' occurring and
their potential impact on achieving program objectives, (2) develops
contingency amounts and (3) identifies the most important risks in
the program for risk management.
Information about risk can be qualitative or quantitative.
The information is based on informed, expert judgment. The cultural
context may be an important impediment to conducting effective
risk analyses. Institutional biases against discussing risk openly often
confound the risk management process. The importance and
methods of gathering unbiased information on program risk are
paramount. The project participants should communicate about risk
within the program often and in unambiguous language.
5.3 Risk Assessment
Complex risks may depend on a large number of uncertain
factors and variables. The risk of losing money by generating and
selling electricity, for example, depends on fuel and electricity
prices, on failure and outage rates, on daily and seasonal
temperatures, etc. These factors are all random variables and can
thus only be described in terms of a probability distribution. To
determine the ultimate quantity of interest, the probability
distribution of profit and loss, we not only have to assess the
individual uncertainties, but also need a model that quantitatively
describes how our revenues depend on the different influencing
factors. Only if such a model is available will we be able to use
techniques from probability theory to correctly aggregate the
individual probability distributions into the probability distribution
for profit and loss.
A basic problem of risk assessment is that the risks we are
trying to estimate refer to future events, but the available data only
refers to past observations. We thus assume that these risks do not
change significantly over the period of time relevant for our analysis.
We can, of course, observe trends and use them to forecast changes
in certain risk characteristics, but while this may improve our
73 | P a g e
estimates, it can never completely eliminate the inherent
uncertainty associated with an assessment of risks in real-world
situations.
If historical data are scarce, statistical methods become very
unreliable, and in many cases there may be no historical data at all.
Then, the assessment of risks has to be based on expert judgments.
Experts, though, usually do not express their statements in terms of
probability distributions. We thus need adequate procedures to
transform their qualitative and quantitative information into an
appropriate probabilistic description.
5.4 Risk Evaluation
According to classical economic theories, rational decisions
should only be based on the expected value of gains and losses. To
illustrate this, assume that you can choose between two options: a
sure gain of $40 and a gamble that gives you a 50 percent chance of
winning either $100 or nothing. The expected value of the gamble
(0.5 ¥ $ 100 + 0.5 ¥ $0 = $ 50) is higher than that of the certain
outcome ($ 40), so that a rational player should prefer the gamble. A
sure loss of $40, on the other hand, should be preferred to a gamble
that gives you a 50 percent chance of losing $ 100 and a 50 percent
chance of losing nothing. [The expected value of this gamble (-$ 50)
is worse than that of the certain loss (– $ 40).] A person (or
company) acting according to these principles is said to be ‘risk-
neutral.’
74 | P a g e
Recent investigations have shown, however, that most
people behave in a risk-averse way with respect to gains and in a
risk-seeking way with respect to losses. When confronted with the
choices described above, most people prefer the certain gain of $ 40
to the risky 50 percent chance of winning $ 100. In the case of
losses, on the other hand, the majority prefer to risk the 50 percent
chance of losing $ 100, rather than accept the sure loss of $ 40.
Risk preferences can conveniently be described in terms of a
so-called utility or value function [3]. This function represents the
subjective value of different gains and losses, and decisions are now
based on a comparison of expected value, rather than on expected
gain or loss.
5.5 Risk Management
Over the past two or three decades, demand for risk
management has increased dramatically. The main reason is the
growing number and complexity of risks. On top of this, the
increased attention is linked to the recent development of powerful
techniques for estimating and analyzing different types of risk,
especially in the finance sector.
The purpose of risk management is to minimize the risks
over which we have some control and, if possible, avoid or eliminate
the risks that are beyond our influence. The main steps in a
comprehensive risk management procedure are:
Risk identification
Risk assessment (quantification and aggregation of all relevant
risk factors)
Risk evaluation (in terms of well-defined risk measures and
criteria)
Risk control (according to a company-wide risk policy that
includes a specification of risk limits and of mitigation and
reporting requirements)
5.6 Self Test
1. Explain Risk Analysis.
2. Explain Risk Management and Risk Assessment.
75 | P a g e
UNIT -6
76 | P a g e
SOFTWARE METRICS
78 | P a g e
the collection of one or more data points (e.g., a number of module
reviews are investigated to collect measures of the number of errors
for each). A software metric relates the individual measures in the
same way (e.g., the average number of errors found per review or
the average number of errors found per person-hour expended on
reviews).
A software engineer collects, measures and develops
metrics so that indicators will be obtained. An indicator is a metric
or combination of metrics that provide insight into the software
process, a software project, or the product itself. An indicator
provides insight that enables the project manager or software
engineers to adjust the process, the project, or the process to make
things better.
For example, four software teams are working on a large
software project. Each team must conduct design reviews but is
allowed to select the type of review that it will use. Upon
examination of the metric, errors found per person-hour expended,
the project manager notices that the two teams using more formal
review methods exhibit an errors found per person-hour expended
that is 40 percent higher than the other teams. Assuming all other
parameters equal, this provides the project manager with an
indicator that formal review methods may provide a higher return
on time investment than another, less formal review approach. She
may decide to suggest that all teams use the more formal approach.
The metric provides the manager with insight. And insight leads to
informed decision making.
6.3 Software Metrics Type
Metrics provide the scale for quantifying qualities. Metrics
can be categorized into two: Direct metrics and indirect metrics.
Direct metrics can directly measure. Indirect metrics cannot be
measured directly.
Direct matrics
LOC (line of code)
Execution speed
79 | P a g e
defect rate
memory size
Indirect metrics
Functionality
Efficiency
Maintainability
Further software metrics can be categorized as:
Technical metrics: focus on the characteristics such as logical
complexity, degree of modularity etc. of the software.
Quality metrics: provide an indication of how closely software to
customer requirements.
Productivity metrics: focus on the output of the development
process.
Human-oriented metrics: human perception about the
effectiveness of tools and methods.
Size-oriented metrics : direct measures of development process
output and quality.
Function-oriented metrics : provide indirect measures.
Size-oriented metrics:
Size-oriented metrics is direct measures of software and the
process by which it is developed.
It is programming language dependent and easy to
calculate.
It is the relation of size with the cost and quality that makes
size an important metric.
Software organization maintains a table of size-oriented data as
shown in the following figure:
Effort in
Cost in Pages of
Project person- KLOC Errors People
dollars document
months
01 24 200 15.2 465 30 6
02 40 325 29.3 1068 78 9
Productivity=KLOC/person-month
Quality = defects / KLOC
Cost = $ / KLOC
Documentation = pages of documentation / KLOC
80 | P a g e
Function-Oriented Metrics
This approach focuses on the “functionality” and “utility” of
the system. The most common productivity measurement approach
is function-point approach. Function points are computed by
completing the given table shown below:
81 | P a g e
Does the system require reliable backup and recovery?
Are data communications required?
Are there distributed processing functions?
Is performance critical?
Will the system run in an existing, heavily utilized operational
environment?
Does the system require on-line data entry?
Does the on-line data entry require the input transaction to be
built over multiple screens or operations?
Are the master files updated on-line?
Are the inputs, outputs, files, or inquiries complex?
Is the internal processing complex?
Is the code designed to be reusable?
Are conversion and installation included in the design?
Is the system designed for multiple installations in different
organizations?
Is the application designed to facilitate change and ease of use
by the user?
Each of these questions is answered using the scale that
ranges from 0 to 5. The constant Values in Equation (given above)
and the weighting factors that are applied to information domain
counts are determined empirically.
Software Quality Metrics:
Quality can be measured throughout the software
development process, and after software has been delivered to the
customer. Metrics in this category includes defects uncovered and
maintainability of the system. Measures of software quality are
Correctness- is the degree to which software performs it’s specified
function.
Maintainability- is the ease with which the program is
corrected to set the reported defect, adopted if its environment
changes, or enhanced to satisfy extended requirements of the user.
82 | P a g e
Integrity- it measures the systems ability to withstand attacks, both
accidental and malicious.
Usability- measured in terms of four characteristics:
1. intellectual skill required to learn the system
2. time requiredto become moderately efficient in use of the
system
4. net increase in productivity measured when the moderately
efficient user uses the system
5. subjectivity assessment of user’s attitudes towards the system,
usually through a questionnaire to the system users.
Project Metrics
Software process metrics are used for strategic purposes.
Software project measures are tactical. Project manager and the
software team use the indicators derived from project metrics to
adapt project workflow and technical activities.
The first application of project metrics on most software
projects occurs during estimation. Metrics collected from past
projects are used as a basis from which effort and time estimates
are made for current software work. As a project proceeds,
measures, of effort and calendar time expended are compared to
original estimates (and the project schedule). The project manager
uses these data to monitor and control progress.
The intent of project metrics is twofold. First, these metrics
are used to minimize the development schedule by making the
adjustments necessary to avoid delays and mitigate potential
problems and risks. Second, project metrics are used to assess
product quality on an ongoing basis and, when necessary, modify
the technical approach to improve quality.
As quality improves, defects are minimized, and as the
defect count goes down, the amount .of rework required during the
project is also reduced. This leads to a reduction in overall project
cost.
83 | P a g e
Another model of software project metrics suggests that
every project should measure:
Inputs-measures of the resources (e.g., people, environment)
required to do the work.
Outputs-measures of the deliverables or work products created
during the software engineering process.
Results-measures that indicate the effectiveness of the
deliverables.
In actuality, this model can be applied to both process and
project. In the project context, the model can be applied recursively
as each framework activity occurs. Therefore the output from one
activity becomes input to the next. Results metrics can be used to
provide an indication of the usefulness of work products as they
flow from one framework activity (or task) to the next.
6.4 Software Metrics Steps
1. Objective Statement: Software metrics can perform one of four
functions. Metrics can help us Understand more about our
Software products, processes and services. Metrics can be used
to evaluate our Software products, processes and services
against established standards and goals. Metrics can provide the
information we need to Control resources and processes used to
produce our software. Metrics can be used to Predict attributes
of Software entities in the future. (Humphrey 1989)
2. Clear Definitions: The second step in designing a metric is to
agree to a standard definition for the entities and their
attributes being measured. When we use terms like defect,
problem report, size and even project, other people will
interpret these words in their own context with meanings that
may differ from our intended definition. These interpretation
differences increase when more ambiguous terms like quality,
maintainability and user-friendliness are used. Additionally,
individuals may use different terms to mean the same thing. For
example, the terms defect report, problem report, incident
84 | P a g e
report, fault report or customer call report may be used by
various organizations to mean the same thing.
3. Define the Model: The next step is to derive a model for the
metric. In simple terms, the model defines how we are going to
calculate the metric. Some metrics, called metric. Primitives are
measured directly and their model typically consists of a single
variable. Other more complex metrics are modeled using
mathematical combinations of metrics primitives or other
complex metrics. Most modeling includes an element of
simplification. When we create a Software measurement model
we need to be pragmatic. If we try to include all of the elements
that affect the attribute or characterize the entity our model can
become so complicated that its useless. Being pragmatic means
not trying to create the perfect model. Pick the aspects that are
the most important. Remember that the model can always be
modified to include additional levels of detail in the future.
There are two methods for selecting a model. In many cases
there is no need to "re-invent the wheel".
4. Establish Counting Criteria: The next step in designing a metric
is to break the model down into its lowest level metric
primitives and define the counting criteria used to measure each
primitive. This defines the mapping system for the
measurement of each metric primitive. The importance of the
need for defining counting criteria can be illustrated by
considering the lines of code metrics. Lines of code are one of
the most used and most often mis-used of all of the Software
Metrics. The problems and variations and anomalies of using
lines of code are well documented [Jones 1986]. However, there
is still no industry-accepted standard for counting lines of code.
Therefore, if you are going to use lines of code Metric, it is
critical that specific counting criteria be defined.
The metric primitives and their counting criteria define the
first level of data needs to be collected in order to implement
the metric.
85 | P a g e
5. Decide What’s "Good": The fourth step in designing a Metric is
defining what’s "Good". One of the first places to start looking
for "what’s good" is the customer. Many times, user
requirements dictate certain values for some metrics. There
may be product reliability levels that must be met. The customer
may have a defined expectation of defect reduction from
release to release or a required repair time for discovered
defects. Another source of information is the metrics literature.
Research and studies have helped establish industry-accepted
norms for standard measures. The best source of information on
"what’s good" is your own data. Processes vary from group to
group. Many metrics do not have industry accepted counting
criteria (i.e., lines of code), and most documentation does not
include how the metrics were calculated. Therefore, comparing
your values to published standards may result in erroneous
interpretations. Whenever possible, use your organization’s own
data to determine baselines. If historic data is not available, wait
until enough data is collected to reasonably establish current
values. Once you have decided "what’s good", you can
determine whether or not action is needed. If you are "meeting
or exceeding" desired values, no corrective action is necessary.
Management can either turn its attention elsewhere or establish
some maintenance level actions to insure that the value stays at
acceptable levels.
6. Metrics Reporting: The next step is to decide how to report the
metric. This includes defining the report format, data extraction
and reporting cycle, reporting mechanisms and distribution and
availability. The data extraction cycle defines how often the data
snap-shot(s) are required for the metric and when those data
items will be available snap-shots(s) available for use for
calculating the metrics The reporting cycle defines how often
the report generated and when is it due for distribution.
7. Additional Qualifiers: The final step in designing a metrics is
determining the additional metrics qualifiers. A good metrics is a
generic metrics. That means that the metrics is valid for an
86 | P a g e
entire hierarchy of additional extraction qualifiers. For example,
we can talk about the duration of unplanned outages for an
entire product line, an individual product or a specific release of
that product. The additional qualifiers provide the demographic
information needed for these various views of the metric. The
main reason that the additional qualifiers need to be defined as
part of the metrics design is that they determine the second
level of data collection requirements. Not only is the metric
primitive data required but also data has to exist to allow the
distinction between these Additional qualifiers.
8. Human Factors: No discussion on selecting and designing
Software metrics would be complete without a look at how
measurements affect people and people affect measures. The
people involved in collecting the data, in calculating and
reporting the metrics and in using the metrics
6.5 Software metrics Rules
Follow some basic rules:
1) Don’t measure individuals: The state-of-the-art in Software
metrics is just not up to this yet. Individual productivity
measures are the classic example of this mistake.
2) Never use metrics as a "stick": The first time we use a metrics
against an individual or a group is the last time we get valid
data.
3) Don’t ignore the data: A sure way to kill a metric program is to
ignore the data when making decisions. "Support your people
when their reports are backed by data useful to the
organization" (Grady 1992, 114). If the goals we establish and
communicate don’t agree with our actions, then the people in
our organization will perform based in our behavior, not our
goals.
4) Never use only one metric: Software is complex and
multifaceted. A metrics program must reflect that complexity. A
balance must be maintained between cost, quality and schedule
attributes to meet all of the customers needs. Focusing on any
one single metric can cause the attribute being measured to
improve at the expense of other attributes.
87 | P a g e
6.6 Software Metrics Objectives
Following are the Objectives of metrics:
1) Provide feedback: Providing regular feedback to the team about
the data they help collect has several benefits:
a) It helps maintain focus on the need to collect the data.
When the team sees the data
b) Actually being used, they are more likely to consider data
collection important.
c) If team members are kept informed about the specifics of
how the data is used, they are less likely to become
suspicious about its use.
d) By involving team members in data analysis and process
improvement efforts, we benefit from their unique
knowledge and experience.
e) Feedback on data collection problems and data integrity
issues helps educate team
f) members responsible for data collection. The benefit can be
more accurate, consistent and timely data.
2) Obtain "buy-in": To have ’buy-in" to both the goals and the
metrics in a measurement program, team members need to
have a feeling of ownership. Participating in the definition of the
metrics will enhance this feeling of ownership. In addition, the
people who work with a process on a daily basis will have
intimate knowledge of that process. This gives them a valuable
perspective on how the process can best be measured to insure
accuracy and validity and how to best interpret the measured
result to maximize usefulness.
Metrics in the Process and Project Domains
Metrics should be collected so that process and product
indicators can be ascertained. Process indicators enable a software
engineering organization to gain insight into the efficacy of an
existing process i.e., the paradigm, software engineering tasks, work
products, and milestones. They enable managers and practitioners
88 | P a g e
to assess what works and what doesn't. Process metrics are
collected across all projects and over long periods of time. Their
intent is to provide indicators that lead to long-term software
process improvement. Project indicators enable a software project
manager to assess the status of an ongoing project track potential
risks uncover problem areas before they go "critical" adjust work
flow or tasks evaluate the project team's ability to control quality of
software work products.
In some cases, the same software metrics can be used to
determine a project and then process indicators. In fact, measures
that are collected by a project team and converted into metrics for
use during a project can also be transmitted to those with
responsibility for software process improvement. For this reason,
many of the same metrics are used in both the process and project
domain.
89 | P a g e
UNIT -7
90 | P a g e
SOFTWARE QUALITY
92 | P a g e
8) Testability: Testability determines whether or not the effort
required to test programs, to ensure their reliability, as feasible.
9) Portability : Portability determines the efficiency with which the
program will run if it is placed on another hardware platform or
operating system.
10) Reusability : Reusability specifies how well a program or parts of
the program can be reused in terms of packing and scope of the
functions that are performed by the program.
11) Interoperability : Interoperability calculates the effort required
in transferring a program to another system.
Software quality can be measured by a grading scheme from
0 to 10. 0 being the minimum. The metrics used in the scheme are
shown in the table given below:
Metric Description
Ease with which conformance to standards can be
Audibility
checked
Communication
Precision of calculation and control
commonality
Degree to which the full implementation of the
Completeness
function has been achieved
Compactness of the program in terms of code and
Conciseness
lines
Use of uniform design and documentation
Consistency
techniques throughout the program
Use of standard datatype and structure throughout
Data commonality
the program
Damage that occurs when the program encounters
Error tolerance
an error
Execution efficiency Run time performance of the program
Degree to which the architectural, data, or
Expandability
procedural design can be extended
Availability of mechanisms that control or protect
Security
program and data.
Degree of ease with which the program can be
Simplicity
understood
7.3 Software Quality Assurance
Software Quality assurance (SQA) plays a critical role in
producing a competitive and profitable software documentation
package. There are many different approaches to quality and quality
processes. Quality assurance processes with the goal to assist
93 | P a g e
individuals in processing and applying information. SQA is defined as
a planned and systematic approach required to ensure the quality of
the software product. It can be achieved by adhering to software
product standards and procedures. Standards are criteria to which
the products are compared. Procedures are criteria to which the
development and control processes are compared.
Procedures are the explicit steps followed in a process.
Standards are of 3 types :
Documentation standard that specifies the form and content for
planning, control and product documentation.
Design standard that provides rules and methods for translating
the software requirements into design.
Code standard that designates the language in which the code is
to be written.
7.4 Activities
Following are the SQA activities, which assure that the
software development process, and control processes are carried
out according to standards and procedures.
Formal Technical Reviews (FTRs) – is a meeting with the
technical staff; explicitly aimed towards discussing the quality
problem.
Application of technical methods – helps the analysts and
designer to achieve high quality specifications and design.
Software testing – helps in error detection.
Measurement – is measuring the impact of procedural and
methodological changes on software based on software metrics.
Audits – are used to review management, technical, and
assurance procedures to provide an indication of quality and
status of software product.
Record keeping and Reporting – it provides for the collection
and circulation of information pertaining to software quality
assurance.
94 | P a g e
7.5 Formal Technical Reviews
FTR are well planned, controlled and attended meetings
that are conducted to uncover the defects in software product that
can be removed It includes walkthrough, round-robin reviews,
inspections and other technical assessments related to the software
product.
The aims of FTR are:
Revealing errors
Verification of software, whether it meets the requirements or
not
Verifying and assuring that software has been developed
according to the standards
Checking the uniformity of the software
Auditing the manageability of the product
7.6 Phases of FTR
FTRs are conducted at each stage in a software
development cycle.
Requirement phase – identification of requirements and
corresponding system elements.
Planning phase – determination of software scope, estimation
of resources, risk analysis, scheduling
Analysis phase – information content, information content,
information structure
Designing phase – data design, procedural design, interface
design
Coding phase – to uncover translational errors
Testing phase – functional and behavioral characteristics of the
software.
Maintenance phase – corrective, adaptive, perfective and
preventive maintenance
95 | P a g e
7.7 Software Configuration Management
Configuration Management (CM) addresses the composition
of a project, documentation defining the project, and other data
that supports the project. CM is a baseline and requirements
management process that provides managed control to all phases of
a project life cycle. It is a management discipline that applies
technical and administrative direction to the development,
production, and life cycle support of a project. In achieving this,
Configuration Management is a management process for
establishing and maintaining consistency of a project's performance,
functional, and physical attributes with its requirements, design,
development, and operational information throughout its life.
Software configuration management is a key software
development process, and is essential for doing software assurance.
Changes to the software under development are usually a significant
cause of changes to a project's schedule and budget; unmanaged
change is very possibly the largest single cause of failure to deliver
systems on time and within budget. Software Configuration
Management is the process that has been developed to control and
manage change. Change is inevitable during the software
development life cycle. Changes to the software come from both
external and internal sources. External changes originate from users,
from evolution of operational environments, and from
improvements in technology. Internal changes come from improved
designs and methods, from incremental development, and from
correction of errors.
Software configuration management is the process whose
objective is the identification of the configuration of software at
discrete points in time and the systematic control of changes to the
identified configuration for the purpose of maintaining software
integrity and traceability throughout the software life cycle. There
are four SCM functions:
Identification of the components that make up the software
system and that define its functional characteristics Control of
changes to those components Reporting of status of the processing
96 | P a g e
of change requests and, for approved requests, their
implementation status Authentication that the controlled items
meet their requirements and are ready for delivery.
The components of a software system that are controlled by
the SCM process include project documentation, product
documentation, code, data, and any other items needed to meet a
set of requirements or contractual obligations. All of these items can
be controlled by the same SCM process.
The term "configuration" means the functional and/or
physical characteristics of software as set forth in technical
documentation and realized in a product. Thus "configuration"
includes all of the characteristics of the software to be controlled -
its content, the content of documents that describe it, the versions
of software and documents as these contents are changed, data
needed for operation of the software, and any other essential
elements or characteristics that make the software what it is.
The software under control is usually divided into
"configuration items." Configuration item (CI) is the term used for
each of the logically related components that make up some
discrete element of software. For example, if a system contains
several programs, each program and its related documentation and
data might be designated a configuration item. The number of CIs in
a system is a design decision. A CI that is purely software is often
called a Computer Software Configuration Item, or CSCI.
Software configuration management is composed of four
functions:
Configuration Identification - is the process of defining each
baseline to be established during the software life cycle and
describing the software configuration items and their
documentation that make up each baseline. First, the software
must be grouped into configuration items.
Configuration Control - is the process of evaluating,
coordinating, and deciding on the disposition of proposed
changes to the configuration items, and for implementing
97 | P a g e
approved changes to base lined software and associated
documentation. The change control process ensures that
changes, which have been initiated, are classified and evaluated,
approved or disapproved, and that those approved are
implemented, documented, and verified.
Configuration Status Accounting - is the process used to trace
changes to the software. It ensures that status is recorded,
monitored, and reported on both pending and completed
actions affecting software baselines. This process also defines
the current as-built status of the code and associated
documentation.
Configuration Authentication - is the process of verifying that a
deliverable software baseline contains all of the items which are
required for that delivery, and that these items have themselves
satisfy their requirements. The authentication function usually
consists of two "audits"; a functional configuration audit (FCA)
and a physical configuration audit (PCA). Functional audits
authenticate that the software has been tested to assure that it
performs in accordance with requirements in the baseline
documentation. Physical audits authenticate that the software
to be delivered contains all of the required components,
documents, and data.
7.8 Self Test
1. Define Software quality and its factors.
2. Explain Formal Technical Review
98 | P a g e
UNIT -8
99 | P a g e
COUPLING AND COHESION
100 | P a g e
identified as influencing coupling between modules. Among them
the most important are the type of connection between modules,
the complexity of the interface, and the type of information flow
between modules.
Coupling increases with the complexity and obscurity of the
interface between modules. To keep coupling low we would like to
minimize the number of inter- faces per module and the complexity
of each interface. An interface of a module is used to pass
information to and from other modules. Coupling is reduced if only
the defined entry interface of a module is used by other modules
(for example, passing information to and from a module exclusively
through parameters). Coupling would increase if a module is used by
other modules via an indirect and obscure interface, like directly
using the internals of a module or using shared variables.
8.2 Factors affecting Coupling
Complexity: Complexity of the interface is another factor affecting
coupling. The more complex each interface is, the higher will be the
degree of coupling. For example, complexity of the entry interface
of a procedure depends on the number of items being passed as
parameters and on the complexity of the items. Some level of
complexity of interfaces is required to support the communication
needed between modules. However, often more than this minimum
is used. For example, if a field of a record is needed by a procedure,
often the entire record is passed, rather than just passing that field
of the record. By passing the record we are increasing the coupling
unnecessarily. Essentially, we should keep the interface of a module
as simple and small as possible.
Information Flow: The type of information flow along the interfaces
is the third major factor affecting coupling. There are two kinds of
information that can flow along an interface: data or control.
Passing or receiving control information means that the action of
the module will depend on this control information, which makes it
more difficult to understand the module and provide its abstraction.
Transfer of data information means that a module passes as input
some data to another module and gets in return some data as
101 | P a g e
output. This allows a module to be treated as a simple input- output
function that performs some transformation on the input data to
produce the output data. In general, interfaces with only data
communication result in the lowest degree of coupling, followed by
interfaces that only transfer control data. Coupling is considered
highest if the data is hybrid. that is, some data items and some
control items are passed between modules. The effect of these
three factors on coupling is summarized in the following table.
8.3 Cohesion
Introduction: We have seen that coupling is reduced when the
relationships among elements in different modules are minimized.
That is, coupling is reduced when elements in different modules
have little or no bonds between them. Another way of achieving this
effect, is to strengthen the bond between elements of the same
module by maximizing the relationship between elements of the
same module. Cohesion is the concept that tries to capture this intra
module. With cohesion, we are interested in determining how
closely the elements of a module are related to each other.
Cohesion of a module represents how tightly bound the
internal elements of the module are to one another. Cohesion of a
module gives the designer an idea about whether the different
elements of a module belong together in the same module.
Cohesion and coupling are clearly related. Usually, the greater the
cohesion of each module in the system, the lower the coupling
between modules is. This correlation is not perfect, but it has been
observed in practice.
8.4 Levels of Cohesion
There are several levels of cohesion:
Coincidental
Logical
Temporal
Procedural
Communicational
Sequential
Functional
102 | P a g e
8.5 Coincidental Cohesion
Coincidental is the lowest level, and functional is the
highest. These levels do not form a linear scale. Functional binding is
much stronger than the rest, while the first two are considered
much weaker than others. Often, many levels can be applicable
when considering cohesion between two elements of a module. In
such situations, the highest level is considered. Cohesion of a
module is considered the highest level of cohesion applicable to all
elements in the module.
Coincidental cohesion occurs when there is no meaningful
relationship among the elements of a module. Coincidental
cohesion can occur if an existing program is "modularized" by
chopping it into pieces and making different pieces modules. If a
module is created to save duplicate code by combining some part of
code that occurs at many different places, that module is likely to
have coincidental cohesion. In this situation, the statements in the
module have no relationship with each other, and if one of the
modules using the code needs to be modified and this modification
includes the common code, it is likely that other modules using the
code do not want the code modified. Consequently, the
modification of this "common module" may cause other modules to
behave incorrectly. The modules using these modules are therefore
not modifiable separately and have strong interconnection between
them. We can say that, generally speaking, it is poor practice to
create a module merely to avoid duplicate code (unless the common
code happens to perform some identifiable function, in which case
the statements will have some relationship between them) or to
chop a module into smaller modules to reduce the module size.
8.6 Logical Cohesion
A module has logical cohesion if there is some logical
relationship between the elements of a module, and the elements
perform functions that fall in the same logical class. A typical
example of this kind of cohesion is a module that performs all the
inputs or all the outputs. In such a situation, if we want to input or
output a particular record, we have to somehow convey this to the
103 | P a g e
module. Often, this will be done by passing some kind of special
status flag, which will be used to determine what statements to
execute in the module. Besides resulting in hybrid information flow
between modules, which is generally the worst form of coupling
between modules, such a module will usually have tricky and clumsy
code. In general, logically cohesive modules should be avoided, if
possible.
8.7 Temporal Cohesion
Temporal cohesion is the same as logical cohesion, except
that the elements are also related in time and are executed
together. Modules that perform activities like "initialization," "clean-
up," and "termination" are usually temporally bound. Even though
the elements in a temporally bound module are logically related,
temporal cohesion is higher than logical cohesion, because the
elements are all executed together. This avoids the problem of
passing the flag, and the code is usually simpler.
8.8 Procedural Cohesion
A procedurally cohesive module contains elements that
belong to a common procedural unit. For example, a loop or a
sequence of decision statements in a module may be combined to
form a separate module. Procedurally cohesive modules often occur
when modular structure is determined from some form flowchart.
Procedural cohesion often cuts across functional lines. A module
with only procedural cohesion may contain only part of a complete
function or parts of several functions.
8.9 Communicational Cohesion
A module with communicational cohesion has elements that
are related by a reference to the same input or output data. That is,
in a communication ally bound module, the elements are together
because they operate on the same input or output data: An example
of this could be a module to "print and punch record."
Communication ally cohesive modules may perform more than one
function. However, communicational cohesion is sufficiently high as
104 | P a g e
to be generally acceptable if alternative structures with higher
cohesion cannot be easily identified.
8.10 Sequential Cohesion
When the elements are together in a module because the
output of one forms the input to another, we get sequential
cohesion. If we have a sequence of elements in which the output of
one forms the input to another, sequential cohesion does not
provide any guidelines on how to combine them into modules.
Different possibilities exist: combine all in one module, put the first
half in one and the second half in another, the first third in one and
the rest in the other, and so forth. Consequently, a sequentially
bound module may contain several functions or parts of different
functions. Sequentially cohesive modules bear a close resemblance
to the problem structure. However, they are considered to be far
from the ideal, which is functional cohesion.
8.11 Functional Cohesion
Functional cohesion is the strongest cohesion. In a
functionally bound module, all the elements of the module are
related to performing a single function. By function, we do not mean
simply mathematical functions; modules accomplishing a single goal
are also included. Functions like "compute square root" and "sort
the array" are clear examples of functionally cohesive modules.
How does one determine the cohesion level of a module?
There is no mathematical formula that can be used. We have to use
our judgment for this. A useful technique for determining if a
module has functional cohesion is to write a sentence that
describes, fully and accurately, the function or purpose of the
module. The following tests can then be made :
1. If the sentence must be a compound sentence, if it contains a
comma, or it has more than one verb, the module is probably
performing more than one function, and it probably has
sequential or communicational cohesion.
2. If the sentence contains words relating to time, like "first,"
"next," "when," and "after" the module probably has sequential
or temporal cohesion.
105 | P a g e
3. If the predicate of the sentence does not contain a single
specific object following the verb (such as "edit all data") the
module probably has logical cohesion.
4. Words like "initialize," and "cleanup" imply temporal cohesion.
Modules with functional cohesion can always be described
by a simple sentence. However, if a description is a compound
sentence, it does not mean that the module does not have
functional cohesion. Functionally cohesive modules can also be
described by compound sentences. If we cannot describe it using a
simple sentence, the module is not likely to have functional
cohesion.
8.12 Self Test
1. What do you mean by Modularity?
2. Define Cohesion and Coupling?
106 | P a g e
UNIT-9
107 | P a g e
CODING
9.1 Introduction
The main activity of the coding phase is to translate design
into code. We have tried up to now how to structure our work
products so that they facilitate understanding and we have tried to
blueprint a well-thought out solution with good inherent structure.
If we translate this structured design properly, we will have a
structured program. Structured programming has been a buzzword
for over a decade and many articles and books have described
“structured code.” It is surely more then the absence of GOTOs. A
structured program doesn’t just “happen.” It is the end product of
series of efforts that try to understand the problem and develop a
structured, understandable solution plan, i.e., the design. It is, all
but impossible, to write a good structured program based on an
unstructured, poor design. So, the minimum premises for a well-
structured program are a well-structured design that was developed
through the structured techniques.
The coding phase affects both testing and maintenance,
profoundly. As we saw earlier, the time spent in coding is a small
percentage of the total software cost, while testing and
maintenance consume the major percentage. Thus, it should be
clear that the goal during coding should not be to reduce the
implementation cost but the goal should be to reduce the cost of
later phases, even if it means that the cost of this phase has to
increase. In other words, the goal during this phase is not to simplify
the job of the programmer. Rather, the goal should be to simplify
the job of the tester and the maintainer.
This distinction is important, as most programmers are
individualistic, and mostly concerned about how to finish their job
quickly, without keeping the later phases in mind. During
implementation, it should be kept in mind that the programs should
108 | P a g e
not be constructed so that they are easy to write, but so that they
are easy to read and understand. A program is read, a lot more
often, and, by a lot more people, during the later phases. Often,
making a program more readable will require extra work by the
programmers. For example, sometimes there are "quick fixes" to
modify a given code easily, which result in a code that is more
difficult to understand. In such cases, in the interest of simplifying
the later phases, the easy "quick fixes" should not be adopted.
There are many different criteria for judging a program,
including readability, size of the program, execution time, and
required memory. Having readability and understandability as a
clear objective of the coding activity can itself help in producing
software that is more maintainable. A famous experiment by
Weinberg showed that if programmers are specified a clear
objective for the program, they usually satisfy it. In the experiment,
five different teams were given the same problem for which they
had to develop programs. However, each of the teams was specified
a different objective, which it had to satisfy. The different objectives
given were: minimize the effort required to complete the program,
minimize the number of statements, minimize the memory
required, maximize the program clarity, and maximize the output
clarity. It was found that, in most cases, each team did the best for
the objective that was specified to it. The rank of the different teams
for the different objectives is shown in the following figure:
Resulting Rank ( 1 = Best)
01 02 03 04 05
Minimize effort to complete (01) 1 4 4 5 3
Minimize number of statements (02) 2–3 1 2 3 5
Minimize memory required (03) 5 2 1 4 4
Maximize program clarity (04) 4 3 3 2 2
Maximize output clarity (05) 2–3 5 5 1 1
Figure: The Weinberg Experiment
The experiment clearly shows that if objectives are clear,
programmers tend to achieve that objective. Hence, if readability is
an objective of the coding activity, then it is likely that programmers
will develop easily understandable programs. For our purposes, ease
109 | P a g e
of understanding and modification should be the basic goals of the
programming activity. This means that simplicity and clarity are
desirable, while cleverness and complexity are not.
9.2 Programming Practice
The primary goal of the coding phase is to translate the
given design into source code, in a given programming language, so
that code is simple, easy to test, and easy to understand and modify.
Simplicity and clarity are the properties that a programmer should
strive for.
Good programming is a skill that can only be acquired by
practice. However, much can be learned from the experience of
others, and some general rules and guidelines can be laid for the
programmer. Good programming (producing correct and simple
programs) is a practice independent of the target programming
language, although some well-structured languages like Pascal, Ada,
and Modula make the programmer's job simpler. In this section, we
will discuss some concepts related to coding in a language-
independent manner.
9.3Top-Down and Bottom-Up Methodology:
All designs contain hierarchies, as creating a hierarchy is a
natural way to manage complexity. Most design methodologies for
software also produce hierarchies. The hierarchy may be of
functional modules, as is the case with the structured design
methodology where the hierarchy of modules is represented by the
structure chart. Or, the hierarchy may be an object hierarchy as is
produced by object-oriented design methods and, frequently,
represented by object diagrams. The question at coding time is:
given the hierarchy of modules produced by design, in what order
should the modules be built-starting from the top level or starting
from the bottom level?
In a top-down implementation, the implementation starts
from the top of the hierarchy and proceeds to the lower levels. First,
the main module is implemented, then its subordinates are
implemented, and their subordinates, and so on. In a bottom-up
110 | P a g e
implementation, the process is the reverse. The development starts
with implementing the modules at the bottom of the hierarchy and
proceeds through the higher levels until it reaches the top.
Top-down and bottom-up implementation should not be
confused with top-down and bottom-up design. Here, the design is
being implemented, and if the design is fairly detailed and complete,
its implementation can proceed in either the top-down or the
bottom-up manner, even if the design was produced in a top-down
manner. Which of the two is used, mostly affects testing.
If there is a complete design, why is the order in which the
modules are built, an issue? The main reason is that we want to
incrementally build the system. That is, we want to build the system
in parts, even though the design of the entire system has been done.
This is necessitated by the fact that for large systems it is simply not
feasible or desirable to build the whole system and then test it. All
large systems must be built by assembling validated pieces together.
The case with software systems is the same. Parts of the system
have to be first built and tested, before putting them together to
form the system. Because parts have to be built and tested
separately, the issue of top-down versus bottom-up arises.
The real issue in which order the modules are coded comes
in testing. If all the modules are to be developed and then put
together to form a system for testing purposes, as is done for small
systems, it is immaterial which module is coded first. However,
when modules have to be tested separately, top-down and bottom-
up lead to top-down and bottom-up approaches to testing. And
these two approaches have different consequences. Essentially,
when we proceed top-down, for testing a set of modules at the top
of the hierarchy, stubs will have to be written for the lower- level
modules that the set of modules under testing invoke. On the other
hand, when we proceed bottom-up, all modules that are lower in
the hierarchy have been developed and driver modules are needed
to invoke these modules under testing.
Top-down versus bottom-up is also a pertinent issue when
the design is not detailed enough. In such cases, some of the design
111 | P a g e
decisions have to be made during development. This may be true,
for example, when building a prototype. In such cases, top-down
development may be preferable to aid the design while the
implementation is progressing. On the other hand, many complex
systems, like operating systems or networking software systems, are
naturally organized as layers. In a layered architecture, a layer
provides some services to the layers above, which use these services
to implement the services it provides. For a layered architecture, it is
generally best for the implementation to proceed in a bottom-up
manner.
In practice, in large systems, a combination of the two
approaches is used during coding. The top modules of the system
generally contain the overall view of the system and may even
contain the user interfaces. Starting with these modules and testing
them gives some feedback regarding the functionality of the system
and whether the "look and feel” of the system is OK. For this, it is
best if development proceeds top-down. On the other hand, the
bottom-level modules typically form the "service routines" that
provide the basic operations used by higher-level modules. It is,
therefore, important to make sure that these service modules are
working correctly before they are used by other modules. This
suggests that the development should proceed in a bottom-up
manner. As both issues are important in a large project, it may be
best to follow a combination approach for such systems.
Finally, it should be pointed out that incremental building of
code is a different issue from the one, addressed in the incremental
enhancement process model. In the latter, the whole software is
built in increments. Hence, even the SRS and the design for an
increment, focus on that increment only. However, in incremental
building, which we are discussing here, the design itself is complete
for the system we are building. The issue is, in which order the
modules specified in the design, should be coded.
9.4 Structured Programming
Structured coding practices translate a structured design
into well-structured code. PDL statements come in four different
112 | P a g e
categories: sequence, selection (IF-THEN-ELSE, CASE), iteration
(WHITE, REPEAT-UNTIL, FOR), and parallelism. Data statements
included structure definitions and monitor. Programming languages
may have special purpose statements: patter matching in SNOBOL;
process creation and generation of variates for some probability
distributions in simulation languages such as SIMULA67, and
creating appending, or querying a database file in DBase (Reg.
Trademark). Even special purpose languages have at least the first
three types of statements.
The goal of the coding effort is to translate the design into a
set of Single-Entry-Single-Exit (SESE) modules. We can explain this by
representing a program as a directed graph where every statement
is a node and, possible transfers of control between statements is
indicated through arcs between nodes. Such a control flow graph
shows one input arc, one output arc and for all nodes in the graph a
path starts at the input arc, goes to the output arc, and passes
through that node.
Clearly, no meaningful program can be written as a
sequence of simple statements without any branching or repetition
(which also involves branching). So, how is the objective of
linearizing the control flow to be achieved? By making use of
structured constructs. In structured programming, a statement is
not a simple assignment statement, it is a structured statement. The
key property of a structured statement is that it has a single-entry
and a single-exit. That is, during execution, the execution of the
(structured) statement starts from one defined point and the
execution terminates at one defined point. With single-entry and
single-exit statements, we can view a program as a sequence of
(structured) statements. And, if all statements are structured
statements, then during execution, the sequence of execution of
these statements will be the same as the sequence in the program
text. Hence, by using single-entry and single-exit statements, the
correspondence between the static and dynamic structures can be
obtained. The most commonly used single-entry and single-exit
statements are:
113 | P a g e
Selection: if B then S 1 else S2
if B then Sl
Iteration: While B do S
I repeat S until B
Sequencing: Sl; S2; S3;
It can be shown that these three basic constructs are
sufficient to program any conceivable algorithm. Modern languages
have other such constructs that help linearize the control flow of a
program, which, generally speaking, makes it easier to understand a
program. Hence, programs should be written so that, as far as
possible, single-entry, single-exit control constructs are used. The
basic goal, as we have tried to emphasize, is to make the logic of the
program simple to understand. No hard and fast rule can be
formulated that will be applicable under all circumstances.
It should be pointed out that the main reason that
structured programming was promulgated is formal verification of
programs. As we will see later in this chapter, during verification, a
program is considered a sequence of executable statements, and
verification proceeds step by step, considering one statement in the
statement list (the program) at a time. Implied in these verification
methods is the assumption that during execution, the statements
will be executed in the sequence in which they are organized in the
program text. If this assumption is satisfied, the task of verification
becomes easier. Hence, even from the point of view of verification,
it is important that the sequence of execution of statements is the
same as the sequence of statements in the text.
Any piece of code with a single-entry and single-exit cannot
be considered a structured construct. If that is the case, one could
always define appropriate units in any program to make it appear as
a sequence of these units (in the worst case, the whole program
could be defined to be a unit). The basic objective of using
structured constructs is to make the control flow linear so that the
execution behavior is easier to understand and argue about. In
liberalized control flow, if we understand the behavior of each of the
114 | P a g e
basic constructs properly, the behavior of the program can be
considered a composition of the behaviors of the different
statements. For this basic approach to work, it is implied that we can
clearly understand the behavior of each construct. This requires that
we be able to succinctly capture or describe the behavior of each
construct. Unless we can do this, it will not be possible to compose
them. Clearly, for an arbitrary structure, we cannot do this merely
because it has a single entry and single-exit. It is from this viewpoint
that the structures mentioned earlier are chosen as structured
statements. There are well-defined rules that specify how these
statements behave during execution, which allows us to argue
about larger programs.
Overall, it can be said that structured programming, in
general, leads to programs that are easier to understand than
unstructured programs, and that such programs are easier
(relatively speaking) to formally prove. However, it should be kept in
mind that structured programming is not an end in itself. Our basic
objective is that the program be easy to understand. And structured
programming is a safe approach for achieving this objective. Still,
there are some common programming practices that are now well
understood that make use of unstructured constructs (e.g., break
statement, continue statement). Although efforts should be made to
avoid using statements that effectively violate the single entry and
single-exit property, if the use of such statements is the simplest
way to organize the program, then from the point of view of
readability, the constructs should be used. The main point is that
any unstructured construct should be used only if the structured
alternative is harder to understand. This view can be taken only
because we are focusing on readability. If the objective was formal
verifiability, structured programming will probably be necessary.
9.5 Hiding Information
A software solution to a problem always contains data
structures that are meant to represent information in the problem
domain. That is, when software is developed to solve a problem, the
software uses some data structures to capture the information in
115 | P a g e
the problem domain. With the problem information represented
internally as data structures, the required functionality of the
problem domain, which is in terms of information in that domain,
can be implemented as software operations on the data structures.
Hence, any software solution to a problem contains data structures
that represent information in the problem domain.
In the problem domain, in general, only certain operations
are performed on some information. That is, a piece of information
in the problem domain is used only in a limited number of ways in
the problem domain. For example, a ledger in an accountant's office
has some very defined uses: debit, credit, check the current balance,
etc. An operation where all debits are multiplied together and then
divided by the sum of all credits is, typically, not performed. So, any
information in the problem domain, typically, has a small number of
defined operations performed on it.
When the information is represented as data structures, the
same principle should be applied, and only some defined operations
should be performed on the data structures. This, essentially, is the
principle of information hiding. The information captured in the data
structures should be hidden from the rest of the system, and only
the access functions on the data structures that represent the
operations performed on the information should be visible. In other
words, when the information is captured in data structures and,
then, on the data structures that represent some information, for
each operation on the information an access function should be
provided. And, as the rest of the system in the problem domain only
performs these defined operations on the information, the rest of
the modules in the software should only use these access functions
to access and manipulate the data structures.
If the information hiding principle is used, the data structure
need not be directly used and manipulated by other modules. All
modules, other than the access functions, access the data structure
through the access functions.
Information hiding can reduce the coupling between
modules and make the system more maintainable. If data structures
116 | P a g e
are directly used in modules, then all modules that use some data
structures are coupled with each other and if change is made in one
of them, the effect on all the other modules needs to be evaluated.
With information hiding, the impact on the modules using the data
needs to be evaluated only when the data structure or its access
functions are changed. Otherwise, as the other modules are not
directly accessing the data, changes in these modules will have little
direct effect on other modules using the data. Also, when a data
structure is changed, the effect of the change is generally limited to
the access functions, if information hiding is used. Otherwise, all
modules using the data structure may have to be changed.
Information hiding is also an effective tool for managing the
complexity of developing software. As we have seen, whenever
possible, problem partitioning must be used so that concerns can be
separated and, different parts solved separately. By using
information hiding, we have separated the concern of managing the
data from the concern of using the data to produce some desired
results. Now, to produce the desired results, only the desired
operations on the data need to be performed, thereby making the
task of designing these modules easier. Without information hiding,
this module will also have to deal with the problem of properly
accessing and modifying the data.
Another form of information hiding is to let a module see
only those data items needed by it. The other data items should be
"hidden" from such modules and the modules should not be
allowed to access these data items. Thus, each module is given
access to data items on a "need-to-know" basis. This level of
information hiding is usually not practical, and most languages do
not support this level of access restriction. However, many modem-
programming languages in the form of data abstraction support the
information hiding principle discussed earlier. We discussed the
concept of data types and classes earlier, and we have seen that it
forms the basis of the object-oriented design approach.
With support for data abstraction, a package or a module is
defined that encapsulates the data. The module on the
117 | P a g e
encapsulated data defines some operations. Other modules that are
outside this module can only invoke these predefined operations on
the encapsulated data. The advantage of this form of data
abstraction is that the data is entirely in the control of the module in
which the data is encapsulated.
Other modules cannot access or modify the data; the
operations that can access and modify are also a part of this
module.
Many of the older languages, like Pascal, C, and FORTRAN,
do not provide mechanisms to support data abstraction. With such
languages, data abstraction can be supported only by a disciplined
use of the language. That is, the access restrictions will have to be
imposed by the programmers; the language does not provide them.
For example, to implement a data abstraction of a stack in C, one
method is to define a struct containing all the data items needed to
implement the stack and then to define functions and procedures
on variables of this type. A possible definition of the struct and the
interface of, the "push" operation is given next:
typedef struct {
int xx[100];
int top;
} stack;
void push (s, i)
stack s; int i;
{
:
}
Note, that in implementing information hiding in languages
like C and Pascal, the language does not impose any access
restrictions. In the example of the stack earlier, the structure of
variables declared of the type stack, can be accessed from
procedures other than the ones defined for stack. That is why
discipline by the programmers is needed to emulate data
abstraction. Regardless of whether or not the language provides
constructs for data abstraction, it is desirable to support data
118 | P a g e
abstraction in cases where the data and operations on the data are
well defined. Data abstraction is one way to increase the clarity of
the program. It helps in clean partitioning of the program into pieces
that can be separately implemented and understood.
9.6 Verification & Validation
The goal of verification and validation activities is to assess
and improve the quality of the work products generated during
development and modification of software. Quality attributes of
interest include correctness, completeness, consistency, reliability,
usefulness, usability, efficiency, conformance to standards, and
overall cost effectiveness.
There are two types of verification: life-cycle verification and
formal verification. Life-cycle verification is the process of
determining the degree to which the work products of a given phase
of the development cycle fulfill the specifications established during
priori phases. Formal verification is rigorous mathematical
demonstration that source code conforms to its specifications.
Validation is the process of evaluating software at the end of the
software development process to determine compliance with the
requirements. Boehm phrases these definitions as follows:
Verification: “Are we building the product right?”
Validation: “Are we building the right product?”
Program verification methods fall into two categories-static
and dynamic methods. In dynamic method, the program is executed
on some test data and the outputs of the program are examined to
determine if there are any errors present. Hence, dynamic
techniques follow the traditional pattern of testing, and the
common notion of testing refers to this technique.
Static techniques, on the other hand, do not involve actual
program execution on actual numeric data, though it may involve
some form of conceptual execution. In static techniques, the
program is not compiled and then executed, as in testing. Common
forms of static techniques are program verification, code reading,
code reviews and walkthroughs, and symbolic execution. In static
119 | P a g e
techniques, often the errors are detected directly, unlike dynamic
techniques where only the presence of an error is detected. This
aspect of static testing makes it quite attractive and economical.
It has been found that the types of errors detected by the
two categories of verification techniques are different. The type of
errors detected by static techniques is often not found by testing, or
it may be more cost-effective to detect these errors by static
methods. Consequently, testing and static methods are
complimentary in nature, and both should be used for reliable
software.
9.7 Good Coding Style
Why is programming style important? A well-written
program is more easily read and understood both by the author and
by others who work with that program. Not even the author will
long remember his precise thoughts on a program. The program
itself should help the reader to understand what it does quickly
because only a small fraction of the developers if any, are
maintaining the program they wrote. Others will, and they must be
able to understand what the program does. Bad programming style
makes program difficult to understand, hard to modify, and
impossible to maintain over a long period of time, even by the
person who coded it originally.
A good programming style is characterized by the following:
simplicity,
readability,
good documentation,
changeability,
predictability
consistency in input and output,
module independence, and
good structure.
Some general rules that usually apply.
120 | P a g e
Names: novice programmers do often, not consider selecting
module and variable names important. Only when one starts
reading programs written by others, where the variable names are
cryptic and not representative, does one realize the importance of
selecting proper names. Most variables in a program reflect some
entity in the problem domain, and the modules reflect some
process. Variable names should be closely related to the entity they
represent, and module names should reflect their activity. It is bad
practice to choose cryptic names just to avoid typing) or totally
unrelated names. lt is also bad practice to use the same name for
multiple purposes.
Control constructs: As discussed earlier, it is desirable that as much
as possible single-entry, single-exit constructs be used. It is also
desirable to use a few standard control constructs rather than using
a wide variety of constructs, just because they are available in the
language.
Gotos: Gotos should be used sparingly and in a disciplined manner
(this discussion is not applicable to gotos used to support single-
entry, single-exit constructs in languages like FORTRAN). Only, when
the alternative to using gotos is more complex, should the gotos be
used. In any case, alternatives must be thought of, before finally
using a goto. If a goto must be used, forward transfers (or a jump to
a later statement) are more acceptable than a backward jump. Use
of gotos for exiting a loop or for invoking error handlers is quite
acceptable (many languages provide separate constructs for these
situations, in which case those constructs should be used).
Information hiding: As discussed earlier, information hiding should
be supported where possible. Only the access functions for the data
structures should be made visible while hiding the data structure
behind these functions.
User-defined types: Modem languages allow users to define types
like the enumerated type. When such facilities are available, they
should be exploited where applicable. For example, when working
with dates, a type can be defined for the day of the week. In Pascal,
this is done as follows:
type days = (Mon, Tue, Wed, Thur, Fri, Sat, Sun);
121 | P a g e
Variables can then be declared of this type. Using such types
makes the program much clearer than defining codes for each day
and then working with codes.
Nesting: The different control constructs, particularly the if-then-
else, can be nested. If the nesting becomes too deep, the programs
become harder to understand. In case of deeply nested if-then-else,
it is often difficult to determine the if statement to which a
particular else clause is associated.
Where possible, deep nesting should be avoided, even if it
means a little inefficiency. For example, consider the following
construct of nested if-then-elses:
if C1 then S1
else if C2 then S2
else if C3 then S3
else if C4 then S4;
If the different conditions are disjoint (as they often are),
this structure can be converted into the following structure:
if C1 then S1;
if C2 then S2;
if C3 then S3;
if C4 then S4;
This sequence of statements will produce the same result as
the earlier sequence (if the conditions are disjoint), but it is much
easier to understand. The price is a little inefficiency in that the
latter conditions will be evaluated even if a condition evaluates to
true, while in the previous case, the condition evaluation stops
when one evaluates to true. Other such situations can be
constructed, where alternative program segments can be
constructed, to avoid a deep level of nesting. In general, if the price
is only a little inefficiency, it is more desirable to avoid deep nesting.
Module size: We discussed this issue during system design. A
programmer should carefully examine any routine with very few
statements (say fewer than 5) or with too many statements (say
more than 50). Large modules often will not be functionally
122 | P a g e
cohesive, and too-small modules might incur unnecessary overhead.
There can be no hard-and-fast rule about module sizes, the guiding
principle should be cohesion and coupling.
Module interface: A module with a complex interface should be
carefully examined. Such modules might not be functionally
cohesive and, might be implementing multiple functions. As a rule of
thumb, any module whose interface has more than five parameters
should be carefully examined and broken into multiple modules
with a simpler interface, if possible.
Program layout: How the program is organized and presented can
have great effect on the readability of it. Proper indentation, blank
spaces, and parentheses should be used to enhance the readability
of programs. Automated tools are available to "pretty print" a
program, but it is good practice to have a clear layout of programs.
Side effects: When a module is invoked, it sometimes has side
effects of modifying the program state, beyond the modification of
parameters listed in the module interface definition, for example,
modifying global variables. Such side effects should be avoided
where possible, and if a module has side effects, they should be
properly documented.
Robustness: A program is robust if it does something planned even
for exceptional conditions. A program might encounter exceptional
conditions in such forms as incorrect input, the incorrect value of
some variable, and overflow. A program should try to handle such
situations. In general, a program should check for validity of inputs,
where possible, and should check for possible overflow of the data
structures. If such situations do arise, the program should not just
"crash" or "core dump"; it should produce some meaningful
message and exit gracefully.
9.8 Self test
1. Differentiate between verification and validation with example.
2. Explain the importance of Information Hiding in design process
with an example.
3. List and explain various features of good coding style.
123 | P a g e
UNIT-10
124 | P a g e
SOFTWARE TESTING
STRATEGIES
125 | P a g e
A strategy for software testing must accommodate low-level
tests that are necessary to verify that a small source code segment
has been correctly implemented as well as high-level tests that
validate major system functions against customer requirements. A
strategy must provide guidance for the practitioner and a set of
milestones for the manager. Because the steps of the test strategy
occur at a time when dead-line pressure begins to rise, progress
must be measurable and problems must surface as early as possible.
1.1 Organizing for Software Testing
For every software project, there is an inherent conflict of
interest that occurs as testing begins. The people who have built the
software are now asked to test the software. This seems harmless in
itself; after all, who knows the program better than its developers?
Unfortunately, these same developers have a vested interest in
demonstrating that the program is error free, that it works
according to customer requirements, and that it will be completed
on schedule and within budget. Each of these interests mitigate
against thorough testing.
From a psychological point of view, software analysis and
design (along with coding) are constructive tasks. The software
engineer creates a computer program, its documentation, and
related data structures. Like any builder, the software engineer is
proud of the edifice that has been built and looks askance at anyone
who attempts to tear it down. When testing commences, there is a
subtle, yet definite, attempt to 'break' the thing that the software
engineer has built. From the point of view of the builder, testing can
be considered to be (psychologically) destructive.
There are often a number of misconceptions that can be
erroneously inferred from the preceding discussion:
That the developer of software should do no testing at all.
That the software should be ‘tossed over the wall’ to
strangers who will test it mercilessly,
That tester gets involved with the project only when the
testing steps are about to begin.
Each of these above statements is incorrect.
126 | P a g e
The software developer is always responsible for testing the
individual units (components) of the program, ensuring that each
performs the function for which it was designed. In many cases, the
developer also conducts integration testing -- a testing step that
leads to the construction (and test) of the complete program
structure. Only after the software architecture is complete does an
independent test group become involved.
The role of an independent test group (ITG) is to remove the
inherent problems associated with letting the builder test the thing
that has been built. Independent testing removes the conflict of
interest that may otherwise be present. After all, personnel in the
independent group team are paid to find errors.
However, the software engineer doesn’t turn the program
over to ITG and walk away. The developer and the ITG work closely
throughout a software project to ensure that thorough tests will be
conducted: While testing is conducted, the developer must be
available to correct errors that are uncovered.
The ITG is part of the software development project team in
the sense that it becomes involved during the specification activity
and stays involved (planning and specifying test procedures)
throughout a large project. However, in many cases the ITG reports
to the software quality assurance organization, thereby achieving a
degree of independence that might not be possible if it were a part
of the software engineering organization.
1.2 A software Testing Strategy
The software engineering process may be viewed as the
spiral illustrated in figure below. Initially, system engineering defines
the role of software and leads to software requirements analysis.
Where the information domain, function, behavior, performance,
constraints. and validation criteria for software are established.
Moving inward along the spiral we come to design and finally to
coding. To develop computer software, we spiral inward along
streamlines that decrease the level of abstraction on each turn
A strategy for software testing may also be viewed in the
context of the spiral (figure above). Unit testing begins at the vortex
127 | P a g e
of the spiral and concentrates on each unit (i.e, component) of the
software as implemented in source code. Testing progresses by
moving outward along the spiral to integration testing, where the
focus is on design and the construction of the software architecture.
Taking another turn outward on the spiral, we encounter validation
testing, where requirements established as part of software
requirements analysis are validated against the software that has
been constructed. Finally, we arrive at system testing, where the
software and other system elements are tested as a whole. To test
computer software, we spiral out along streamlines that broaden
the scope of testing with each turn.
Considering the process from a procedural point of view,
testing within the context of software engineering is actually a series
of four steps that are implemented sequentially. The steps are
shown in Figure below.
Initially, tests focus on each component individually,
ensuring that it functions properly as a unit. Hence, it is named unit
testing. Unit testing makes heavy use of white-box testing
techniques, exercising specific paths in a module's control structure
to ensure complete coverage and maximum error detection. Next,
components must be assembled or integrated to form the complete
software package. Integration testing addresses the issues
associated with the dual problems of verification and program
construction. Black-box test case design techniques are the most
prevalent during integration, although a limited amount of white-
box testing may be used to ensure coverage of major control paths.
After the software has been integrated (constructed), a set of high-
order tests are conducted Validation criteria (established during
requirements analysis) must be tested. Validation testing provides
final assurance that software meets all functional, behavioral, and
performance requirement. Black box testing techniques arc used
exclusively during validation
The last high-order testing step falls outside the boundary of
software engineering and into the broader context of computer
system engineering. Software, once validated, must be combined
with other system elements (e.g., hardware, people, and databases).
System testing verifies that all elements mesh properly and that
overall system function/performance is achieved.
128 | P a g e
10.2 Unit Testing
Unit testing focuses verification effort on the smallest unit
of software design, that is software component or module. Using
the component-level design description as a guide, important
control paths are tested to uncover errors within the boundary of
the module. The relative complexity of tests and uncovered errors is
limited by the constrained scope established for unit testing. The
unit test is white-box oriented, and the step can be conducted in
parallel for multiple components.
Unit Test consideration
The tests that occur as part of unit tests are illustrated
schematically in Figure below. The module interface is tested to
ensure that information properly flows into and out of the program
unit under test. The local data structure is examined to ensure that
data stored temporarily maintains its integrity during all steps in an
algorithm's execution. Boundary conditions are tested to ensure
that the module operates properly at boundaries established to limit
or restrict processing. All independent paths (basis paths) through
the control structure are exercised to ensure that all statements in a
module have been executed at least once. And finally, all error
handling paths are tested.
Tests of data flow across a module interface are required
before any other test is initiated. If data do not enter and exit
properly, all other tests are moot. In addition, local data structures
should be exercised and the local impact on global data should be
ascertained (if possible) during unit testing.
Selective testing of execution paths is an essential task
during the unit test. Test cases should be designed to uncover errors
due to erroneous computations, incorrect comparisons, and
improper control flow. Basis path and loop testing are effective
techniques for uncovering a broad array of path errors.
Among the more common errors in computation are :
Misunderstood or incorrect arithmetic precedence,
mixed mode operations,
129 | P a g e
incorrect initialization
precision inaccuracy
Incorrect symbolic representation of an expression.
Test cases should uncover errors such as
Comparison of different data types,
incorrect logical operators or precedence,
expectation of equality when precision error makes equality
unlikely,
incorrect comparison of variables,
improper or nonexistent loop termination,
failure to exit when divergent iteration is encountered, and
Improperly modified loop variables.
Unit Test Procedures
Unit testing is normally considered as an adjunct to the
coding step. After source level code has been developed, reviewed,
and verified for correspondence to component-level design, unit
test case design begins. A review of design information provides
guidance for establishing test cases that are likely to uncover errors
in each of the categories discussed earlier. Each test case should be
coupled with a set of expected results.
Because a component is not a stand-alone program, driver
and/or stub software must be developed for each unit test. The unit
test environment is illustrated in figure below. In most applications a
driver is nothing more than a 'main program' that accepts test case
data, passes such data to the component. (to be tested), and prints
relevant results. Stubs serve to replace modules that are
subordinate (called by) the component to be tested. A stub or
‘dummy subprogram’ uses the subordinate modules’s interface,
may do minimal data manipulation, prints verification of entry and
returns control to the module undergoing testing.
Drivers and stubs represent overhead that is, both are software that
must be developed to test the module but it will not be delivered to
the customer. If the drivers and stubs are kept simple than
130 | P a g e
overhead will be relatively low. Unfortunately, many components
cannot be adequately tested with ‘simple’ overhead software. In
such cases, complete testing can be postponed until the integration
test step (where driver or stubs are also used).
Unit testing is simplified when a component with high
cohesion is designed. When only one function is addressed by the
component, the number or test cases is reduced and errors can be
more easily predicted and uncovered.
10.3 Integration Testing
A neophyte in the software world might ask a seemingly
legitimate question once all modules have been unit tested: "If they
all work individually, why do you doubt that they'll work when we
put them together?" The problem, or course, is putting them
together -- interfacing. Data can be lost across an interface; one
module can have an inadvertent, adverse affect on another; sub-
functions, when combined, may not produce the desired major
function; individually acceptable imprecision may be magnified to
unacceptable levels; global data structures can present problems.
Sadly, the list goes on and on.
Integration testing is a systematic technique for constructing
the program structure while at the same time conducting tests to
uncover errors associated with interfacing. The objective is to take
unit tested components and build a program structure that has been
dictated by design.
There is often a tendency to attempt non-incremental
integration; that is, to construct the program using a ‘big bang’
approaches. All components are combined in advance. The entire
program is tested as a whole. And chaos usually results! A set of
errors is encountered. Correction is difficult because isolation or
causes is complicated by the vast expanse of the entire program.
Once these errors are corrected, new ones appear and the process
continues in a seemingly endless loop.
Incremental integration is the antithesis of the big bang
approach. The program is constructed and tested in small
increments, where errors are easier to isolate and correct;
131 | P a g e
interfaces are more likely to be tested completely; and a systematic
test approach may be applied. In the sections that follow, a number
of different incremental integration strategies are discussed.
Top down Integration
Top down integration testing is an incremental approach to
construction or program structure. Modules are integrated by
moving downward through the control hierarchy beginning with the
main control module (main program). Modules subordinate (and
ultimately subordinate) to the main control module are
incorporated into the structure in either a depth-first or breadth-
first manner.
Referring to Figure below depth-first integration would
integrate all components on a major control path of the structure.
Selection of a major path is somewhat arbitrary and depends on
application-specific characteristics. For example, selecting the left
hand path, components M1 M2 and M5 would be integrated first.
Next, M8 or (if necessary proper functioning of M2) M6 would be
integrated. Then, the central and right hand control paths are built.
Breadth first integration incorporates all components directly sub-
ordinate at each level, moving across the structure horizontally.
From the figure, components M2, M3 and M4 ( a replacement of
stub s4) would be integrated first. The next control level M5, M6
and so on, follows.
The integration process is performed in a series of five steps:
The main control module is used as a test driver and stubs
are substituted for all components directly sub-ordinate to the main
control module.
Depending on the integration approach selected (i.e., depth
or breadth first), sub-ordinate stubs are replaced one at a time with
actual components. Tests are conducted as each component is
integrated. On completion of each set of tests, another stub is
replaced with the real components.
Regression testing may be conducted to ensure that new
errors have not been introduced. The process continues until the
entire program structure is built.
132 | P a g e
The top-down integration strategy verifies major control or
decision points early in the test process. In a well-factored program
structure, decision-making occurs at upper levels in the hierarchy
and is therefore encountered first. If major control problems do
exist, early recognition is essential. If depth-first integration is
selected, a complete function of the software may be implemented
and demonstrated.
Top-down strategy sounds relatively uncomplicated, but in
practice, logistical problems can arise. The most common of these
problems occurs when processing at low levels in the hierarchy is
required to adequately test upper levels. Stubs replace low-level
modules at the beginning of top-down testing; therefore, no
significant data can now upward in the program structure. The
tester is left will three choices;
Delay many tests until stubs are replaced with actual
modules.
Develop stubs that perform limited functions that simulate
the actual module, or Integrate the software from the bottom of
the hierarchy upward.
The first approach (delay tests until stubs are replaced by
actual modules) causes us to loose some control over
correspondence between specific tests and incorporation of specific
modules. This can lead to difficulty in determining the cause of
errors and tends to violate the highly constrained nature of the top-
down approach. The second approach is workable but can lead to
significant overhead, as stubs become more and more complex. The
third approach is called bottom-up testing.
Bottom-up integration testing, as its name implies, begins
construction and testing with atomic modules (i.e., components at
the lowest levels in the program structure). Because components
are integrated from the bottom up, processing required for
components subordinate to a given level is always available and the
need for stubs is eliminated.
133 | P a g e
A bottom-up integration strategy may be implemented with
the following steps:
Low-level components are combined into clusters (sometimes
called builds) that perform a specific software sub-function.
A driver (a control program for testing) is written to coordinate
test case input and output.
The cluster is tested.
Drivers are removed and clusters are combined moving upward
in the program structure.
Integration follows the set pattern. Components are
combined to form clusters 1,2, and 3.
Each of the clusters is tested using a driver. Components in
clusters 1 and 2 are subordinate to Ma. Drivers D1 and D2 are
removed and the clusters are interfaced directly to Ma. Similarly,
driver D3 for cluster 3 is removed prior to integration with module
Mb. Both Ma and Mb will ultimately be integrated with component
Mc, and so forth.
As integration moves upward the need for separate test
drivers lessens. In fact, if the top two levels of program structure are
integrated top down, the number of drivers can be reduced
substantially and integration of clusters is greatly simplified.
10.4 Validation Testing
Although radiology and neurology specialists positively
reviewed our functional mappings, it is difficult to validate the
results, as we have no functional map ground truth for the tested
subjects. We are thus pursuing three avenues for validating our
results:
Map repeatability: At a minimum we would like to duplicate
functional mapping results on the same subject at different time
points. Such results are not definitive indicators of mapping
accuracy, but do gauge the reliability of our registration and tracking
techniques in the context of functional mapping. We have run such
repeatability trials on two subjects in which we mapped the same
side of the motor cortex at two different time points. We are
134 | P a g e
pursuing more accurate methods of evaluating repeatability such as
weighting multiple small latency stimulations by their response
amplitudes and using the same stimulation grid pattern which is
saved for each subject with his MRI scan.
Map symmetry: In addition to repeatability we can also perform
symmetry tests in which we compare motor cortex maps generated
on the two sides of the brain. Quantitative evaluation of such results
is difficult to achieve, but qualitatively we expect the two sides of
the motor cortex to be symmetric. We have initiated such symmetry
trials and are exploring result analysis techniques, such as evaluating
whether the motor cortex lies on corresponding gyri.
Surgical validation: An exact validation can be obtained in the
operating room in the case of craniotomy surgeries. Surgeons
currently use electrical stimulators to directly stimulate the brain
surface when they are operating near the motor or sensory cortex.
By tracking the position of such stimulators relative to an MR scan
on which we have overlaid the functional mapping we can verify the
maps. We have not yet had the opportunity to perform such
quantitative validation, but in the neurosurgery case that we had
mapped, the surgeon qualitatively validated our results as accurate.
10.5 System Testing
Testers, who are trained to plan, execute, and report on
application and system code should perform system testing. They
should be aware of scenarios that might not occur to the end user,
like testing for null, negative, and format inconsistent values. A
tester should be able to repeat the steps that caused an error.
The testing of a complete system prior to delivery. The
purpose of system testing is to identify defects that will only surface
when a complete system is assembled. That is, defects that cannot
be attributed to individual components or the interaction between
two components. System testing includes testing of performance,
security, configuration sensitivity, startup and recovery from failure
modes. System Testing is a service for System Builders. It is a fast
and inexpensive way to find out if your system complies with the
135 | P a g e
high “Designed for Windows” compatibility standards set by
Microsoft.
System testing is available for these operating systems:
Windows XP
Windows 2000
Windows ME
Windows Server 2003
Windows Datacenter Server
The following categories are available:
Desktop PC
Mobile PC
Server PC
System using Logo'd Motherboard
Benefits:
You will know in less than two weeks whether your system
qualifies for the logo. You can identify incompatible components
and exchange them for alternatives. Test results documentation that
we provide includes everything needed for a successful submission.
You will save at least 100 man-hours. You will save on special test
equipment such as Foxfire cards
Regression Testing
Each time a new module is added as part of integration
testing the software changes. New data flow paths are established,
new I/O may occur, and new control logic is invoked. These changes
may cause problems with functions that previously worked
flawlessly. In the context of an integration test strategy, regression
testing is the re-execution of some subset of tests that have already
been conducted to ensure that changes have not propagated
unintended side effects.
In a broader context, successful tests (of any kind) result in
the discovery of errors, and errors must be corrected. Whenever
software is corrected, some aspect of the software configuration
136 | P a g e
(the program, its documentation, or the data that support it) is
changed. Regression testing is the activity that helps to ensure that
changes (due to testing or for other reasons) do not introduce
unintended behavior or additional errors.
Regression testing may be conducted manually, by re-
executing a subset of all test cases or using automated
capture/playback tools. Capture/playback tools enable the software
engineer to capture test cases and results for subsequent playback
and comparison.
The regression test suite (the subset of tests to be executed)
contains three different classes of test cases:
A representative sample of tests that will exercise all software
functions.
Additional tests that focus on software functions that are likely
to be affected by the change.
Tests that focus on the software components that have been
changed.
As integration testing proceeds, the number of regression tests
can grow quite large.
Therefore, the regression test suite should be designed to
include only those tests that address one or more classes of errors in
each of the major program functions. It is impractical and inefficient
to re-execute every test for every program function once a change
has occurred.
Smoke Testing:
Smoke testing is an integration testing approach that is
commonly used when "shrink- wrapped" software products are
being developed. It is designed as a pacing mechanism for time-
critical projects, allowing the software team to assess its project on
a frequent basis. In essence, the smoke testing approach
encompasses the following activities:
1. Software components that have been translated into code are
integrated into a "build." A build includes all data files, libraries,
reusable modules, and engineered components that are
required to implement one or more product functions;
137 | P a g e
2. A series of tests is designed to expose errors that will keep the
build from properly performing its function. The intent should
be to uncover "show stopper" errors that have the highest
likelihood of throwing the software project behind schedule.
3. The build is integrated with other builds and the entire product
(in its current j form) is smoke tested daily. The integration
approach may be top down or bottom up. The daily frequency
of testing the entire product may surprise some readers.
However, frequent tests give both managers and practitioners a
realistic assessment of integration testing progress. We can
describes the smoke test in the following manner:
The smoke test should exercise the entire system from end
to end. It does not have to be exhaustive, but it should be capable of
exposing major problems. The smoke test should be thorough
enough that if the build passes, you can assume that it is stable
enough to be tested more thoroughly.
Smoke testing provides a number of benefits when it is
applied on complex, time- critical software engineering projects:
Integration risk is minimized. Because smoke tests are
conducted daily, incompatibilities and other show stopper
errors are uncovered early, thereby reducing the likelihood of
serious schedule impact when errors are uncovered.
The quality of the end-product is improved. Because the
approach is construction (integration) oriented, smoke testing is
likely to uncover both functional errors and architectural and
component-level design defects. If these defects are corrected
early, better product quality will result.
Error diagnosis and collection are simplified. Like all integration
testing approaches, errors uncovered during smoke testing are
likely to be associated with "new software increments"-that is,
the software that has just been added to the build(s) is a
probable cause of a newly discovered error.
Progress is easier to assess. With each passing day, more of the
software has been integrated and more has been demonstrated
to work. This improves team morale and gives managers a good
indication that progress is being made.
138 | P a g e
Test Oracles
To test any program, we need to have a description of its
expected behavior and a method of determining whether the
observed behavior conforms to the expected behavior. For this we
need a test oracle.
139 | P a g e
important that the behavior of the system or component be
unambiguously specified and that the specification itself is error-
free. In other words, the specifications should actually specify the
true and correct system behavior. These conditions are hard to
satisfy. After all, it is the activity of some earlier phase that
determines these specifications, and these activities might be error-
prone. Hence, the specifications themselves may contain errors, be
imprecise, or contain ambiguities. Such shortcomings in the
specifications are the major cause of situations where one party
claims that a particular condition is not a failure while the other
claims it is. However, there is no easy solution to this problem.
Testing does require some specifications against which the given
system is tested.
There are some systems where oracles are automatically
generated from specifications of programs or modules. With such
oracles, we are assured that the output of the oracle is consistent
with the specifications. However, even this approach does not solve
all our problems, because of the possibility of errors in the
specifications. Consequently, an oracle generated from the
specifications will only produce correct results if the specifications
are correct, and it will not be dependable in the case of specification
errors. Furthermore, such systems that generate oracles from
specifications are likely to require formal specifications, which are
frequently not generated during design.
7. Test Cases and Test Criteria
Having test cases that are good at revealing the presence of
faults is central to successful testing. The reason for this is that if
there is a fault in a program, the program can still provide the
expected behavior for many inputs. Only for the set of inputs that
exercise the fault in the program will the output of the program
deviate from the expected behavior. Hence, it is fair to say that
testing is as good as its test cases.
Ideally, we would like to determine a set of test cases such
that successful execution of all of them implies that there are no
errors in the program. This ideal goal cannot usually be achieved
140 | P a g e
due to practical and theoretical constraints. Each test case costs
money, as effort is needed to generate the test case, machine time
is needed to execute the program for that test case, and more effort
is needed to evaluate the results. Therefore, we would also like to
minimize the number of test cases needed to detect errors. These
are the two fundamental goals of a practical testing activity-
maximize the number of errors detected and minimize the number
of I test cases (i.e., minimize the cost). As these two are frequently
contradictory, the problem of selecting the set of test cases with
which a program should be tested becomes more complex.
While selecting test cases the primary objective is to ensure
that if there is an I error or fault in the program, it is exercised by
one of the test cases. An ideal test case set is one that succeeds
(meaning that its execution reveals no errors) only I if there are no
errors in the program. One possible ideal set of test cases is one that
includes all the possible inputs to the program. This is often called
exhaustive testing. However, exhaustive testing is impractical and
infeasible, as even for small programs the number of elements in
the input domain can be extremely large (i.e., it is not practical due
to cost constraints).
Hence, a realistic goal for testing is to select a set of test
cases that is close to ideal. How should we select our test cases? On
what basis should we include some element of the program domain
in the set of test cases and not include others? For this test selection
criterion (or simply test criterion) can be used. For a given program
P and its specifications, a test selection criterion specifies the
conditions that must be satisfied by a set of test cases T. The
criterion becomes a basis for test case selection. For example, if the
criterion is that all statements in the program be executed at least
once during testing, then a set of test cases T satisfies this criterion
for a program P if the execution of P with T ensures that each
statement in P is executed at least once.
There are two aspects of test case selection-specifying a
criterion for evaluating a set of test cases, and generating a set of
test cases that satisfy a given criterion. As we will see, many test
141 | P a g e
case criteria have been proposed. However, generating test cases
for most of these is not easy and cannot, in general, be automated
fully. Often, a criterion is specified and the tester has to generate
test cases that satisfy the criterion. In some cases, guidelines are
available for deciding test cases. Overall, the problem of test case
selection is very challenging, and current solutions are limited in
scope.
There are two fundamental properties for a testing
criterion: reliability and validity. A criterion is reliable if all the sets
(of test cases) that satisfy the criterion detect the same errors. That
is, it is insignificant which of the sets satisfying the criterion is
chosen; every set will detect exactly the same errors. A criterion is
valid if for any error in the program there is some set satisfying the
criterion that will reveal the error. A fundamental theorem of testing
is that if a testing criterion is valid and reliable, if a set satisfying the
criterion succeeds (revealing no faults) then the program contains
no errors. However, it has been shown that no algorithm exists that
will determine a valid criterion for an arbitrary program.
8. Test Plan Activities During Testing
A test plan is a general document for the entire project that
defines the scope, approach to be taken, and the schedule of testing
as well as identifies the test items for the entire testing process and
the personnel responsible for the different activities of testing. The
test planning can be done well before the actual testing commences
and can be done in parallel with the coding and design phases. The
inputs for forming the test plan are: (1) project plan, (2)
requirements document, and (3) system design document. The
project plan is needed to make sure that the test plan is consistent
with the overall plan for the project and the testing schedule
matches that of the project plan. The requirements document and
the design document are the basic documents used for selecting the
test units and deciding the approaches to be used during testing. A
test plan should contain the following:
Test unit specification.
Features to be tested.
142 | P a g e
Approach for testing.
Test deliverables.
Schedule.
Personnel allocation.
One of the most important activities of the test plan is to
identify the test units. A test unit is a set of one or more modules,
together with associated data, that are from a single computer
program and that are the object of testing. A test unit can occur at
any level and can contain from a single module to the entire system.
Thus, a test unit may be a module, a few modules, or a complete
system.
As seen earlier, different levels of testing have to be used
during the testing activity. The levels are specified in the test plan by
identifying the test units for the project. Different units are usually
specified for unit, integration, and system testing. The identification
of test units establishes the different levels of testing that will be
performed in the project. Generally, a number of test units are
formed during the testing, starting from the lower-level modules,
which have to be unit tested. That is, first the modules that have to
be tested individually are specified as test units. Then the higher-
level units are specified, which may be a combination of already
tested units or may combine some already tested units with some
untested modules. The basic idea behind forming test units is to
make sure that testing is being performed incrementally, with each
increment including only a few aspects that need to be tested.
An important factor while forming a unit is the "testability"
of a unit. A unit should be such that it can be easily tested. In other
words, it should be possible to form meaningful test cases and
execute the unit without much effort with these test cases.
For example, a module that manipulates the complex data
structure formed from a file input by an input module might not be
a suitable unit from the point of view of testability, as forming
meaningful test cases for the unit will be hard, and driver routines
will have to be written to convert inputs from files or terminals that
143 | P a g e
are given by the tester into data structures suitable for the module.
In this case, it might be better to form the unit by including the input
module as well. Then the file input expected by the input module
can contain the test cases.
Features to be tested include all software features and
combinations of features that should be tested. A software feature
is a software characteristic specified or implied by the requirements
or design documents. These may include functionality, performance,
design constraints, and attributes.
The approach for testing specifies the overall approach to
be followed in the current project. The techniques that will be used
to judge the testing effort should also be specified. This is
sometimes called the testing criterion or the criterion for evaluating
the set of test cases used in testing. In the previous sections we
discussed many criteria for evaluating and selecting test cases.
Testing deliverables should be specified in the test plan
before the actual testing begins. Deliverables could be a list of test
cases that were used, detailed results of testing, test summary
report, test log, and data about the code coverage. In general, a test
case specification report, test summary report, and a test log should
always be specified as deliverables. Test case specification is
discussed later. The test summary report summarizes the results of
the testing activities and evaluates the results. It defines the items
tested, the environment in which testing was done, and any
variations from the specifications observed during testing. The test
log provides a chronological record of relevant details about the
execution of the test cases.
The schedule specifies the amount of time and effort to be
spent on different activities of testing, and testing of different units
that have been identified. Personnel allocation identifies the
persons responsible for performing the different activities.
10.6 The Art of Debugging
Software has increased tremendously over the past
decades; advances in software engineering techniques for producing
144 | P a g e
the software have been only moderate, at best. Software
development has remained primarily a labor-intensive effort and
thus subject to human limitations. As Frederick Brooks explained
over a quarter of a century ago,1 there is a big difference between
an isolated program created by a lone programmer and a
programming systems product. A programming systems product
“can be run, tested, repaired, and extended by anybody … in many
operating environments, for many sets of data” and forms a part of
“a collection of interacting programs, coordinated in function and
disciplined in format, so that the assemblage constitutes an entire
facility for large tasks.” Brooks asserted a nine-fold increase in cost
to develop a programming system product from an isolated program
With the advent of the Internet and the World Wide Web, the
problems that were recognized a quarter century ago as having “no
silver bullet” for the solution1 have been magnified. The challenges
of designing and testing distributed computing systems, with
distributed data and Web services, with the need for coexistence of
heterogeneous platforms, unpredictable run-time environments,
and so on, make the already difficult problem even harder.
A key ingredient that contributes to a reliable programming
systems product is the assurance that the program will perform
satisfactorily in terms of its functional and nonfunctional
specifications within the expected deployment environments. In a
typical commercial development organization, the cost of providing
this assurance via appropriate debugging, testing, and verification
activities can easily range from 50 to 75 percent of the total
development cost. Thus we should consider what is involved in
these activities that make them so challenging and so expensive.
Since one of the goals of this special issue of the IBM
Systems Journal is to be accessible to the students of software
engineering at large, we define relevant terminology and its
implications (we include formal notation for this terminology, but it
is not essential for the basic understanding of problem definition).
Note that the terms “debugging,” “testing,” and “verification” are
not mutually exclusive activities, especially in everyday practice. The
145 | P a g e
definitions draw distinctions, but the boundaries may actually be
fuzzy. We begin with a software program written in a programming
language (let P be the program written in language L). The program
is expected to satisfy a set of specifications, where those
specifications are written in a specification language (call the set of
specifications = { 1, 2, 3, … , n} and the specification language
). In most real-world cases, the specification language ( ) is the
natural language of the development team (i.e., English, Spanish,
etc.).
Debugging: The process of debugging involves analyzing and
possibly extending (with debugging statements) the given program
that does not meet the specifications in order to find a new program
that is close to the original and does satisfy the specifications (given
specifications and a program P, not satisfying some k , find a
program P' “close” to P that does satisfy k). Thus it is the process of
“diagnosing the precise nature of a known error and then correcting
it.”2
Verification: Given a program and a set of specifications, show that
the program satisfies those specifications (given P and a set of
specifications = { 1, 2, 3, … , n}, show that P satisfies ). Thus,
verification is the process of proving or demonstrating that the
program correctly satisfies the specifications. 2 Notice that we use
the term verification in the sense of “functional correctness,” which
is different from the typical discussion of verification activities
discussed in some software engineering literature,3,4 where it
applies to ensuring that “each step of the development process
correctly echoes the intentions of the immediately preceding step.”
Testing: Whereas verification proves conformance with a
specification, testing finds cases where a program does not meet its
specification (given specifications and a program P, find as many of
1, 2, 3, … , p not satisfied by P). Based on this definition, any
activity that exposes the program behavior violating a specification
can be called testing. In this context, activities such as design
reviews, code inspections, and static analysis of source code can all
be called testing, even though code is not being executed in the
146 | P a g e
process of finding the error or unexpected behavior. These activities
are sometimes referred to as “static testing.”5 Of course, execution
of code by invoking specific test cases targeting specific functionality
(using, for example, regression test suites) is a major part of testing.
Validation: Validation is the process of evaluating software, at the
end of the development process, to ensure compliance with
requirements. Note that the verification community also uses the
term validation to differentiate formal functional verification from
extensive testing of a program against its specifications.
Defect: Each occurrence of the program design or the program code
that fails to meet a specification is a defect (bug).
9.1 Debugging, testing, and verification mapped to the software
life cycle
In a typical software development process, irrespective of
the specific development model followed (i.e., waterfall, iterative,
spiral, etc.), certain basic activities are required for a successful
execution of a project. In this context, it is useful to know the
specific roles played by debugging, testing, and verification.
Debugging. The purpose of debugging is to locate and fix the
offending code responsible for a symptom violating a known
specification. Debugging typically happens during three activities in
software development, and the level of granularity of the analysis
required for locating the defect differs in these three. The first is
during the coding process, when the programmer translates the
design into an executable code. During this process the errors made
by the programmer in writing the code can lead to defects that need
to be quickly detected and fixed before the code goes to the next
stages of development. Most often, the developer also performs
unit testing to expose any defects at the module or component
level. The second place for debugging is during the later stages of
testing, involving multiple components or a complete system, when
unexpected behavior such as wrong return codes or abnormal
program termination (“abends”) may be found. A certain amount of
debugging of the test execution is necessary to conclude that the
program under test is the cause of the unexpected behavior and not
147 | P a g e
the result of a bad test case due to incorrect specification,
inappropriate data, or changes in functional specification between
different versions of the system. Once the defect is confirmed,
debugging of the program follows and the misbehaving component
and the required fix are determined. The third place for debugging is
in production or deployment, when the software under test faces
real operational conditions. Some undesirable aspects of software
behavior, such as inadequate performance under a severe workload
or unsatisfactory recovery from a failure, get exposed at this stage
and the offending code needs to be found and fixed before large-
scale deployment. This process may also be called “problem
determination,” due to the enlarged scope of the analysis required
before the defect can be localized.
Verification. In order to verify the functional correctness of a
program, one needs to capture the model of the behavior of the
program in a formal language or use the program itself. In most
commercial software development organizations, there is often no
formal specification of the program under development. Formal
verification is used routinely by only small pockets of the industrial
software community, particularly in the areas of protocol
verification and embedded systems. Where verification is practiced,
the formal specifications of the system design (derived from the
requirements) are compared to the functions that the code actually
computes. The goal is to show that the code implements the
specifications.
Testing. Testing is clearly a necessary area for software
validation. Typically, prior to coding the program, design reviews
and code inspections are done as part of the static testing effort.
Once the code is written, various other static analysis methods
based on source code can be applied. The various kinds and stages
of testing that target the different levels of integration and the
various modes of software failures are discussed in a wide body of
literature. The testing done at later stages is “black box” testing,
based on external specifications, and hence does not involve the
understanding of the detailed code implementations. Typically,
148 | P a g e
system testing targets key aspects of the product, such as recovery,
security, stress, performance, hardware configurations, software
configurations, etc
Current state of technology and practice
In commercial hardware development, it is a common
practice to capture the requirements and specifications in a formal
manner and use them extensively in the development and testing of
the products. The cost of bad or imprecise specification is high and
the consequences are severe. In contrast, software poses feasibility
challenges for the capture and use of such information. A software
development organization typically faces:
Ever-changing requirements (which, in many cases, are
never written down) Consequently, in most software organizations,
neither the requirements nor the resulting specifications are
documented in any formal manner. Even if written once, the
documents are not kept up to date as the software evolves (the
required manual effort is too burdensome in an already busy
schedule). Specifications captured in natural languages are not
easily amenable to machine processing.
Should one wish to go beyond fuzzy specifications written in
a natural language, there is a long history of many intellectually
interesting models and techniques that have been devised to
formally describe and prove the correctness of software: Hoare-
style assertions, Petri nets, communicating sequential processes,
temporal logic, algebraic systems, finite state specifications, model
checking, and interval logics. A key aspect of formal modeling is that
the level of detail needed to capture the adequate aspects of the
underlying software program can be overwhelming. If all of the
details contained in the program are necessary to produce the
specification or test cases, then the model may well be at least as
large as the program, thus lessening its attractiveness to the
software engineers. For example, there have been several attempts
to model software programs as finite state machines (FSMs). While
FSMs have been successful in the context of embedded systems and
protocol verification, state-based representation of software leads
149 | P a g e
to explosion in the number of states very quickly. This explosion is a
direct result of software constructs such as unbounded data
structures, unbounded message queues, the asynchronous nature of
different software processes (without a global synchronizing clock),
and so on. In order to be relevant and manageable, software models
have to use techniques such as symbolic algorithms, partial order
reduction, compositional reasoning, abstraction, symmetry, and
induction.
Debugging. As is well known among software engineers,
most of the effort in debugging involves locating the defects.
Debugging is done at the smallest level of granularity during the
coding process. In the early years of software development, defects
that escaped code reviews were found by compilation and
execution. Through a painful process (such as inserting print
statements for the known outputs at the appropriate places in the
program), a programmer could locate the exact location of the error
and find a suitable fix.
Even today, debugging remains very much an art. Much of
the computer science community has largely ignored the debugging
problem.15 Eisenstadt16 studied 59 anecdotal debugging experiences
and his conclusions were as follows: Just over 50 percent of the
problems resulted from the time and space chasm between
symptom and root cause or inadequate debugging tools. The
predominant techniques for finding bugs were data gathering (e.g.,
print statements) and hand simulation. The two biggest causes of
bugs were memory overwrites and defects in vendor-supplied
hardware or software.
To help software engineers in debugging the program during
the coding process, many new approaches have been proposed and
many commercial debugging environments are available. Integrated
development environments (IDEs) provide a way to capture some of
the language-specific predetermined errors (e.g., missing end-of-
statement characters, undefined variables, and so on) without
requiring compilation. One area that has caught the imagination of
the industry is the visualization of the necessary underlying
150 | P a g e
programming constructs as a means to analyze a program. There is
also considerable work in trying to automate the debugging process
through program slicing.
When the testing of software results in a failure, and
analysis indicates that the test case is not the source of the problem,
debugging of the program follows and the required fix is
determined. Debugging during testing still remains manual, by and
large, despite advances in test execution technology. There is a clear
need for a stronger (automatic) link between the software design
(what the code is intended to do), test creation (what the test is
trying to check), and test execution (what is actually tested)
processes in order to minimize the difficulty in identifying the
offending code when a test case fails. Debugging during production
or after deployment is very complicated. Short of using some
advanced problem determination techniques for locating the
specific defect or deficiency that led to the unexpected behavior,
this debugging can be painful, time consuming, and very expensive.
The problems are exacerbated when problem determination
involves multiple interacting software products. As debugging
moves away from actual programming of the source code (for
example, in system test, or even later in customer beta test),
problem determination becomes even more manual and time-
consuming.
Verification. As discussed earlier, in order to verify the
functional correctness of a program, one needs to capture the
specifications for the program in a formal manner. This is difficult to
do, because the details in even small systems are subtle and the
expertise required to formally describe these details is great. One
alternative to capturing a full formal specification is to formalize
only some properties (such as the correctness of its synchronization
skeleton) and verify these by abstracting away details of the
program. For network protocols, reactive systems, and
microcontroller systems, the specification of the problem is
relatively small (either because the protocols are layered with well-
defined assumptions, inputs, and outputs, or because the size of the
151 | P a g e
program or the generality of the implementation is restricted) and
hence tractable by automatic or semiautomatic systems. There is
also a community that builds a model representing the software
requirements and design and verifies that the model satisfies the
program requirements. However, this does not assure that the
implemented code satisfies the property, since there is no formal
link between the model and the implementation (that is, the
program is not derived or created from the model).
Historically, software verification has had little impact on
the real world of software development. Despite the plethora of
specification and verification technologies, the problem has been in
applying these techniques and theories to full-scale, real-world
programs. Any fully detailed specification must, by its very nature,
be as complex as the actual program. Any simplification or
abstraction may hide details that may be critical to the correct
operation of the program. Similarly, any proof system that can
automatically verify a real program must be able to handle very
complex logical analyses, some of which are formally undecidable.
The use of complex theorem-proving systems also requires a high
skill level and does not scale to large programs. The human factor
also enters into the equation: crafting a correct specification
(especially one using an obscure formal system) is often much more
difficult than writing the program to be proved (even one written in
an obscure programming language). To date, success in program
verification has come in restricted domains where either the state
space of the problem is constrained or only a portion of the program
is actually verified. General theorem provers, model checkers, state
machine analyzers, and tools customized to particular applications
have all been used to prove such systems.
Testing. Dijkstra's criticism, “Program testing can be used to
show the presence of bugs, but never to show their absence” is well
known. From his point of view, any amount of testing represents
only a small sampling of all possible computations and is therefore
never adequate to assure the expected behavior of the program
under all possible conditions. He asserted that “the extent to which
152 | P a g e
the program correctness can be established is not purely a function
of the program's external specifications and behavior but it depends
critically upon its internal structure.” However, testing has become
the preferred process by which software is shown, in some sense, to
satisfy its requirements. This is primarily because no other approach
based on more formal methods comes close to giving the scalability
and satisfying the intuitive “coverage” needs of a software engineer.
10.7 Self Test
1. Define Testing and its techniques.
2. What is the objective of testing?
3. Explain Unit testing and Integration testing.
4. What are Test Oracles?
153 | P a g e
UNIT-11
154 | P a g e
MAINTENANCE
11.1 Introduction
Software maintenance is a task that every development
group has to face when the software is delivered to the customer’s
site, installed and is operational. Software Maintenance is a very
broad activity that includes error corrections, enhancements of
capabilities, deletion of obsolete capabilities, and optimization.
Because change is inevitable, mechanisms must be developed for
evaluating, controlling and making modifications. So any work done
to change the software after it is in operation is considered to be
maintenance. The purpose is to preserve the value of software over
time. The value can be enhanced by expanding the customer base,
meeting additional requirements, becoming easier to use, more
efficient and employing newer technology. Maintenance may span
for 500 years, whereas development may be 1-2 years.
11.2 Categories of Maintenance
The only thing that remains constant in life is “CHANGE’. As
the specification of the computer systems change, reflecting
changes in the external world, so must the system themselves. More
than two-fifths of maintenance activities are extensions and
modifications requested by the users. There are three major
categories of software maintenance, which are discussed below :
11.3 Corrective Maintenance
This refers to modifications initiated by defects in the
software. A defect can result from design errors, logic errors and
coding errors. Design errors occur when, changes made to the
software are incorrect, incomplete, wrongly communicated or the
change request is misunderstood. Logic errors result from invalid
tests and conclusions, incorrect implementation of design
specifications, faulty logic flow or incomplete test data. Coding
155 | P a g e
errors are caused by incorrect implementation of detailed logic
design and incorrect use of the source code logic.
In the event of system failure due to an error, actions are
taken to restore operation of the software system. Due to pressure
from management, maintenance personnel sometimes resort to
emergency fixes known as “patching”. Unforeseen ripple effects
imply that a change to one part of a program may affect other
sections is an unpredictable manner, thereby leading to distortion in
the logic of the system. This is often due to lack of time to carry out
a through “impact analysis” before effecting the change.
11.4 Adaptive Maintenance
It includes modifying the software to match changes in the
ever-changing environment. The term environment in this context
refers to the totality of all conditions and influences which act from
outside upon the software, for example, business rules, government
policies, work patterns, software and hardware operating platforms.
A change to the whole or part of this environment will
require a corresponding modification of the software.
Thus, this type of maintenance includes any work initiated
as a consequence of moving the software to a different hardware or
software platform-compiler, operating system or new processor.
Any change in the government policy can have far-reaching
ramifications on the software.
11.5 Perfective Maintenance
It means improving processing efficiency or performance, or
restructuring the software to improve changeability. When the
software becomes useful, the user tends to experiment with new
cases beyond the scope for which it was initially developed.
Expansion in requirements can take the form of enhancement of
existing system functionality or improvement in computational
efficiency; for example, providing a Management Information
System with a data entry Module or a new message handling facility.
It is impossible to produce systems of any size, which do not need to
be changed. Over the lifetime of a system, its original requirements
156 | P a g e
will be modified to reflect changing user and customer needs. The
system’s environment will change as new hardware is introduced.
Errors, undiscovered during system validation, may emerge and
require-repair. The maintenance of existing software can accour for
over 70% of all effort expended by a software organization.
The process of chagning a system after it has been delivered
and is in use is called software maintenance. The changes may
involve simple changes to correct coding errors, more extensive
changes to correct design errors or significant enhancements to
correct specification errors or accommodate new requirements.
Therefore, maintenance is the process of chagning a system to
maintain its ability to survive. We may define maintenance by
describing four activities that are undertaken after a program is
released for use.
1. Corrective maintenance is concerned with fixing reported errors
in the software. Coding errors are usually relatively cheap to
correct, design errors are more expensive as they may involve
the rewriting of several program components. Requirements
errors are the most expensive to repair because of the extensive
system redesign which may be necessary.
2. Adaptive maintenance means changing the software to some
new environment such as a different hardware platform or for
use with a different hardware platform or for use with a
different operating system. The software functionality does not
radically change.
3. Perfective maintenance involves implementing new functional
or non-functional system requirements. These are generated by
software customers as their organization or business changes.
4. Preventive maintenance involves when software is changed to
improve future maintainability or reliability or to provide a
better basis for future enhancement often called preventive
maintenance.
5. It is difficult to find up-to-date figures for the relative effort
devoted to these different types of maintenance. A survey by
157 | P a g e
Lientz and Swanson (1980) discovered that about 56% of
maintenance was perfective and preventive, 18% adaptive, and
17% corrective. We can show this in the figure below.
159 | P a g e
Such data can provide a manager with an indication of the
efficacy of new techniques and tools. At each level of the software
engineering process, maintainability should be considered:
1. During requirement review, areas of future enhancement and
potential revision are noted. Software portability issues are
discussed and system interfaces are considered.
2. During design review architectural design, and procedural
design and interface design are evaluated for ease of
modification and overall design quality.
3. Code reviews stress style and internal documentation.
Each step can provide hints portions of the program that
may require preventive maintenance before the software is formally
released. The most formal maintenance review occurs at the
conclusion of testing and is called the configuration review. The
configuration review ensures that all elements of the software
configuration are complete, understandable and filed or
modification control.
11.8 Maintenance Tasks
Initially, a maintenance organization must be established,
reporting and evaluation procedures must be described and a
standardized sequence of events must be defined for each
maintenance request. In addition, a record-keeping procedure for
maintenance activities should be established and review and
evaluation criteria defined.
11.9 A Maintenance Organization
In the case of maintenance formal organizations rarely exist
and maintenance is often performed on a catch-as-catch-can basis.
Maintenance requests are channeled through a maintenance
controller who forwards each request for evaluation to a system
supervisor. The system supervisor is a member of the technical staff
who has been assigned the responsibility to become familiar with a
small subset of production programs. Once an evaluation is made, a
change control authority must determined the action to be taken.
This organization reduces confusion and improves the flow of
maintenance activities.
160 | P a g e
The software developer normally generally generates a
maintenance request form (MRF), sometimes called a software
problem report that is completed by the user who desires a
maintenance activity. If an error is encountered , a complete
description of the circumstance leading to the error must be
included. For adaptive or perfective maintenance requests, a brief
change specification is submitted. The MRF is an externally
generated document that is used as a basis for planning the
maintenance task. The software organization develops a software
change report that indicates:
1. The magnitude of effort required satisfying an MRF.
2. The nature of modifications required.
3. The priority of the request.
4. After-the-fact data about the modification.
The SCR is submitted to a change control authority before
further maintenance planning is initiated.
11.10 Flow of Events
The first requirement is to determine the type of
maintenance that is to be conducted. A user may view a request as
an indication of software error while a developer may-view the
same request as adaption or enhancement.
From a flow, a request for corrective maintenance begins
with an evaluation of error severity. If a severe error exists,
personnel are assigned under the direction of the system supervisor
and problem analysis beguns immediately. For less severe errors,
the request for corrective maintenance is evaluated and categorized
and then scheduled in conjunction with other tasks requiring
software development resources.
161 | P a g e
Figure : Maintenance Flow Of Events
Above figure is sufficient to indicate the flow of events in
the maintenance.
Record Keeping for software maintenance has been non-
existent. So we are frequently unable to assess the effectiveness of
maintenance techniques, incapable of determining the quality of a
production program, and unwilling to determine what maintenance
really costs.
162 | P a g e
Swanson provides a comprehensive list of data for
recording:
1. Program identification.
2. Number of source statements.
3. Number of m/e code instructions.
4. Programming language used.
5. Program installation date.
6. Number of program runs since installation.
7. Number of processing failures.
8. Program change level and identification.
9. Number of source statements added by program change.
10. Number of source statements deleted by program change.
11. Number of person-hours spent per change.
12. Program change date.
13. Identification of software engineer.
14. MRF identification.
15. Maintenance type.
16. Maintenance start and close dates.
17. Cumulative number of person-hours spent on maintenance.
18. Net benefits associated with maintenance performed.
The following model has been suggested as a predictor for
the number of person-months, E.maint, expended on software
maintenance annually.
E.maint = ACT * KLOC 1.05
where ACT = Annual change traffic.
163 | P a g e
An evaluation of software maintenance activities is often
complicated by a lack of hard data. If record keeping is initiated, a
number of measures of maintenance performance may be
developed Swanson presents an abbreviated list of potential
measures:
Average number of processing failures per program run,
Total person-hours spent in each maintenance category.
Average number of program changes made per program, per
language, per maintenance type.
Average number of person-hours spent per source statement
added or deleted due to maintenance.
Average person-hours spent per language.
Average turnaround time for an MRF.
Percentage of maintenance requests by type.
The seven measures described above can provide a
quantitative framework from which decisions on development
technique, language selection, maintenance effort projections,
resource allocation and many other issues can be made. Such data
can be applied to evaluate the maintenance task.
11.11 Maintenance Side Effects
When used in the context of software maintenance, the
term, “side effects” implies an error or other undesirable behavior
that occurs as a result of modification. There are three major
categories for side effects defined by Freedman & Weinberg.
11.12 Coding Side Effects
A simple change to a single statement can sometimes have
disastrous results. Change invites error and error always leads to
problems. Although every code modification has the potential for
introduction error, the following set of change tends to be more
error-prone than others:
1. A subprogram is deleted or changed.
2. A statement label is deleted or modified.
3. An identifier is deleted or modified.
164 | P a g e
4. Changes are made to improve execution performance.
5. File open or close is modified.
6. Logical operators are modified.
7. Design changes are translated into major code changes.
8. Changes are made to logical tests of boundary conditions.
Coding side effects range from nuisance errors detected and
remedied during regression testing to problems that cause software
failure during operation.
11.13 Data Side Effects
Data side effects occur as a result of modifications made to
the software information structure. The following changes in data
frequently result in side effects:
1. Redefinition of local and global constants.
2. Redefinition of record or file formats.
3. Increase or decrease in the size of an array or a higher-order
data structure.
4. Modification to global data.
5. Reinitialization of control flags or pointers.
6. Rearrangement of arguments for I/O or subprograms.
11.14 Documentation Side Effects
Documentation side effects occur when changes to source
code not reflected in the design documentation or user-oriented
manuals. Whenever a change to data flow, design architecture,
module procedure or any other related characteristic is made,
supporting technical documentation must be updated. Design
documentation that doesn’t accurately reflect the current state of
the software is probably worse than no documentation at all.
If modification to the executable software are not reflected
in user documentation side effects are guaranted. Documentation
side effects can be reduced substantially if the entire configuration
is reviewed to re-released of the software. In fact, some
165 | P a g e
maintenance requests may require no change to software design or
source code, but indicate a lack of clarity in user documentations.
11.15 Maintaining “Alien Code”
Nearly every mature software organization must maintain
programs that were developed 15 or more years ago. Such
programs are sometimes called ”aline code” because:
No current member of the technical staff worked on
development of the program.
No development methodology was applied, therefore poor data
and architectural design resulted, documentation is incomplete
and a record of past changes is sketchy.
For the maintenance of alien code Yourdon provides following
suggestions:
Study the program, try to get as much background information
as possible.
Try to become familiar with the overall flow of control of the
program.
Evaluate the reasonableness of existing documentation, insert
your own comments in the listing if you think they will help.
Make good use of cross reference listings, symbol tables.
Make changes to the program with the greatest caution.
Don’t try to share the use of temporary variables and working
storage that already exist in the program.
Don’t try to share the use of temporary variables and working
storage that already exist in the program.
Keep detailed records.
Avoid the irrational urge to throw the program away and rewrite
it.
Do inset error checking.
11.16 Self Test
1. What do you mean by maintenance? When it starts? Why is it
required? Justify it with examples.
2. List and describe various types of maintenance. Which are/is
more important and why? Explain through same suitable
example.
166 | P a g e
View publication stats