Software Engineering Quality Practices describes how software engineers and the managers that supervise them can develop quality software in an effective, efficient, and professional manner. This volume conveys practical advice quickly and clearly while avoiding the dogma that surrounds the software profession. It concentrates on what the real requirements of a system are, what constitutes an appropriate solution, and how you can ensure that the realized solution fulfills the desired qualities of relevant stakeholders. The book also discusses how successful organizations attract and keep people who are capable of building high-quality systems.
Review By: Ross Collard 11/10/2008Ronald K. Kandt has distilled a career's worth of insights and lessons learned into Software Engineering Quality Practices. This book is written for people charged with establishing, promoting, or maintaining effective software engineering practices for an organization at CMM Level 1 or 2, and--rightly or wrongly--who believe the organization’s survival or effectiveness lies in moving to the next CMM level.
If you are instead more into relatively new-fangled ideas, like agile methods and test-driven design, or you do not like process-driven approaches like CMM, this is probably not the best book for you.
The book presents approximately 200 quality practices for software development, maintenance, testing, documentation, etc. Most practices take the form of step-by-step procedures, guidelines, and checklists. Representative examples of the practices (using the author’s names for each practice) include:
Create a software engineering steering group
Obtain the commitment of participants
Define an orientation program for new personnel
Reward outstanding accomplishments
Control problem employees
Document identified software defects
Use good writing style
Verify that systems work in a variety of configurations
Clearly present information
While acknowledging their potential to be of value, I generally found the practices to be detached and bureaucratic. I can see them being used more by Human Resources departments than by software engineers. They could be useful for people who need to manage or work with software engineers, but who themselves do not have software engineering backgrounds.
I examined a handful of practices closely, and asked these four questions of each one:
1. Is the practice basically correct; does it provide good advice?
2. Is it useful?
3. Is it practical?
4. Can it be applied successfully by the less expert members of its target audience, i.e., by neophytes in software engineering such as managers who are brought in from other areas?
In the fourth question, I was especially interested in context dependency. Practices with names like "Develop a project plan" must be highly context-dependent: a generic "one size fits all" procedure could be dangerous.
I found that the practices were mostly acceptable and useful if you were not already familiar with them. For example, having a practice to "test the back-up process" may seem unnecessary because this practice should already exist. Yet many organizations have poor back-up practices, so I was thankful that it was included in the book.
However, there was not much direction about how to tune the practices to the context. Some practices I flatly disagree with, such as the one titled, "Test each basis path." This practice states that we need to test each "conditional predicate" in a module, without defining what a conditional predicate is. In my experience, testing all conditional predicates (e.g., all basis paths), is a weak, inefficient, and sometimes dangerous measure of test coverage. What about multiple loops in the code? These loops usually are not basis paths but often find important bugs. What about risk-based prioritization and selective testing of basis paths? Saying that all conditional predicates need to be tested, regardless of context, is too simplistic.
The attention that the book gives to various topics tells us a lot about its overall focus and message. The amount of space allocated to a topic is one indicator, examples are another.
In the book, approximately equal coverage (about six pages each) is provided for four approaches to quality software: extreme programming (xp), the Rational Unified Process (RUP), software cleanroom, and CMMI. Most authors tend to advocate either the relatively avant garde (xp and RUP) or the more traditional (CMMI and cleanroom), but not both. Presumably Mr. Kandt is trying to give a balanced perspective.
The following topics are not found in the book’s table of contents nor in its index: agile development, agile testing, test-driven development, basis path, branch, loop, boundary value, equivalence, finite state machine, class, thread, multi-threaded, refactoring, cyclomatic complexity or any type of complexity, mutex, and semaphore, to name just a few.
The book has virtually no specification, design, or code examples of effective or ineffective practices, and none that are language-specific (e.g., written in Java or C++). This book might not be helpful if you learn better through examples and exercises with worked-through suggested answers than by relatively abstract procedure descriptions.