Workflow
This page elaborates each part of the
workflow graph.
Software engineering an application based on an
incremental/iterative
development process should, in a healthy project, allocate
resources with a distribution profile similar to that shown in
the graphic (RUP bump chart) on the Phases and Iterations
page. The word "increment" in this context means that software is
released in frequent intervals. Hence, we talk about an
"incremental release". The word "iterative" means that the activities associated with software development
(requirements, analysis, design, coding, and testing) are each
undergoing changes at any given time. The only exception to the
iterative rule where all activities are occurring in parallel is
on the day when a new incremental release is produced and all
software artifacts must be checked-in and tagged.
Vision document, Top-level features list, Architectural overview
These documents serve the following purposes:
- Establish the context for the system.
- Define the problem to be solved.
- Describe the core features that form the contractual basis for more detailed requirements.
- Identify key stakeholder and user needs.
- Highlight the overall intent and purpose of the system.
- Present an overview of the architecture.
Except for minor changes, these documents should remain
relatively static after completion of the inception phase. Business and
marketing plans are heavily based on these documents and
therefore, they should not represent a moving target. Any changes
to these documents after the inception phase must be approved by
the business.
Current & Next iteration plan
Each incremental release requires a new project plan in order to
assigned roles and objectives to each team member as a function
of time. The duration of an increment is determined by the rhythm
established by the project. It is not a constant, but rather a
function of several factors such as quality, risk, project phase,
and available resources. Hence, a project plan must not purport
to predict the future for something that has never been done
before. It can only serve to estimate the future. Nevertheless, a
project should be managed such that the duration of an increment
is never longer than five weeks.
Incremental deliverables provide essential feedback to adjust the
allocation of resources, maintain quality standards and keep the
project on track. Five weeks is short enough to obtain meaningful feedback
on the state of the project and yet long enough to implement
some interesting and complex use-cases to impress the customer. Achieving a five-week
release cycle may be difficult in the initial stages of a
project before the team, tools, and process can be setup and calibrated to
each other; project planners should take this fact into account.
If the customer calls to request a new feature or a change
to an existing feature, the request must be addressed on the next
iteration cycle; the current iteration must not be disrupted by
random events.
If a release cannot be delivered after six
weeks then the project could be experiencing a serious problem.
Management must act immediately to corrected the situation. In
such situations be on guard against suggestions to trade off quality
against the calendar.
At the end of a release the customer and/or the customer
representative shall receive whatever was agreed to in writing
before work on the release began. Acceptance criterion should be
clearly stated in advance to mitigate potential problems that can
result from factors like cultural differences.
Project planners should attempt to extrapolate one release beyond
the current one. This means each release begins with two plans:
The 5-week plan and the 10-week plan. The 5-week plan is
submitted for use by the development team at the start of an
incremental release. At the end of the release expected results
from both the 5 and 10 week plans are compared against the actual
results to produce estimation errors. The estimation error for
the 5-week plan should be small or zero. The estimation errors
for the 10-week plan will obviously be larger, but it should at
least be bounded. This error information (trend analysis) is used
to influence decisions for the next 5 and 10 week plans. A
project plan that attempts to predict software deliverables in
detail beyond 10 weeks (e.g. function X will be implemented on
January 22) is really not worth the effort.
Change Request & Problem Reports (CR&PR)
This activity requires a multi-user Web-based tool to
provide a list of all pending change requests
and problem reports. Changes to development artifacts are
proposed through change requests (CRs). Change requests are used
to document and track defects, enhancement requests, and any other
type of request for a change to the software. The benefit of
change requests is that they provide a record of decisions, and
due to the assessment process, they ensure that change impacts are
understood project wide.
All change requests that arise during an
incremental cycle are carefully entered to the CR&PR tool so that
the project planners can consider these for the next release.
Most
problems will be discovered and reported during system and
integration testing by customer and the quality assurance teams.
This is only the case however if developers hold to the rule that
errors and warnings reported by regression tests get the highest
priority.
It may not be feasible to perform full integration testing during
normal iterative development in the case of some large legacy
systems; budget your resources accordingly.
Use-case Scenario Stories (UCSS)
This activity is concerned with creating (in natural-language
text) small scenarios stories that illustrate
ways to use the
system. For example, a way to use a medical clinic could be
stated as follows: "A patient calls the clinic to make an
appointment. The receptionist finds the nearest empty time slot
in the weekly appointment book and schedules the appointment
accordingly." This use case scenario represents a primary (a happy
use-case) scenario. A secondary scenario might be stated as
follows: "A patient calls the clinic to make an appointment. The
receptionist cannot find an empty time slot in the weekly
appointment book and therefore schedules an appointment with
another clinic for which a time slot in the current week is
available." UCSSs should be kept short and simple. The formal and
expanded version of the use-case story is developed in the UML
behavior model. A
use-case diagram displays use-cases with an oval-shaped
symbol. Each use-case symbol must be linked to its
scenario stories and to other related documents. Use-case scenario
stories are documented with a word processor using a standardized
template with sections for Brief Description, Basic Flow,
Alternative Flows, Special Requirements, Pre-Conditions,
Post-Conditions, and Extension Points.
Functional Requirements Specification (FRS)
The FRS provides technical details for the analysis review stage
where the business behavior and system/subsystem structural
models are analyzed for both completeness and correctness. Each requirement in the FRS
will map to one or more elements
in the behavior model. For example, an object in a sequence
diagram.
It is very important to maintain traceability between statements
in the FRS and corresponding elements in the architecture model
in order to estimate the impact and cost of change requests and
also to ensure that every requirement is represented in the model
and hence in the code.
The FRS should be around 80 percent complete by the end of the
inception phase. The remaining 20% will be taken care of during
elaboration and construction. Each iteration will result
in the discovery of new and unforeseen requirements that will add
technical detail to existing features and/or require completely new features.
In any case, the FRS will evolve and mature into its final form
by the end of the transition phase before going into production.
Each incremental release begins with an updated FRS. The contents of
the FRS (and all related documents) must be agreed to in writing
by both customer and developer before the new cycle begins.
Hence, the
FRS document represents a binding contract between customer and
developer and states unequivocally the software capabilities and
related artifacts that shall be delivered at the end of the next
incremental release. Since we are talking about a legal contract, the FRS and
all related documents must be frozen at the start of each
release cycle. If the customer insists on changing the
requirements (i.e. breaking the contract) during the course of an
development cycle, then the customer must absorb any associated
costs. It is necessary to enforce this rule with a cost penalty
to prevent casual change requests, which is a common occurrence
when informal agreements are used.
Because of legal ramifications and consequences to the health of
the project, it is very important to spend sufficient time with the
customer to discover and select the most appropriate requirements for
implementation in the next release. This task requires the
negotiation skills of the project manager since most customers
tend to push for unrealistic delivery schedules. Keep in mind
that bowing to unrealistic demands and promising too many
features in a single release will benefit neither the customer
nor the project since quality and reputations will suffer
as a result. Remember also that two weeks of perfect engineering time
equates to about four weeks of real engineering time. To avoid
any misunderstandings it is recommend that acceptance
criterion define exactly what it means for a release to be
completed.
It is error-prone and costly to manage complex and
changing requirements with a word processor alone. Your modeling,
office, an version control tools should be tightly integrated.
Business Requirements Model (BRM)
The BRM is a behavior model expressed in UML notation that
captures the essential abstractions, features and requirements of
the system from the user's point of view.
As the name implies, this model represents
the specification of the business requirements. The primary
information source for the BRM are the use-case stories. The BRM model replaces the
role of a traditional software requirements specification
document and
forms the basis for all further software development activities.
The discovery of objects required to complete use-case scenarios
and the construction of sequence, communication, activity, robust
analysis, and business process diagrams represent the main work
activities in this model. When you are working on the BRM model
your UML tool should be creating code elements such as classes, methods,
parameters, and data members in the background.
The power of use-cases for capturing, describing, validating and
establishing software requirements lies in the fact that users
can better express their requirements if they can imagine how
they would interact with the system. Since use-case and activity
diagrams consist of collaborating objects and work flow
activities drawn from the problem domain, the customer and domain
experts can easily find the dependencies, activities, objects,
and corresponding responsibilities to construct a meaningful
model.
A robustness model can also be employed to provide a bridge
between the analysis-level view provided by use-case text
descriptions and the views provided by interaction-type diagrams.
Drawing the robustness diagram for a use-case provides a visual
completeness check to show when the entire use-case has been
accounted for. Robustness diagrams are not part of the standard
UML diagram set, but many modeling tools nevertheless provide
support.
It is very important that domain experts from the customer’s side
be available to collaborate with the development team in order to
build an accurate behavior model. This is especially true during
the inception phase. Any conceptual errors which find their way into the
behavior model will quickly propagate throughout the system and
are expensive
to remove once finally discovered.
Because the BRM drives all activities downstream, a use-case
expert should be assigned to the project to serve as the
technical lead responsible for the design, implementation,
quality, testability, reliability, performance, resilience, and
maintainability of the BRM.
Each incremental release cycle begins with a new collection of
prioritized use-case stories to be
implemented. In modeling the use-cases the classes and messages
required to realize the scenarios are identified and hence by
association, the class owners, i.e. the individual developers. In
this way the use-case team-lead knows the members of his
team. At the completion of an
incremental release the team is disbanded.
Teams formed in this manner own all the code needed to
implement or change a use-case scenario. This organization
eliminates the hassle of having to wait for a member of another
team (with other priorities) to implement a code change. From time to time a class owner
may find herself to be a member of more than one use-case team.
This is not the norm, but it is not a problem either. Most
developers can handle the situation of belonging to two or even three use-case
teams concurrently for limited period of time, i.e. the duration
of an incremental cycle.
Highest-risk use-case collection
After the BRM team have modeled a sufficient number
of business use-cases (technical use-cases appear elsewhere in
the architecture) from the use-case scenario stories, this set of use-cases
are analyze to
identify those that represent the highest remaining risks
to the project. Each use-case in the behavior model is therefore ranked
according to the risk it presents to the project. From the
complete set of use-cases, a subset is selected to form a
collection of as many use-cases as can reasonably be implemented
in the span of time allocated to an incremental release; 5-weeks on average.
The
highest priority use-case in the collection is the first one to
“attack”. High-risk use-cases are often difficult to implement
and test and the project plan should take this into account. At
the beginning of each project phase there will be lots of
high-risk use-cases in the queue which may slow things down
because of the modeling and implementation challenges they
represent.
Nevertheless, it is better to discover and attack the difficult
problems early while there is still sufficient time and resources
to do the job right. After the difficult cases are out of the way
the rate of development will accelerate as you take on the easier
cases. Make sure the management/customer is aware of this
strategy, otherwise they might think your progress is too slow
and that the delivery date will never be achieved.
System architecture model
This aspect of the architecture focuses at the system level on
three main concerns:
The domain model.
The domain model sets the context (visually) for the entire
project and establishes a consistent vocabulary that binds
business and IT together. By modeling the domain, rather than
ad-hoc functional requirements, which are constantly evolving as
the system develops, we can produce systems that are flexible and
sustainable. The domain model therefore becomes the context for
all function related decision making throughout the project; it is
the key artifact of the system architecture.
The domain model is constructed as a class diagram even though
the "classes" in the diagram normally represent class categories - domain level abstractions contained within subsystems.
The domain model shows the messages, cardinality, and
associations between conceptual objects in the problem domain. Associations
between domain objects may appear as noun-phrases such as
“Records sale of”, “Is paid by”, “Works for”, and so on.
It is highly recommended to use the MIC method for building the
domain model so that the class archetypes, Moment-Interval (MI),
Role, Description, and Party, Place or
Thing (PPT) are clearly identified.
If the
removal of an object in the domain model does not cause the model
to collapse (i.e. render it useless) then the object in question
does not qualify as a domain object and should be removed since
it is not important to the analysis and design at this level of
abstraction.
The domain model is the result of an object-oriented analysis of
the problem domain in which all conceptual entities that form the vocabulary of the problem
domain have been identified. One must avoid the natural tendency to invent classes
during domain analysis. The real task is to discover domain
entities, not invent them.
Inter-subsystem coupling dependences. This aspect of the
system architecture focuses on the visibility, associations, and
communication mechanisms between the subsystems as well as any connections to external
systems. Since each subsystem consists of abstraction layers it
is important to identify these and map each process,
activity, and object to a specific layer. For example, in the
persistence layer of subsystem_X connections to building block
components DataSet, CacheStore, QueryProvider must
be shown in the deployment and component diagrams.
Data model. The model of the database scheme associated with the
persistence layer must include all entities (tables), attributes,
relationships (foreign and primary keys), cardinality, and
constraints (e.g. null/not-null) for the current development cycle
in order for the business logic to
compile and test against it.
The object-oriented (OO) architecture model is
a reflection of the problem domain in the solution domain, i.e. a
computer system. The virtual objects that reflect their
counterparts in the real-world contain state information that
cannot be lost when the computer system in which they live is
shutdown. This implies the need for data storage and introduces a
problem whose solution is always underestimated in terms of
difficulty, time, and effort. The problem is that OO-model and
the data model use fundamentally different technologies which must interact
and this need causes a major drain on development resources. This
technological barrier is often referred to as the "impedance mismatch"
problem -
a term borrowed from electrical engineering. To avoid the
distraction and cost of developing infrastructure to deal with
this problem the use of an
object-relational mapping framework and toolset such as TopLink
(an Oracle product) is highly recommend. In any case, it is
critical to have the data model
defined correctly both structurally and analytically at the start
of a new incremental release. Any major rework to the database scheme
(generated from the data model) will have a
profound impact and ripple effect on the object model and
delivery schedule!
Sub-system architecture model
This view of the architecture focuses on intra-subsystem and
inter-subsystem interfaces, visibility, dependency types, and
coupling mechanisms. Each object in a use-case scenario and each
activity in a process must be mapped to a specific component in a
given subsystem.
Subsystems should be loosely coupled to each other via clearly defined
interfaces. The logical partitioning of work and responsibilities
among subsystems allows each one to be developed and
tested in relative isolation.
The incremental/iterative development methodology enables
interfaces to be published early and to evolve in controlled
steps. An interface should only contain what is needed for the
current incremental release. In the inception phase most interfaces
and supporting classes will be skeletons and stubs, but
nevertheless these should be in a compilable state at the
code-level. Making
changes to a published subsystem interface from a previous
incremental release is a
serious matter. If this happens too often then a weakness exists in
the analysis and/or design review stages.
Analysis review
The analysis review is a manual walkthrough and inspection of the
analysis model. In the inspection part of the review, the
subsystem lead narrates (teaches) the logic behind each use-case,
interaction, and activity diagram to a group of reviews. The
reviewers listen to the author, raise questions and ask for
clarification in an attempt to uncover errors. In the walkthrough
part of the review, one or more reviewers play the role of
tester. These people come to the review armed with a set of test
cases to apply to the model, especially exceptional test cases
where things go wrong. All action items that are raised during
the review concerning errors, corrections, and improvements are
recorded in the change request and problem report tool.
The recommended size for a review group is four to five persons,
including the use-case team lead. The roles of the participants
(one person may have more than one role) and the tasks they
fulfill are: developer, moderator/coordinator, secretary/scribe,
standards bearer, maintenance expert and the user/customer
representative.
The goal of the review is to improve quality by
finding weaknesses or omissions in the analysis model. Only after all action items have
been appropriately resolved may the use-case team proceed to the
next stage in the development cycle. Reviewers should not use the
occasion to parade their technical prowess nor attack the
developer - professional courtesy is the recognized standard of
conduct.
To assist the review team in identifying incomplete, incorrect,
or inconsistent designs, a checklist should be provided to guide
the inspection and walkthrough. The inspection for a
check-and-balance between diagrams is only meaningful if the
solution space (for the current iteration) has been sufficiently
modeled. The review session proceeds from the use-case diagram to
a sequence diagram, to the class diagram, to state diagrams, etc,
and back again. The review process should follow the “strong
forces” between UML diagrams to maximize effectiveness.
UML diagram relationships
- A class diagram uses relationships to show permitted
message paths for sequence diagrams.
- A class diagram shows methods that are the transitions on
the state diagram.
- A component diagram (a physical analog of a class diagram)
shows the dependencies on classes in the class diagram.
- An activity diagram focuses on the flow of activities
involved in a single process by combining the paths from
multiple sequence diagrams.
- A sequence diagram includes a set of messages between
two objects, which must be in the same order as a valid set
of transitions in the state-chart diagram.
- A sequence diagram illustrates the instantiation of a
use-case scenario from the use-case diagram.
- A deployment diagram contains nodes that are dependent
on components in the component diagram.
UML diagram checklist
- Are all associations that are shown with no navigation information
truly bidirectional?
- Do all associations specify their multiplicity constraints?
- Do the standard and composite aggregation associations
correctly reflect the requirements?
- Is every sequence-diagram a subset of some activity diagram?
- Does every message sent in an interaction diagram appear as
a method in the public interface of the class of the receiving object?
- Is a transition-out state in the state-machine diagram
mutually exclusive?
- Do all state machines contain initial and final states?
- Are all messages shown correctly as synchronous or asynchronous?
- Do the number of forks and joins balance in every activity diagram?
Refined architecture model
In this model all the actors, objects, messages, and data types
required to validate a use-case scenario have been identified and
appear where required in various static and dynamic UML diagrams.
All classes have been assigned to components, and all activity
diagrams needed to describe a use-case scenario are complete. For
example, an object that appears in a sequence diagram maps to
a class located in a package of a subsystem. The messages
passed between objects may be either simple text descriptions to
serve as placeholders for the next release or implemented method
signatures developed in the current or a previous iteration.
The
refined architecture model contains many UML elements which map
to classes and class members and therefore represents the
transition from analysis and design to implementation. The
use-case, design, implementation, process, and deployment views
of the architecture are elaborated in sufficient detail to allow
for a complete design review.
Detailed architecture model
At this iteration stage in the workflow, the architecture must be complete
in the sense that all classes, messages,
data members, and infrastructure mechanisms corresponding to
model artifacts exist as valid programming constructs.
The bodies behind the method interface specifications
new to this iteration may however be stubbed-out.
In order for clients of
objects with new interfaces to compile and execute, the bodies
behind the stubbed-out methods must reply to a request with "mock objects" and/or perform “work” using (temporary)
hard-coded values. These a priori values can be fetched from a collection
pool
of valid results. Any clients of an object whose interface is new
or which has been extended, must be able to compile and execute against
the new interface without concern that the body behind the method
is a stub.
Test plans
Test plans specify what will be tested, how it will be tested,
and also identify all associated requirements.
They explain how to exercise inter-class collaboration in a
component, inter-component collaboration in a subsystem, and
inter-subsystem collaboration within and between layers.
Functional testing begins at the granularity of individual class
methods (unit tests) and progresses outwards towards abstract methods associated with
categories of classes contained within components. For each class method there
must be a corresponding test
case description (JavaDoc) embedded in the corresponding unit
test.
Tests that directly exercise the methods of a class are
called white-box tests because they use knowledge of the internal
code structure. Tests performed without knowledge of
the internal workings of the code are called black-box tests.
Whereas white-box tests use knowledge of how the “target of the
test” processes the request, black-box tests rely upon the output
as a function of input (transfer functions) to evaluate the
outcome.
There are several other test-axes to consider as part of the
overall test strategy. Namely: installation, multi-user,
operational, performance, robustness, load, stress, stability, integrity, usability, security, and configuration.
Descriptions of these tests are part of the integration and
deployment test
plan.
Each test in a software test plan must identify the
associated requirements, the segment level, and the category. The
segment that a test exercises is identified as: System (SYS),
Layer (LYR), Subsystem (SUB), or Unit (UNT). Category examples
are: Configuration, Reporting, Import/Export, User interface, and
Startup/Shutdown.
Functional tests at the class-level are documented in the unit-test code.
Tools which are a standard part of most integrated development
environments are then able to extracted this information into
hyperlinked documentation viewable in a browser. The test plan
documentation must be linked to the requirements with a tool to
ensure consistency and sufficient coverage along each test axis.
Test-case drivers
Collections of test-case drivers are a valuable extension to a
software application. A test-case
driver must exist for every (non-trivial) method in the target
class. For every class named ClassName there shall exist a class
named ClassName_Test that contains a set of test
drivers. The target and it's test classes are to be maintained as
a single unit. An inspection (manual or automated) of a
component will quickly reveal if the corresponding unit tests are
available or not.
For every subsystem named subsystemName a class shall
exist named subsystemName_Test. This
class serves as a focal point for collecting and running all test
suites located at lower levels in the abstraction hierarchy.
In an ideal project, the interface specifications
are so well defined that test drivers can be designed and written
for methods that do not yet exist. With unit tests already in
place, the responsibility of the developer is then to implement
the body of the target class until all unit tests pass with 100%
success. This is referred to as test-driven development.
A regression test must never be left in a state that reports
errors or warnings. Correcting the source of the error should always
has the highest priority!
Implemented architecture model
The objective at this stage in the workflow is to
implement the bodies of all methods in all classes that are stubbed out or incomplete
such that all component, subsystem and system tests report
no errors and no warnings.
Although most of the difficult work
has already been done in the analysis and design phases, things
can still go wrong during implementation if professional
programming standards and best practices are not followed. An implemented architecture
model that has passed all tests represents the solution space.
Code and test review
The code and test review, which should definitely include
automated tools, is focused on implementation issues such as programming
practices, conformance with naming conventions, reuse, patterns, efficient use of computing resources, maintainability,
extendibility, robustness, testability, and comprehension. A code
and test review is said to have passed if each of the above
mentioned criteria
is given a passing grade. The definition of a passing grade
is a subjective measure that the review team must determine among
themselves.
Subsystem synchronization
Before system & integration testing can proceed, all subsystems -
previously tested in relative isolation - must be built using the
same context. The iteration plan that allocates resources for each
release must be organized to allow different development teams to
converge at the synchronization point at more or less the same
time, i.e. within a day or two.
Tests along all axes
Before we can enter the solution space, all tests along all
axes must pass according to the criteria specified in the
integration/deployment test plan. If a test along any of the test axes
should fail, then we must return to the implementation model of
the architecture to find and correct the problem. In rare cases we may need to iterate
back to the design view.
Solution space
The completion of all activities in the workflow graph
results in an incremental release which is a successful
deployment of a mini-project.
Initially the architecture model is only a skeleton and a crude
approximation of the final system, but from increment to
increment the model eventually evolves into the completed form.
The operative word here is, "evolves". By avoiding
big-bang development, we minimize unpleasant surprises during
integration testing.
Each time the solution space is entered the software is either in
an alpha or a beta release state. A beta release represents a software
milestone with
enough functionality and stability to be useful to the customer;
it may be deployed for field trial purposes. Alpha releases
represent incremental releases between beta milestone; these
should never enter the field.
Version numbers should be of the form aa.bbb.cc. The generation
number is represented by aa. The build number is represented by
bbb; stable releases use even-numbers and development releases
use odd-numbers. The number of working days required to produce an
incremental release is indicated by cc. For example, before production of the first generation of an application the
following version numbers are possible:
00.007.25 (generation 0, build #007, 25 working days) Development
release
00.009.20 (generation 0, build #009, 20 working days) Development
release
00.010.23 (generation 0, build #010, 23 working days) Stable
release
Customer feedback form
This form is used to establish closure for the current release
and serves as a legal document for contractual agreement
purposes. Payment for services rendered often accompanies the
successful delivery of an incremental release. The signed
document indicates that the customer, or a representative of the
customer, is satisfied with the state
of the software. The form
should fit on a single sheet of A4 paper. It indicates
that the current state of the software has been shown to meet all
the established requirements up to an including the last
incremental release.
There should be no rational reason why the customer is not prepared to sign the form since the release
was built and delivered to meet the requirements and acceptance
criteria agreed to at the start of release development. If however
differences between the developer and the customer cannot be resolved, then in the worst possible case,
the project will have only lost a single iteration cycle or
approximately a five-week investment. Compare this to the
rejected delivery of a software system after one year in
development.
Risk assessment report
At the end of an iteration cycle much has been discovered and
learnt about the system during development. With that knowledge
the development team gains an improved ability to identify
potential barriers to success in the next
iteration. A key objective of this development process is to
identify and confront risks as early as possible. If a risk were
stated in the form, "X may not work" then we must make a plan to
try “X” as soon as possible. Each potential risk must be
described, assessed, ranked, and entered into a tracking tool with a red flag where it cannot escape attention. Risk
assessment feedback is used by project management to identify the
next set of highest-risk use-cases to implement from the
remaining set of use-cases. The risk assessment report is a
primary source of input for making course corrections to the
project plan.
Quality assurance report
The quality assurance report provides an objective and unbiased
measure of the quality of the released software. There are
several quality metrics that one can measure and several ways to
audit software and therefore, it is important not to overwhelm
the reader with too much information. You must decide in advance
what shall be measured and reported. One useful measure is the
defect discovery rate of accumulated bugs discovered in a
subsystem and/or a component at the end of each incremental
release. When this information is plotted as the number of
defects versus incremental release over the development lifecycle
from inception to transition, a bell curve should result with a
peak in the middle of the construction phase. Another measure
worth noting is the defect density (number of defects per
thousand source lines of code) for each unit in a subsystem. Both runtime and static analysis
metrics must be reported.