Add daily email for 2024-02-16
Keep logic within tests for as long as you can
This commit is contained in:
parent
f6ca30c61e
commit
0d9bb37503
69
source/_daily_emails/2024-02-16.md
Normal file
69
source/_daily_emails/2024-02-16.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: Keep logic within tests for as long as you can
|
||||
date: 2024-02-16
|
||||
permalink: archive/2024/02/16/keep-logic-within-tests-for-as-long-as-you-can
|
||||
snippet: |
|
||||
Making the easy change to get a test to pass might mean you write more logic in your tests than you expect, at least to begin with.
|
||||
tags:
|
||||
- software-development
|
||||
- automated-testing
|
||||
- test-driven-development
|
||||
- drupal
|
||||
- php
|
||||
- phpunit
|
||||
---
|
||||
|
||||
Inspired by some recent podcast guests, I've started writing the first code for a Drupal-based SaaS product that I've been thinking of creating.
|
||||
|
||||
Here's an early iteration of the first test I wrote:
|
||||
|
||||
```language-php
|
||||
public function test_it_creates_a_project_node_from_json(): void {
|
||||
self::assertNull(Node::load(id: 1));
|
||||
|
||||
$this->installEntitySchema(entity_type_id: 'node');
|
||||
$this->installConfig(modules: self::$modules);
|
||||
|
||||
$projectData = json_decode(json: self::$projectJson, associative: TRUE);
|
||||
self::assertNotNull($projectData);
|
||||
|
||||
Node::create([
|
||||
'title' => $projectData['list'][0]['title'],
|
||||
'type' => 'drupal_project',
|
||||
])->save();
|
||||
|
||||
$node = Node::load(id: 1);
|
||||
|
||||
self::assertNotNull($node);
|
||||
self::assertInstanceOf(actual: $node, expected: NodeInterface::class);
|
||||
self::assertSame(actual: $node->label(), expected: 'Override Node Options');
|
||||
|
||||
self::assertSame(
|
||||
actual: $node->get('field_drupalorg_node_id')->getString(),
|
||||
expected: strval(107871),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
It checks that, given some defined JSON data, it will create a node in my database.
|
||||
|
||||
It confirms no node ID exists when starting, runs some setup setups (this is a Kernel test), decodes the JSON, creates the node and asserts it contains the expected values.
|
||||
|
||||
There are two things that you may be wondering...
|
||||
|
||||
* Why do you have test setup code that you'll need within the test? Won't you need that for every test?
|
||||
* Why are you creating the node within the test and not somewhere else?
|
||||
|
||||
The answer to both is that this is the first test, and I want to write **as little code as possible for it to pass**.
|
||||
|
||||
When I write the second test, I'll either need to duplicate the setup lines or extract them to a `setUp()` method.
|
||||
|
||||
I'll also need to refactor the code that creates the node.
|
||||
|
||||
Once I've written the second test, to get it to pass, I refactored to use Repository, Builder and Action classes.
|
||||
|
||||
If there's a regression, the test I had will fail, and I could revert to the passing version before reattempting the refactor.
|
||||
|
||||
With test-driven development, I want to work in small and simple steps and get to green by making the smallest and easiest possible change.
|
||||
|
||||
When I have a test that forces me to refactor and adopt a more complex approach, I'll do it.
|
Loading…
Reference in a new issue