Coding and Testing - Part010
Coding and Testing - Part010
1
CODING AND TESTING – Part010
This module tackles the about software reliability and quality management.
Course Module
Coding
Coding
The input to the coding phase is the design document produced at the end
of the design phase.
The detailed design is usually documented in the form of module
specifications where the data structures and algorithms for each module
are specified.
Code Review
Testing is an effective defect removal mechanism. However, testing is
applicable to only executable code.
Review is a very effective technique to remove defects from source code.
In fact, review has been acknowledged to be more cost-effective in
removing defects as compared to testing.
Code Walkthrough
Code walkthrough is an informal code analysis technique.
Course Module
A module is taken up for review after the module has been coded,
successfylly compiled, and all syntax errors have been eliminated.
A few members of the development team are given the code a couple of
days before the walkthough meeting.
Each member selects some test cases and simulates execution of the code
by hand.
The main objective of code walkthrough is to discover the algorithmic
and logical errors in the code.
The members note down their findings of their walkthrough and discuss
those in a walkthrough meeting where the coder of the module is present.
Code Inspection
The code is examined for the presence of some common programming
errors.
This is in contrast to the hand simulation of code execution carried out
during code walkthrough.
The principal aim of code inspection is to check for the presence of some
common types of errors that usually creep into code due to programmer
mistakes and oversights and to check whether coding standards have
been adhered to.
The inspection process has several beneficial side effects, other than
finding errors.
Software Documentation
When a software is developed, in addition to the executable files and the
source code, several kinds of documents such as user’ manual, software
requriements specification (SRS) document, design document, test
document, installation manual, etc., are developed as part of the software
engineering process.
All these documents are considered a vital part of any good software
development practice.
Software Engineering
5
CODING AND TESTING – Part010
Internal Documentation
The code comprehension features provided in the source code itself.It can
be provided in the code in several forms.The important types of internal
documentation are the following:
Comments embedded in the source code.
Use of meaningful variable names.
Module and function headers.
Code indentation.
Code structuring.
Use of enumerated types.
Use of constant identifiers.
Use of user-defined data types.
Careful experiments suggest that out of all types of internal
documentation, meaningful variable names is most useful while trying to
understand a piece of code.
External Documentation
Is provided through various types of supporting documents such as users’
manual, sofware requirements specification document, design document,
test document, etc.A systematic software development style ensures that
all these documents are of good quality and are produced in an orderly
fashion.An important feature that is required of any good external
documentation is consistency with the code.If the different documents
are not consistent, a lot of confusion is created for somebody trying to
understand the software.All the documents developed for a product
should be up-to-date and every change made to the code should be
reflected in the relevant external documents.Even if only a few
documents are not up-to-date, they create inconsistency and lead to
confusion.Another important feature required for external documents is
proper understandability by the category of users for whom the
document is designed. For achieving this, Gunning’s fog index is very
useful.
Course Module
can be computed as follows: D = 0.4 x (words / sentences ) + per cent of
words having 3 or more syllables.Observe that the fox index is computed
as the sum of two different factors.
The first factor computes that average number of words per sentence.
This factor therefore accounts for the common observation that long
sentences are difficult to understand.
The second factor measures the percentage of complex words in the
document.
Note that a syllable is a group of words that can be independently
pronounced.
Words having more than three syllables are complex words and presence
of many such words hamper readability of a document.
If a users’ manual is to be designed for use by factory workers whose
educational qualification is class 8, then the document should be written
such that the Gunning’s fog index of the document does not exceed 8.
Testing
The aim of program testing is to help realiseidentify all defects in a
program. However, in practice, even after saisfactorycomlpetion of the
testing phase, it is not possible to guarantee that a program is error free.
This is because the input data domain of most programs is very large, and
it is not practical to test the program exhaustively with respect to each
value that the input can assume.
Consider a function taking a floating point number as argument. If a tester
takes 1 sec to type in a value, then even a million testers would not be
able to exhaustively test it after trying for a million number of years. Even
with this obvious limitation of the testing process, we should not
underestimate the importance of testing.Careful testing can expose a
large percentage of the defects existing in a program, and therefore
aprovides a practical way of reducing defects in a system.Testing
program involves executing the program with a set of test inputs and
observing if the program behaves as expected.If the program fails to
behave as expected, then the input data and the conditions under which it
fails are noted for later debugging and error correction.The tester who
inputs several test data to the system and observes the outputs produced
by it to check if the system fails on some specific inputs.Unless the
conditions under which a software fails are noted down, it becomes
difficult for the developers to reproduce a failure observed by the testers.
Course Module
System testing can be considered as validation step where it is
determined whether the fully developed code is as per its requirements
specification.
The primary objective of the verification steps are to determine whether
the steps in product development are being carried out alright, whereas
validation is carried out towards the end of the development process to
determine whether the right products has been developed.
Testing Activities
Test suite design: The set of test cases using which a program is to be
tested is designed possibly using several test case design techniques.
Running test cases and checking the results to detect failures: Each test
case is run and the results are compard with the expected results. A
mismatch between the actual result and expected results indicates a
failure. The test cases for which the system fails are noted down for later
debugging.
Locate error: The failure symptoms are analysed to locate the rrors. For
each failure observed during the previous activity, the statements that are
in error are identified.
Error correction: After the error is located during debugging, the code is
appropriately changed to correct the error.
When test cases are designed based on random input data, many of the
test cases do not contribute to the significace of the test suite. That is,
they do not help detect any additional defects not already being detected
by other test cases in the suite.
Testing a software using a large collection of randomly selected test cases
does not guarantee that all of the errors in the system will be uncovered.
A minimal test suite is a carefully designed set of test cases such that each
test case helps detect different errors. This is in contrast to testing using
some random input values.
There are essentially two main approaches to systematically design test
cases:
Black-box approach
White-box (or glass-box) approach
After testing all the units individually, the units are slowly integrated and
tested after each step of integration. Finally, the fully integrated system is
tested. Integration and system testing are known as testing in the large.
Unit testing
Unit testing is undertaken after a module has been coded and reviewed.
This activity is typically understaken by the coder of the module himself
in the coding phase.
Before carrying out unit testing, the unit test cases have to be designed
and the test environment for the unit under test has to be developed.
In order to test a single module, we need a complete environment to
provide all relevant code that is necessary for execution of the module.
Besides the module under test, the following are needed to test the
module:
The procedures belonging to other modules that the module under test
calls.
Non-local data structures that the module accesses.
A procedure to call the functions of the module under test with
appropriate parameters.
Stub: A stub procedure is a dummy procedure that has the same I/O
arameters as the function called by the unit under test but a highly
simplified behaviour.
Driver: A driver module should contain the non-local data structures
accessed by the module under test. Additionally, it should also have the
code to call the different functions of the unit under test with appropriate
parameter values for testing.
Black-Box Testing
Test cases are designed from an examination of the input/output values
only and no knowledge of design or code is required.
The following approaches available to design black box test cases:
Equivalence class partitioning
Boundary value analysis
White-Box Testing
White-box testing is an important type of unit testing.
A large number of white-box testing strategist exist.
Each testing strategy essentially designs test cases based on analysis of
some aspect of source code and is based on some heuristic.
Fault-based testing
Targets to detect certain types of faults.These faults that a test strategy
focuses on constitutes that fault model of the strategy.
Coverage-based testing
Attempts strategy attempts to execute certain elements of a program.
Popular examples of coverage-based testing strategies are statement
coverage, branch coverage, multiple condition converage, and path
coverage-based testing.
Branch Coverage
A test suite satisfies branch coverage, if it makes each branch condition in
the program to assume true and false values in turn.
For branch coverage each branch in the CFG representation of the
program must be taken at least once, when test suite is executed.
Branch testing is also known as edge testing, since in this testing scheme,
each edge of a program’s control flow graph is traversed at least once.
Course Module
Multiple Condition Coverage
Test cases are designed to make each component of a composite
conditional expression to assume both true and false values.
Branch testing can be considered to be a simplistic condition testing
strategy where only the compound conditions appearing in the different
branch statements are made to asume the true and false values.
It is easy to prove that condition testing is a stronger testing strategy than
branch testing.
Path Coverage
A test suite achieves path coverage if it executes each linearly
independent paths at least once.
A linearly independent path can be defined in terms of the control flow
graph of a program. Therefore, to understand path coverage-based
testing strategy, we need to first understand how the CFG of a program
can be drawn.
Course Module
It is therefore impractical to require the test designers to identify all the
linearly independent paths in a code, and then design the test cases to
force execution along each of the identified paths.
References
Rajib, Mall., et al., (2014). Fundamentals of Software Engineering. Fourth Edition
Course Module