Methodology:
Behavior-Driven Development

Ready to get started?

Check out the plugin on GitHub and start using it today.

Behavior

Behavior-Driven Development — 01

Behavior

What the user sees

Behavior · Examples · Edge cases

Rule text ≤ 300 chars

Example Demo #WordPress

Edge case #123 → not a tag

↓ Click to read more

01 — Behavior

Describe what the user sees, not how the code works. Real case: 4WP Social posts to Bluesky, which allows 300 characters per post.

TEXT
// Bluesky post text — behavior
- Longer than 300 characters → cut, ends with "…"
- Tags become hashtags only while they fit
- #123 and a#b are not tags

02 — Examples

A rule becomes clear with a concrete example: real input, real output.

TEXT
description: 'Demo #WordPress'
tags:        ['WordPress', 'FAQ schema']

Bluesky text:
Demo #WordPress

#FAQschema

// #WordPress is already in the text — not added twice

03 — Edge cases

Edge cases are behavior too. Write them down before the code exists.

TEXT
295 chars + tag 'LongTag'  → no room, tag not added
400 chars                  → cut to 300, ends with "…"
'Issue #123 and a#b'       → no hashtags at all

Driven

Behavior-Driven Development — 02

Driven

Scenarios lead the work

Given · When · Then

Given description, tags

When build Bluesky text

Then "Demo #WordPress…"

↓ Click to read more

04 — Given / When / Then

One scenario, one behavior. The client, the developer and QA read the same words.

TEXT
Scenario: hashtags only while they fit
  Given description "Demo #WordPress"
    And tags "WordPress", "FAQ schema"
  When 4WP Social builds the Bluesky text
  Then the text is "Demo #WordPress\n\n#FAQschema"

05 — One language

The scenario name moves straight into the test name. The test name is the spec.

TEXT
// tests/unit/BlueskyTest.php — 4WP Social
"hashtags only while they fit"
  → test_text_adds_hashtags_only_while_they_fit()

"long text is cut to 300"
  → test_long_text_is_cut_to_300()

"numbers and URL fragments are not tags"
  → test_numbers_and_url_fragments_are_not_tags()

06 — It drives the AI

A scenario is the clearest prompt for a coding agent: the behavior is fixed, the implementation is up to the agent.

TEXT
Make BlueskyTest pass.
Do not change the scenarios.

// AI writes the code.
// The behavior stays yours.

Development

Behavior-Driven Development — 03

Development

Scenario → test → code

Test · Code · Green

Test BlueskyTest

Code Bluesky_Adapter::text()

Green OK (5 tests)

↓ Click to read more

07 — Scenario → Test

The scenario becomes a plain PHPUnit test. No Behat, no .feature files.

TEXT
public function test_text_adds_hashtags_only_while_they_fit(): void {
  $package = new Media_Package( array(
    'description' => 'Demo #WordPress',
    'tags'        => array( 'WordPress', 'FAQ schema' ),
  ) );
  $this->assertSame(
    "Demo #WordPress\n\n#FAQschema",
    Bluesky_Adapter::text( $package )
  );
}

08 — Test → Code

The code does what the scenario says, nothing more: add hashtags one by one, stop when the next one does not fit.

TEXT
$glue = "\n\n";
foreach ( $hashtags as $hashtag ) {
  $next = $text . $glue . $hashtag;
  if ( self::length( $next ) > self::TEXT_MAX ) {
    break;
  }
  $text = $next;
  $glue = ' ';
}

09 — Green

Run it after every change. The behavior is checked, not just the code written.

TEXT
$ vendor/bin/phpunit --filter BlueskyTest
PHPUnit 9.6.38

.....                     5 / 5 (100%)

OK (5 tests, 11 assertions)