Page 233 - DCAP305_PRINCIPLES_OF_SOFTWARE_ENGINEERING
P. 233
Unit 11: Coding Process
Improved Understanding of Required Software Behaviour: The level of requirements on a Notes
project varies greatly. Sometimes requirements are very through and other times they are
vague. Writing unit tests before writing the code helps developers focus on understanding the
required behaviour of the software. As writing a unit test, pass/fail criteria for the behaviour
of the software is being added. Each of these pass/fail criteria adds to the knowledge of how
the software must behave. As more unit tests are added because of new features or new bugs,
the set of unit tests come to represent a set of required behaviours of higher and higher fidelity.
Centralization of Knowledge: Humans all have a collective consciousness that stores ideas they
all have in common. Unfortunately, programming is mostly a solitary pursuit. Modules are
usually developed by a single individual, and a lot of the knowledge that went into designing
the module is usually stuck in the head of the person who wrote the code. Even if it is well
documented, clean code, it is sometimes hard to understand some of the design decisions that
went into building the code. With TDD, the unit tests constitute a repository that provides some
information about the design decisions that went into the design of the module. Together with
the source code, this provides two different points of view for the module. The unit tests provide
a list of requirements for the module. The source code provides the implementation of the
requirements. Using these two sources of information makes it a lot easier for other developers
to understand the module and make changes that would not introduce bugs.
Better Encapsulation and Modularity: Encapsulation and modularity help managing the chaos
of software development. Developers cannot think about all the factors of a software project
at one time. A good design will break up software into small, logical, manageable pieces with
well defined interfaces. This encapsulation allows developers concentrate on one thing at a time
as the application is built. The problem is that sometimes during the fog of development one
may stray from the ideas of encapsulation and introduce some unintended coupling between
classes. Unit tests can help detect unencapsulated a module. One of the principles of TDD says
that the unit tests should be easy to run. This means that the requirements needed to run any
of the unit tests should be minimized. Focusing on making testing easier will force a developer
making more modular classes that have fewer dependencies.
Simpler Class Relationships: A well designed piece of software will have well defined levels
that build upon each other and clearly defined interfaces between the levels. One of the results
of having software that has well defined levels is that it is easier to test. The corollary to this
is also true. If code is designed by writing tests, the focus will be very narrow, so the tests will
tend not to create complex class relationships. The resulting code will be in the form of small
building blocks that fit neatly together. If a unit test is hard to write, then this usually means
there is a problem in the design of the code. Code that is hard to test is usually bad code. Since
the creation of the unit tests help point out the bad code, this allows correcting the problem and
produce better designed, more modular code.
Reduced Design Complexity: Developers try to be forward looking and build flexibility into
software so that it can adapt to the ever-changing requirements and requests for new features.
Developers are always adding methods into classes just in case they may be needed. This
flexibility comes at the price of complexity. It is not that developers want to make the software
more complex, it is just that they feel that it is easier to add the extra code up front than make
changes later. Having a suite of unit tests allows to quickly tell if a change in code has unforeseen
consequences. This will give the developer the confidence to make more radical changes to
the software. In the TDD process, developers will constantly be refactoring code. Having the
confidence to make major code changes any time during the development cycle will prevent
developers from overbuilding the software and allow them to keep the design simple. The
approach to developing software using TDD also helps reduce software complexity. With TDD
the goal is only adding the code to satisfy the unit tests. This is usually called developing by
intention. Using TDD, it is hard to add extra code that is not needed. Since the unit tests are
LOVELY PROFESSIONAL UNIVERSITY 227