Celebrating 30 Years of Delphi With a New Book: Delphi Quality-Driven Development

This year, on February 14th, Delphi celebrates its 30th birthday. Over the past three decades, Delphi has proven to be a robust and versatile development environment, empowering developers to build high-performance applications with ease across multiple platforms: Windows, Linux, Android, iOS, and macOS. 

As we commemorate this milestone, I am also introducing a new book to help guide you into Delphi's fourth decade: Delphi Quality-Driven Development. Useful to lone developers and vast teams alike, this book aims to demonstrate a variety of essential practices and techniques for making high-quality, testable code.

There is a 25% sale going on until the end of February for the Delphi Quality-Driven Development ebook, and there you can also get an additional discount on other books if you add them to your order.

To all my fellow Delphi developers: May your code compile quickly, your memory be manageable, and your code testable.

 

Delphi Quality-Driven Development Book

A practical guide to testing and writing testable code 




Software development is a complex and continuous process. The quality of the end result—the actual software—depends on many variables. Regardless of the size of the team, be it a solo developer, or a team with tens, hundreds, or even thousands of people involved, we cannot always fully control all the aspects of the software development process.

However, we can bring some order into the chaos, and by using well-established and proven practices, we can increase the quality of the software we are producing, and with that, increase customer satisfaction, ultimately improving the success of the software product.

There are always other factors that determine the success (viability) of the software, but a bug-ridden product is never going to be a successful one, unless users are forced to use it for reasons beyond their control.

When it comes to reducing the number of current and future bugs and other quality issues in the software, there is one thing in particular that can and will do more for improving software quality than all the others combined: automated testing.

In that light, the main title of this book could have easily been its subtitle alone: A practical guide to testing and writing testable code. However, the ability to test software requires way more than the mere act of testing or writing testable code, and covering only those two aspects would fail to address other significant factors that contribute not only to the overall quality of the produced software, but also our ability to successfully write and test its code.

While topics surrounding testing and writing testable code do comprise the most significant part of this book, all other parts of the development process that also contribute to the software quality are covered, to give a better understanding of their roles and impact in the whole process. From planning and designing, through development and testing, to deployment.

Besides that, every developer wants to produce high-quality and successful software, while not all of them are very fond of testing. Focusing on testing alone, which many of the testing-related books do, means losing some of the potential audience. What is worse, you lose those that would benefit from it the most.

Testing, you say. I don't have time for this. I have deadlines to meet.

Focusing on the end goal, producing high-quality software, instead of the journey and specific methodology, also allows us to adapt and change the process as we go, instead of sticking to some practice that is not fully applicable to a particular situation.

In our search for successful practices that will help us in doing our job better and faster, we tend to forget why we are using them. All those good practices don't exist in a void for their own sake: They evolved through our collective knowledge, being adapted, tweaked, and polished until they emerged under some name, to be more easily recognizable and approachable.

But in that effort to categorize and simplify the message we are sending to new generations of developers, we often fail to explain its origins and real purpose, passing only half of the knowledge until it degenerates into something that causes more harm than good. And then old practices are quickly abandoned without realizing the reasons for their failure, and new practices emerge, only to fail soon enough.

This is another reason for choosing the title Quality-Driven Development: it can be whatever you need it to be. It is a timeless reminder of your goals, insisting on practical know-how, instead of following and sticking with very specific, rigidly formed processes. And while you will still need to use at least some of those established practices to achieve your goals, you can more freely adapt them to serve you, rather than the other way around.

Larger companies and teams are more likely to use automated testing and other processes that contribute to software quality. Small teams and single developers, not so much. The need to ship a product on time, combined with a lack of resources to follow all the necessary steps to produce high-quality software, is always a great incentive to cut corners. Of course, larger teams are no strangers to cutting corners either, and this book is intended for all of the above, as its goal is not only to teach how to do something and how to apply a certain process, but also why all those pesky, time-consuming tasks are actually saving time and not wasting it.


 

Table of Contents:

Introduction

Part 1. Software Development Process

* Quality Factors

* Software Development Cycle

* Work Smarter, Not Harder

* Don’t Let Rules Rule

* Use the Source, Luke!

   + Version Control Systems and Terminology
   + Git, GitHub... I don’t git it

* Working With Git

   + Creating a Repository
     - .gitattributes configuration file
     - .gitignore configuration file
     - Adding files and committing changes
   + Branching and Merging
     - Single branch
     - Trunk-based development (GitHub flow)
     - Git flow
     - Master-Develop-Feature
     - Merge vs Rebase
     - Resolving and avoiding merge conflicts

* Issue Tracking Systems

Part 2. Documentation, Planning, and Design

