uuid: - value: 066297b1-ab00-4769-afe1-d3831ed2a654 langcode: - value: en type: - target_id: daily_email target_type: node_type target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7 revision_timestamp: - value: '2025-05-11T09:00:12+00:00' revision_uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 revision_log: { } status: - value: true uid: - target_type: user target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 title: - value: 'Writing assertions first' created: - value: '2024-06-05T00:00:00+00:00' changed: - value: '2025-05-11T09:00:12+00:00' promote: - value: false sticky: - value: false default_langcode: - value: true revision_translation_affected: - value: true path: - alias: /daily/2024/06/05/writing-assertions-first langcode: en body: - value: |

As well as writing comments first, when writing tests, I sometimes like to write my tests backwards and start by writing the assertions first.

I know what I want to assert in the test, so it's an easy place to start.

I'll run it, see the error, fix it and continue working backwards.

For example, I could start with this:

public function testOnlyPostNodesAreShown(): void {
        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

This test will fail when I run it, but it makes me think about what I need to do to fix the error and how to do so in the best way.

In this case, I need to make a request to the page that should render the text:

public function testOnlyPostNodesAreShown(): void {
        $this->drupalGet('/blog');

        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

This will still fail, as I also need to create the required posts:

public function testOnlyPostNodesAreShown(): void {
        PostBuilder::create()->setTitle('Post one')->getPost();
        PostBuilder::create()->setTitle('Post two')->getPost();

        $this->createNode([
          'title' => 'This is not a post',
          'type' => 'page',
        ]);

        $this->drupalGet('/blog');

        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

Now the test passes.

Doing test-driven development keeps my code clean and minimal, and I find this approach keeps my test clean, too.

format: full_html processed: |

As well as writing comments first, when writing tests, I sometimes like to write my tests backwards and start by writing the assertions first.

I know what I want to assert in the test, so it's an easy place to start.

I'll run it, see the error, fix it and continue working backwards.

For example, I could start with this:

public function testOnlyPostNodesAreShown(): void {
        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

This test will fail when I run it, but it makes me think about what I need to do to fix the error and how to do so in the best way.

In this case, I need to make a request to the page that should render the text:

public function testOnlyPostNodesAreShown(): void {
        $this->drupalGet('/blog');

        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

This will still fail, as I also need to create the required posts:

public function testOnlyPostNodesAreShown(): void {
        PostBuilder::create()->setTitle('Post one')->getPost();
        PostBuilder::create()->setTitle('Post two')->getPost();

        $this->createNode([
          'title' => 'This is not a post',
          'type' => 'page',
        ]);

        $this->drupalGet('/blog');

        $assert = $this->assertSession();
        $assert->pageTextContains('Post one');
        $assert->pageTextContains('Post two');
        $assert->pageTextNotContains('This is not a post');
      }
      

Now the test passes.

Doing test-driven development keeps my code clean and minimal, and I find this approach keeps my test clean, too.

summary: null field_daily_email_cta: { }