Integrating Testing Into Development: Bdd And Living Documentation

Writing Testable Code from the Start

Following test-driven development (TDD) principles allows developers to write highly modular, less coupled code that lends itself to testability. The key aspects of TDD involve writing failing tests first before incrementally writing implementation code to pass each test. This enforces a cycle of red-green testing that builds program logic in small, testable units.

A major benefit of TDD is the ability to mock and stub out dependencies, making tests fast, isolated, and focused on one class or method at a time. Using mocks, stubs, and test doubles replaces real dependencies with simulated stand-ins that help verify inputs and outputs without relying on the actual dependencies.

Guidelines for Testable Code

  • Modular architecture with separation of concerns
  • Loose coupling between classes and components
  • Avoidance of static methods and seeded singletons
  • Heavy use of interfaces and dependency injection
  • Frequent use of pure, stateless methods without side effects

Following these guidelines will create code that lends itself to testability through isolation, behavior verification, and controlled input/output validation.

Introducing Behavior-Driven Development

Behavior-Driven Development (BDD) expands upon TDD by emphasizing verification of software behavior and business value. BDD aims to create a shared understanding of system behavior between technical and non-technical stakeholders using a format understandable by all.

Gherkin Syntax

BDD commonly relies on Gherkin, a set of grammar rules in a Domain Specific Language designed to describe software behavior without detail about implementation. Gherkin provides plain language constructs including:

  • Feature: High-level business need
  • Scenario: Specific example of using a feature
  • Given/When/Then: Setup, action, and outcome steps
  • And/But: Extend steps

Sample BDD Feature File

Feature: User account registration
  As a user 
  I want to register for an account
  So I can access personalized application content

  Scenario: Happy path registration
    Given I am on the registration page 
     When I enter my details into the form
      And I submit the registration form  
     Then I should have a personalized account

  Scenario: Duplicate email 
     Given I enter an email that is already registered 
     When I submit the registration form
     Then I should see an error that email is already used

Feature files written in Gherkin provide executable specifications readable by business and technical team members for validation against application behavior.

Automated Acceptance Testing

Acceptance testing verifies that software meets agreed-upon requirements and desired behavior as expected by end users and stakeholders. Automating these user-focused black-box tests according to specified acceptance criteria brings numerous benefits.

Benefits of Automated Acceptance Testing

  • Validate new features and functionality work per specs
  • Catch defects and regressions earlier in lifecycles
  • Cover critical happy paths and edge cases
  • Support continuous integration and iterative development
  • Improve feedback between dev, QA, and product teams

Effective test automation relies on layered test pyramids consisting of API, integration, and UI tests targeting riskier paths.

Living Documentation

Living documentation treats required documentation such as specs, architecturedecision records (ADRs), and runbooks as continuously updated source code rather than static documents. The goals of living documentation align with agile methodologies by enabling fluid documentation that evolves alongside code.

Benefits of Living Documentation

  • Keeps documentation accurately reflecting source code
  • Reduces outdated stale documentation tech debt
  • Surfaces gaps between documented behavior vs implementation
  • Encourages developer contributions to documentation

BDD feature files provide an ideal form of executable living documentation accessible to all stakeholders as a single source of truth regarding software capabilities and business value.

Continuous Integration and Delivery

Continuous integration (CI) provides a development practice where developers frequently merge code changes into a shared repository triggering automated builds and tests. Continuous delivery (CD) takes this further by automating release processes to push software changes into staging and production environments once CI builds pass tests.

Linking Deployments to Successful Automated Testing

  • Run full automated test suites on every code change to detect issues early
  • Block deployments to staging or production when any tests fail
  • Support rapid development by fast feedback on merge conflicts or failures
  • Ensure confidence releases contain only passing, validated code changes

This safety net allows teams to confidently release incremental changes frequently and sustainably while preventing broken builds from impacting users.

Leave a Reply

Your email address will not be published. Required fields are marked *