* Software Project Documentation

   + Minimum Viable Product and Future Extensions

* Start, Planning, and Design

   + Concept Document - White Paper
   + Software Requirements Specification
   + Software Design Document

* Source Code and API Documentation

* Testing Documentation

   + Test Case
   + Test Case Scenario
   + Test Case Document

Part 3. Introduction to Testing

* Development and Testing

   + Test Early
   + Manual Testing
   + Unit Testing
   + Integration Testing
   + System Testing
   + Acceptance Testing

* Introduction to Unit Testing

   + Manual Testing
   + Unit Testing 
   + DUnit Template Wizard
   + DUnit Test Workflow
   + Writing and Running Simple Tests
   + Extending the Test Suite 
   + Testing Corner Cases
   + Testing Exceptions 
   + Testing the Destruction Process 
   + DUnit Validation Methods 

* Testing with DUnitX

   + DUnitX Validation Methods
   + Running DUnitX in GUI  
   + DUnit vs DUnitX
   + Migrating from DUnit to DUnitX

* DUnit Extensions

* TestInsight

* Unit Testing Principles

   + Test Repeatability 
   + Speed  
   + Code Paths and Functionality Coverage
   + Testing Implementation Details 
   + Testing in Isolation 
   + Single Test Case per Unit Test
   + Test Granularity   

* Test Doubles

   + Dummy Test Double
   + Fake Test Double
   + Stub Test Double
   + Spy Test Double 
   + Mock Test Double

* Test-Driven Development - TDD

  + Red-Green-Refactor Steps 
  + Refactoring
    - Internal refactoring
    - External refactoring
   + Speeding Up the TDD Process
   + Follow TDD or Not?
   + False Expectations

* Think Before You Code

Part 4. Test Cases

* Test Cases

* Testing Methodologies

   + Black-Box Testing Methodologies 
   + White-Box Testing Methodologies 

* Black-Box Testing

   + Equivalence Partitioning & Boundary Value Analysis 
   + Decision Tables
   + Cause–effect Graph
   + State Transition Testing
   + Classification Trees

* White-Box Testing

   + Static Code Analysis 
   + Control Flow Graph
   + Statement Coverage
   + Branch (Decision) Coverage
   + Path Coverage
   + Basic and Multiple Condition Coverage 
   + Function Coverage 
   + Loop Testing 
   + Data Flow Testing

* White-Box Metrics

   + Cyclomatic Complexity Metric
   + Rapps-Weyuker Metrics

* Code Coverage Tools

* Test Data & Scenarios

   + Valid Data or Scenario 
   + Invalid Data or Scenario
   + Special-Context Values 
   + Boundaries & Data Around Boundaries 
   + Booleans 
   + Enumerated Types 
   + Integer Numbers 
   + Floating-Point Numbers
   + Fixed-Point Numbers 
   + Date and Time 
   + Pointers, Objects, and Interfaces 
   + Procedural Types
   + Records
   + Arrays and Buffers
   + Characters and Strings 
     - Specifications 
     - Choosing the best string type 
     - Indexed string access 
     - Character buffers allocation 
   + Collections and Sets  
   + Variant Types 

Part 5. Development & Testing

* Writing Testable Code

* Never Say Never: Existing Code

* Global State

   + Minimizing Usage of Global State
   + Changing Global State
   + Wrapping Global State
     - Procedural Types
     - Singletons

* Dependencies & Decoupling

   + Dependencies
     - Heavyweight dependencies
     - Simple, commonly used classes
     - Dependency is an integral part of the system under test
     - Code performance and complexity 
     - Unit testing performance
     - Other considerations
   + Dependency Injection 
     - Constructor injection
     - Property or field injection
     - Method injection
     - Factory method 
     - Abstract factory
     - Dependency injection container
     - Metaclasses
   + Dependency Architecture 
     - Interfaces
     - Classes and metaclasses 
     - Adapter and facade patterns 

* Testing Generics

* Testing Multithreaded Code

   + Extract Unrelated Functionality
     - Thread and task termination
     - Communicating with GUI
   + Waiting for Threads or Tasks
   + Testing Thread Safety
   + Anonymous Methods

* Integration Testing

* Testing GUI

  + Extract Testable Code 
  + Add Abstraction Layers
  + Use Messaging Systems 

Part 6. Integration & Deployment

* Integration & Deployment

* Integration & Deployment Automation

   + Automation Tools 
   + Build
   + Test
   + Deliver & Deploy

Appendix

* References

Comments

Popular posts from this blog

Delphi 12.1 & New Quality Portal Released

Assigning result to a function from asynchronous code

Coming in Delphi 12: Disabled Floating-Point Exceptions