diff --git a/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf b/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf
new file mode 100644
index 0000000..c6c4eaf
Binary files /dev/null and b/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf differ
diff --git a/tdd-test-driven-drupal/images/2c6qi8.jpg b/tdd-test-driven-drupal/images/2c6qi8.jpg
new file mode 100644
index 0000000..93bd9a9
Binary files /dev/null and b/tdd-test-driven-drupal/images/2c6qi8.jpg differ
diff --git a/tdd-test-driven-drupal/images/broadbean.png b/tdd-test-driven-drupal/images/broadbean.png
new file mode 100644
index 0000000..3aaf673
Binary files /dev/null and b/tdd-test-driven-drupal/images/broadbean.png differ
diff --git a/tdd-test-driven-drupal/images/matt-stauffer-tweet.png b/tdd-test-driven-drupal/images/matt-stauffer-tweet.png
new file mode 100644
index 0000000..3f27a45
Binary files /dev/null and b/tdd-test-driven-drupal/images/matt-stauffer-tweet.png differ
diff --git a/tdd-test-driven-drupal/images/tdd-loop.png b/tdd-test-driven-drupal/images/tdd-loop.png
new file mode 100644
index 0000000..ffd6078
Binary files /dev/null and b/tdd-test-driven-drupal/images/tdd-loop.png differ
diff --git a/tdd-test-driven-drupal/images/when-you-do-things-right.jpg b/tdd-test-driven-drupal/images/when-you-do-things-right.jpg
new file mode 100644
index 0000000..efe0ac4
Binary files /dev/null and b/tdd-test-driven-drupal/images/when-you-do-things-right.jpg differ
diff --git a/tdd-test-driven-drupal/slides.md b/tdd-test-driven-drupal/slides.md
index ab037ff..ff1be34 100644
--- a/tdd-test-driven-drupal/slides.md
+++ b/tdd-test-driven-drupal/slides.md
@@ -1,58 +1,102 @@
autoscale: true
build-lists: true
-theme: simple, 1
+footer-style: alignment(left)
+footer: @opdavies | oliverdavies.uk
+header-emphasis: #53B0EB
+header: alignment(left)
+text: alignment(left)
+text-emphasis: #53B0EB
+theme: poster, 8
+
+[.header: alignment(center)]

-# __TDD - Test Driven Drupal__
+# _TDD:_ Test
Driven Drupal
---
+[.background-color: #FFFFFF]
[.build-lists: false]
+[.header: #111111]
+[.text: #111111, alignment(left)]
-- PHP code
-- Mixture of D7 and D8
-- SimpleTest (D7)
-- PHPUnit (D8)
-
----
-
-[.build-lists: false]
+
+- Full stack Web Developer & System Administrator
- Senior Developer at Microserve
-- Contrib module maintainer
-- Occasional core contributor
-- Sticker collector and elePHPant herder
-- @opdavies
-- oliverdavies.uk
+- Part-time freelancer
+- Acquia certified Drupal 8 Grand Master
+- Drupal 7 & 8 core contributor
+- opdavies (Drupal.org, GitHub, Twitter)
+- www.oliverdavies.uk
-
+^ Work at Microserve.
+Maintain Drupal modules, PHP CLI tools and libraries
+Blog on my website
---
-## I write and release contrib modules for the community.
-## I write custom modules for client projects.
+[.header: alignment(center)]
+
+## test_driven_drupal_.com_
---
-
+[.header: alignment(center)]
-
-^ First experience of testing with a real module.
-Used on 11,046 sites (84 D5, 7,094 D6, 3,868 D7).
-Currently used on 28,398 (10 D5, 2,207 D6, 23,206 D7, 2,975 D8).
-Tests crucial to preventing regressions when adding new features or fixing bugs.
+## Why?
+## _What?_
+## How?
---
-## __Why Test?__
+[.header: alignment(center)]
+
+## I write _contrib modules_ for the community
+
+---
+
+[.header: alignment(center)]
+
+## I write _custom modules_ for client projects
+
+---
+
+[.background-color: #FFFFFF]
+
+
+
+---
+
+## _Override Node Options_
+
+- Become maintainer in 2012
+- Had some existing tests
+- First experience of testing with a real module
+- Used on _11,046 sites_ in October 2012 (_84_ D5, _7,094_ D6, _3,868_ D7)
+- Used on _29,023 sites_ in June 2018 (_9_ D5, _1,853_ D6, _23,602_ D7, _3,559_ D8)
+- Crucial to preventing regressions when adding new features or fixing bugs
+- Ensured consistency when porting to Drupal 8
+
+^ Preventing regressions in my additions but also user submitted patches
+
+---
+
+[.header: alignment(center)]
+
+## _Why_ write tests?
+
+---
+
+## _Why write tests?_
- Catch bugs earlier
- Piece of mind
- Prevent regressions
- Write less code
- Documentation
-- Drupal core requirement -
+- Drupal core requirement - __
- More important with regular D8 releases
^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst developing rather than after it's been released)
@@ -61,7 +105,7 @@ ONO merge conflict
---
-## __Core Testing Gate__
+## _Core Testing Gate_
New features should be accompanied by automated tests.
@@ -73,278 +117,522 @@ Bug fixes should be accompanied by changes to a test (either modifying an existi
---
-## __Testing in Drupal - SimpleTest__
+[.header: alignment(center)]
-- Based on
-- In D7 core
-- `*.test` files
-- All test classes in one file
+## _Testing may add time now,_ but save more
time in the future
---
-## __Testing in Drupal - PHPUnit__
+[.header: alignment(center)]
-- Used in other PHP projects (e.g. Symfony, Laravel)
-- In D8 core, but not default
-- `*.php` files
-- One test class per file
+## [fit] _How do you get quicker at writing tests?_
+# [fit] By writing more tests
---
-## __The PHPUnit Initiative__
+## _Testing in Drupal_
--
-- D8 core tests to change to PHPUnit
-- Deprecate SimpleTest, remove in D9
-- "A big chunk of old tests" converted on Feb 21st
+- _Drupal 7_ - Simpletest (testing) module provided as part of core
+- _Drupal 8_ - PHPUnit added as a core dependency
+- _PHPUnit Initiative_ - Simpletest to be deprecated and removed in Drupal 9
---
-## __The PHPUnit Initiative__
+## _Setting up your environment_
-As part of the PHPUnit initiative __a considerable part of Simpletests will be converted to PHPUnit based browser tests on February 21st 2017__. A backwards compatibility layer has been implemented so that many Simpletests can be converted by just using the new BrowserTestBase base class and moving the test file. There is also a script to automatically convert test files in the conversion issue.
-
-__Developers are encouraged to use BrowserTestBase instead of Simpletest as of Drupal 8.3.0__, but both test systems are fully supported during the Drupal 8 release cycle.
-
-The timeline for the deprecation of Simpletest's WebTestBase is under discussion.
-
-[.footer: https://groups.drupal.org/node/516229]
+- Drupal includes `core/phpunit.xml.dist`
+- Copy to `core/phpunit.xml`
+- Amend values as needed
+ + Add base URL, database credentials
+- Docksal - `fin addon install phpunit`
---
-## __Types of Tests__
+## _Writing Tests (Drupal 8)_
+
+- PHP class with `.php` extension
+- `tests/src` directory within each module
+- Within the `Drupal\Tests\module_name` namespace
+- Class name must match the filename
+- Namespace must match the directory structure
+- One test class per feature
+- Each method must start with `test`
+
+^ Different to D7
---
-## __Unit Tests__
+[.header: alignment(center)]
+
+## _1._ Arrange
+## _2._ Act
+## _3._ Assert
+
+---
+
+[.hide-footer]
+
+```php
+drupalGet('/examples/phpunit-example');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 5]
+drupalGet('/examples/phpunit-example');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 7-9]
+drupalGet('/examples/phpunit-example');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 11]
+drupalGet('/examples/phpunit-example');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 13-17]
+drupalGet('/examples/phpunit-example');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+
+## _Kernel Tests_
+
+- Integration tests
+- Can install modules, interact with services, container, database
+- Minimal Drupal bootstrap
+- Faster than functional tests
+- More setup required
+
+---
+
+## _Unit Tests_
-- `UnitTestCase`
- Tests PHP logic
- No database interaction
- Fast to run
-
----
-
-## __Unit Tests__
-
-__Pros:__
-
-- Verify individual parts
-- Quickly find problems in code
-- Fast execution
-- No system setup for the test run
-
----
-
-## __Unit Tests__
-
-__Cons:__
-
-- Rewrite on every refactoring
+- Tightly coupled
- Complicated mocking
-- No guarantee that the whole system actually works
---
-## __Kernel Tests__
-
-- Kernel tests are integration tests that test on components. You can install modules.
-- `KernelTestBase`
-
-[.footer: https://www.drupal.org/docs/8/testing/types-of-tests-in-drupal-8]
-
----
-
-## __Kernel Tests__
-
-__Pros:__
-
-- Verify that components actually work together
-- Somewhat easy to locate bugs
-
----
-
-## __Kernel Tests__
-
-__Cons:__
-
-- Slower execution
-- System setup required
-- No guarantee that end user features actually work
-
----
-
-## __UI Tests__
-
-- Web/Functional/FunctionalJavascript
-- `DrupalWebTestCase` (D7)
-- `WebTestBase`, `BrowserTestBase`, `JavascriptTestBase` (D8)
-- Tests functionality
-- Interacts with database
-- Slower to run
-- With/without JavaScript (D8)
-
-^ - Use JavascriptTestBase when you need to test how the system works for a user with Javascript enabled.
-
----
-
-## __Test Driven Development (TDD)__
-
-- Write a test, see it fail
-- Write code until test passes
-- Repeat
-- Refactor when tests are green
-
-
-
-[.footer: http://www.agilenutshell.com/assets/test-driven-development/tdd-circle-of-life.png]
-
-^ "Grab for green."
-Not the only way
-Write code beforehand and test afterwards
-Write code first, comment out/reset branch, then TDD
-
----
-
-## __Porting Modules to Drupal 8__
-
-- Make a new branch
- `git checkout --orphan 8.x-1.x`
-- Add/update the tests
-- Write code to make the tests pass
-- Refactor
-- Repeat
-
----
-
-## __Writing Tests (SimpleTest)__
-
----
-
-
-
-```ini
-# example.info
-
-name = Example
-core = 7.x
-files[] = example.test
-```
-
----
-
-
+[.hide-footer]
```php
-// example.test
+namespace Drupal\collection_class;
-class ExampleTestCase extends DrupalWebTestCase {
+class Collection implements \Countable, \IteratorAggregate {
+ private $items;
- public static function getInfo() {
- return array(
- 'name' => 'Example tests',
- 'description' => 'Web tests for the example module.',
- 'group' => 'Example',
- );
+ public function __construct($items = array()) {
+ $this->items = is_array($items) ? $items
+ : $this->getArrayableItems($items);
}
-}
-```
-
----
-
-```php, [.highlight: 5-7]
-class ExampleTestCase extends DrupalWebTestCase {
-
- ...
-
- public function testSomething {
- $this->assertTrue(TRUE);
+ public function __toString() {
+ return $this->toJson();
}
+ public function all() {
+ return $this->items;
+ }
+
+ public function count() {
+ return count($this->items);
+ }
+
+
+ public function isEmpty() {
+ return empty($this->items);
+ }
+
+ public function first() {
+ return array_shift($this->items);
+ }
}
```
---
-## __Writing Tests (PHPUnit)__
+[.hide-footer]
-- No need to load test classes expicitly.
-- Add classes into `tests/src` directory.
-- Extend `BrowserTestBase`.
-- No `getInfo` method.
+```php
+$collection = new Collection([1, 2, 3, 4, 5]);
-^ Classes get autoloaded PSR-4
+// Returns all items.
+$collection->all();
+
+// Counts the number of items.
+$collection->count();
+
+// Returns the array keys.
+$collection->keys();
+```
---
-
-
-## __Creating the World__
+[.hide-footer]
```php
-public function setUp() {
- // Enable any other required modules.
- parent::setUp(['foo', 'bar']);
+public function testAll() {
+ $items = ['foo', 'bar', 'baz'];
- // Anything else we need to do.
+ $collection = new Collection($items);
+
+ $this->assertEqual($items, $collection->all());
}
```
---
+[.header: #FFFFFF, alignment(left)]
+### _How do I know_
+## Which type of test to use?
-## __Creating the World__
+---
-```php
-$this->drupalCreateUser();
+### _Need a browser?_
+## Use a functional test
-$this->drupalLogin();
+---
-$this->drupalCreateNode();
+### _Interact with other services?_
+## Use a kernel test
-$this->drupalLogout();
+---
+
+### _Isolated PHP code?_
+## Use a unit test
+
+---
+
+## _Setup (functional)_
+
+[.hide-footer]
+
+```
+drupalCreateUser()
+drupalCreateRole()
+
+drupalLogin()
+drupalLogout()
+
+drupalGet()
+drupalPost()
+drupalPostForm()
```
---
-## __Assertions__
+## _Setup (kernel)_
-- `assertTrue`
-- `assertFalse`
-- `assertNull`
-- `assertNotNull`
-- `assertEqual`
- `assertEquals`
+```php
+# UserCreationTrait
+createUser()
+createAdminRole()
+createRole()
+checkPermissions()
+
+# CommentTestTrait
+addDefaultCommentField()
+
+# AssertMailTrait
+getMails()
+assertMail()
+```
---
-## __Assertions__
+## _Assertions_
-- `assertRaw`
-- `assertResponse`
- `assertSession()->statusCodeEquals()`
-- `assertField`
-- `assertFieldById`
-- `assertTitle`
+[.hide-footer]
+
+```php
+assertTrue()
+assertFalse()
+
+assertEquals()
+
+assertNull()
+assertNotNull()
+
+assertCount()
+assertEmpty()
+
+assertArraySubset()
+```
---
-## __Assertions__
+## _Assertions (functional)_
-- `assertText`
- `assertSession()->pageTextContains()`
-- `assertNoText`
- `assertSession()->pageTextNotContains()`
+[.hide-footer]
+
+```php
+pageTextContains()
+pageTextNotContains()
+
+linkByHrefExists()
+linkByHrefNotExists()
+
+statusCodeEquals()
+statusCodeNotEquals()
+```
---
-# __Running Tests__
+[.header: alignment(center)]
+
+# _Real life_ example
---
-## __SimpleTest UI__
+[.background-color: #FFFFFF]
+[.footer-style: #2F2F2F]
+
+
+
+---
+
+## _Specification_
+
+- Job adverts created on third-party system, needs to create nodes in Drupal, links users to separate application system
+- Adverts need to be linked to offices
+- Advert length specified in number of days
+- Path is specified as a field in the API
+- Application URL constructed from domain, includes role ID as a GET parameter and optionally UTM parameters
+
+---
+
+[.hide-footer]
+
+```php
+$data = [
+ 'command' => 'add',
+ 'username' => 'bobsmith',
+ 'password' => 'p455w0rd',
+ 'active_for' => '365',
+ 'application_email' => 'bob.12345.123@smith.aplitrak.com',
+ 'branch_address' => '123 Fake St, Bristol, BS1 2AB',
+ 'branch_name' => 'Test',
+ 'contract' => 'Temporary',
+ 'details' => 'This is the detailed description.',
+ 'job_id' => 'abc123_1234567',
+ 'job_title' => 'Healthcare Assistant (HCA)',
+ 'job_type' => 'Care at Home',
+ 'keywords' => 'flexible, Bristol, part-time',
+ 'locations' => 'Bath, Devizes',
+ 'role_id' => 'A/52/86',
+ 'salary' => '32,000.00 per annum',
+ 'salary_prefix' => 'Basic Salary',
+ 'status' => 'Part time',
+ 'summary' => 'This is the short description.',
+ 'url_alias' => 'healthcare-assistant-aldershot-june17',
+];
+```
+
+---
+
+## _Implementation_
+
+- Added route to accept data from API as XML
+- Added user with API role to authenticate
+- `active_for` converted from number of days to UNIX timestamp
+- `branch_name` and `locations` converted from plain text to entity reference (job node to office node)
+- `url_alias` property mapped to `path`
+
+---
+
+## _Goals_
+
+- Ensure job nodes are _successfully created_
+- Ensure that fields are _mapped correctly_
+- Ensure that _calculations are correct_
+- Ensure that entity references are _linked correctly_
+
+---
+
+## _Types of tests_
+
+- _Unit:_ ensure number of days are converted to timestamps correctly
+- _Kernel:_ job nodes can be added and deleted, expired job nodes are deleted, application URL is generated correctly
+- _Functional:_ job nodes are created with the correct URL and the correct response code is returned
+- _FunctionalJavaScript:_ application URL is updated with JavaScript based on UTM parameters (hosting)
+
+---
+
+## _Results_
+
+- _0 bugs!_
+- Reduced debugging time
+- Easier to identify where issues occurred and responsibilities
+
+---
+
+[.header: alignment(center)]
+
+## Running Tests
---
@@ -364,873 +652,1150 @@ $this->drupalLogout();
---
-## __Running SimpleTest (CLI)__
-
-
-
-```bash
-# Drupal 7
-$ php scripts/run-tests.sh
-
-# Drupal 8
+```
$ php core/scripts/run-tests.sh
+
+$ php core/scripts/run-tests.sh --module example
+
+$ php core/scripts/run-tests.sh --class ExampleTest
```
---
-## __Running SimpleTest (CLI)__
+```
+vendor/bin/phpunit -c core path/to/module
-```bash
---color
+vendor/bin/phpunit -c core path/to/module --filter testSomething
---verbose
-
---all
-
---module
-
---class
-
---file
+vendor/bin/phpunit -c core path/to/module --verbose
```
---
-## __Running PHPUnit__
+[.header: alignment(center)]
-```bash
-# Assumes you have a configured phpunit.xml file.
-
-$ vendor/bin/phpunit
-
-$ vendor/bin/phpunit [directory]
-
-$ vendor/bin/phpunit --filter [method]
-
-$ vendor/bin/phpunit --verbose --debug
-```
-
-^ Either need to be inside "core" directory or use "-c core"
+## _Test Driven_
Development
---
-## __Example: Collection Class__
+## _Test Driven Development_
+
+- Write a test
+- See it fail
+- Write code until test passes
+- Refactor when tests are green
+- Repeat
---
-## __Collection Class__
+[.background-color: #FFFFFF]
+[.footer: https://github.com/foundersandcoders/testing-tdd-intro]
+[.footer-style: #2F2F2F]
--
-- Adds a `Collection` class, based on Laravel’s
-- Provides helper methods for array methods
-- Drupal 7, uses xautoload
-- All unit tests
-
-^ xautoload gives PSR-4 namespaces and autoloading similar to Drupal 8.
+
---
+[.header: alignment(center)]
-
-```php
-$collection = collect([1, 2, 3, 4, 5]);
-
-// Returns all items.
-$collection->all();
-
-// Counts the number of items.
-$collection->count();
-
-// Returns the array keys.
-$collection->keys();
-```
+## Red, Green, Refactor
---
+## _Porting Modules to Drupal 8_
-
-```php
-namespace Drupal\collection_class;
-
-class Collection implements \Countable, \IteratorAggregate {
- private $items;
-
- public function __construct($items = array()) {
- $this->items = is_array($items) ? $items
- : $this->getArrayableItems($items);
- }
-
- public function __toString() {
- return $this->toJson();
- }
-
- ...
-```
+- Make a new branch
+- Add/update the tests
+- Write code to make the tests pass
+- Refactor
+- Repeat
---
+## _How I Write Tests - "Outside In"_
-
-```php
-public function all() {
- return $this->items;
-}
-
-public function count() {
- return count($this->items);
-}
-
-
-public function isEmpty() {
- return empty($this->items);
-}
-
-public function first() {
- return array_shift($this->items);
-}
-```
+- Start with functional tests
+- Drop down to integration or unit tests where needed
+- Programming by wishful thinking
+- Write comments first, then fill in the code
+- Write assertions first, sometimes
---
-## __Testing__
+[.header: alignment(center)]
-```php
-public function setUp() {
- $this->firstCollection = collect(['foo', 'bar', 'baz']);
-
- $this->secondCollection = collect([
- array('title' => 'Foo', 'status' => 1),
- array('title' => 'Bar', 'status' => 0),
- array('title' => 'Baz', 'status' => 1)
- ]);
-
- parent::setUp();
-}
-```
+## Building a new _Drupal 8 Module_ with _TDD_
---
-## __Testing__
+## _Acceptance criteria_
-```php
-public function testCollectFunction() {
- $this->assertEqual(
- get_class($this->firstCollection),
- 'Drupal\collection_class\Collection'
- );
-}
-```
+- As a site visitor
+- I want to see a list of published articles at /blog
+- Ordered by post date
---
-## __Testing__
+## _Tasks_
-```php
-public function testAll() {
- $this->assertEqual(
- array('foo', 'bar', 'baz'),
- $this->firstCollection->all()
- );
-}
-```
+- Ensure the blog page exists
+- Ensure only published articles are shown
+- Ensure the articles are shown in the correct order
---
-## __Testing__
+## _Implementation_
-```php
-public function testCount() {
- $this->assertEqual(
- 3,
- $this->firstCollection->count()
- );
-}
-```
+- Use views module
+- Do the mininum amount at each step, make no assumptions, let the tests guide us
+- Start with functional test
---
-## __Testing__
-
-```php
-public function testMerge() {
- $first = collect(array('a', 'b', 'c'));
- $second = collect(array('d', 'e', 'f'));
-
- $this->assertEqual(
- array('a', 'b', 'c', 'd', 'e', 'f'),
- $first->merge($second)->all()
- );
-}
-```
-
----
-
-
-
----
-
-
-
----
-
-## __Example: Toggle Optional Fields__
-
----
-
-## __Toggle Optional Fields__
-
--
-- Adds a button to toggle optional fields on node forms using form alters
-- Possible to override using an custom alter hook
-- Uses unit and web tests
-
-
-
----
-
-```php
-// Looping through available form elements...
-
-// Only affect fields.
-if (!toggle_optional_fields_element_is_field($element_name)) {
- return;
-}
-
-$element = &$form[$element_name];
-
-if (isset($overridden_fields[$element_name])) {
- return $element['#access'] = $overridden_fields[$element_name];
-}
-
-// If the field is not required, disallow access to hide it.
-if (isset($element[LANGUAGE_NONE][0]['#required'])) {
- return $element['#access'] = !empty($element[LANGUAGE_NONE][0]['#required']);
-}
-```
-
----
-
-## __What to Test?__
-
-- **Functional:** Are the correct fields shown and hidden?
-- **Unit:** Is the field name check returning correct results?
-
----
-
-## __Unit Tests__
-
-```php
-// Returns TRUE or FALSE to indicate if this is a field.
-
-function toggle_optional_fields_element_is_field($name) {
- if (in_array($name, array('body', 'language'))) {
- return TRUE;
- }
-
- return substr($name, 0, 6) == 'field_';
-}
-```
-
----
-
-## __Unit Tests__
-
-```php
-public function testElementNameIsField() {
- ...
-
- $this->assertTrue(
- toggle_optional_fields_element_is_field('field_tags')
- );
-
- $this->assertTrue(
- toggle_optional_fields_element_is_field('body')
- );
-
- $this->assertFalse(
- toggle_optional_fields_element_is_field('title')
- );
-}
-```
-
----
-
-## __Unit Tests__
-
-```php
-public function testElementNameIsField() {
- ...
-
- foreach ($this->elementNameDataProvider() as $data) {
- list($element_name, $expected_result) = $data;
-
- $this->assertEquals(
- $expected_result,
- toggle_optional_fields_element_is_field($element_name)
- );
- }
-}
-
-private function elementNameDataProvider() {
- return array(
- array('body', TRUE),
- array('field_tags', TRUE),
- array('title', FALSE),
- );
-}
-```
-
----
-
-
-
----
-
-## __Web Tests__
-
-```php
-public function setUp() {
- parent::setUp();
-
- $this->drupalLogin(
- $this->drupalCreateUser(array(
- 'create article content',
- 'create page content'
- ));
- );
-
- // Enable toggling on article node forms.
- variable_set('toggle_optional_fields_node_types', array('article'));
-
- $this->refreshVariables();
-}
-```
-
----
-
-## __Custom Assertions__
-
-```php
-private function assertTagsFieldNotHidden() {
- $this->assertFieldByName(
- 'field_tags[und]',
- NULL,
- t('Tags field visible.')
- );
-}
-```
-
----
-
-## __Testing Hidden Fields__
-
-```php
-public function testFieldsHiddenByDefault() {
- variable_set('toggle_optional_fields_hide_by_default', TRUE);
-
- $this->refreshVariables();
-
- $this->drupalGet('node/add/article');
-
- $this->assertShowOptionalFieldsButtonFound();
- $this->assertHideOptionalFieldsButtonNotFound();
- $this->assertTagsFieldHidden();
-
- ...
-```
-
----
-
-## __Testing Hidden Fields__
-
-```php
- ...
-
- $this->drupalPost(
- 'node/add/article',
- array(),
- t('Show optional fields')
- );
-
- $this->assertHideOptionalFieldsButtonFound();
- $this->assertShowOptionalFieldsButtonNotFound();
- $this->assertTagsFieldNotHidden();
-}
-```
-
----
-
-
-
----
-
-
-
----
-
-# __Building a new Drupal
8 Module with TDD__
-
----
-
-As a site visitor
-
-I want to see a list of all published pages at `/pages`
-
-Ordered alphabetically by title.
-
----
+[.hide-footer]
```yml
-# tdd_dublin.info.yml
+# tdd_blog.info.yml
-name: DrupalCamp Dublin test
-core: 8.x
-type: module
+name: 'TDD Example'
+core: '8.x'
+type: 'module'
```
---
+### _Task 1:_
+## Ensure the blog page exists
+
+---
+
+[.hide-footer]
+
```php
-// tests/src/Functional/ListingPageTest.php
+drupalGet('pages');
+use Drupal\Tests\BrowserTestBase;
+
+class BlogPageTest extends BrowserTestBase {
+
+ protected static $modules = ['tdd_blog'];
+
+ public function testBlogPageExists() {
+ $this->drupalGet('/blog');
$this->assertSession()->statusCodeEquals(200);
}
+
}
```
---
+[.hide-footer]
+
+```php, [.highlight: 5]
+drupalGet('/blog');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+}
```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
-Testing modules/tdd_dublin/tests/
-E
+---
-Time: 25.94 seconds, Memory: 6.00MB
+[.hide-footer]
+
+```php, [.highlight: 7-9]
+drupalGet('/blog');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 11]
+drupalGet('/blog');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 13-17]
+drupalGet('/blog');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```bash, [.highlight: 1]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
+
+Time: 19.31 seconds, Memory: 6.00MB
There was 1 error:
-1) PageListTest::testListingPage
-Behat\Mink\Exception\ExpectationException: Current response status code is 404,
-but 200 expected.
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected.
-/var/www/vendor/behat/mink/src/WebAssert.php:770
+/var/www/vendor/behat/mink/src/WebAssert.php:768
/var/www/vendor/behat/mink/src/WebAssert.php:130
-/var/www/modules/tdd_dublin/tests/src/PageListTest.php:11
+/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 3, Errors: 1.
```
---
-- Add the view.
-- Copy the config into the module’s `config/install`.
+[.hide-footer]
----
+```bash, [.highlight: 4]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
-Testing modules/tdd_dublin/tests/
-E
-
-Time: 19.07 seconds, Memory: 6.00MB
+Time: 19.31 seconds, Memory: 6.00MB
There was 1 error:
-1) PageListTest::testListingPage
-Drupal\Core\Config\UnmetDependenciesException:
-Configuration objects provided by tdd_dublin
-have unmet dependencies:
-node.type.page (node),
-views.view.pages (node, views)
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected.
+
+/var/www/vendor/behat/mink/src/WebAssert.php:768
+/var/www/vendor/behat/mink/src/WebAssert.php:130
+/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 3, Errors: 1.
```
---
-```yml
-name: DrupalCamp Dublin tests
+[.hide-footer]
+
+```bash, [.highlight: 5-13]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
+
+Time: 19.31 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected.
+
+/var/www/vendor/behat/mink/src/WebAssert.php:768
+/var/www/vendor/behat/mink/src/WebAssert.php:130
+/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 3, Errors: 1.
+```
+
+---
+
+[.hide-footer]
+
+```bash, [.highlight: 14-16]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
+
+Time: 19.31 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected.
+
+/var/www/vendor/behat/mink/src/WebAssert.php:768
+/var/www/vendor/behat/mink/src/WebAssert.php:130
+/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 3, Errors: 1.
+```
+
+---
+
+[.hide-footer]
+
+```bash, [.highlight: 18-19]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
+
+Time: 19.31 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected.
+
+/var/www/vendor/behat/mink/src/WebAssert.php:768
+/var/www/vendor/behat/mink/src/WebAssert.php:130
+/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 3, Errors: 1.
+```
+
+---
+
+- _The view has not been created_
+- Create a new view
+- Set the path
+- Export the config
+- Copy it into the module's `config/install` directory
+
+---
+
+[.hide-footer]
+
+```[.highlight: 11-13]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
+
+Time: 16.02 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by tdd_blog
+have unmet dependencies: views.view.blog (node.type.article, node, views)
+
+/var/www/web/core/lib/Drupal/Core/Config/UnmetDependenciesException.php:98
+/var/www/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:469
+/var/www/web/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:132
+/var/www/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:145
+/var/www/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
+/var/www/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:437
+/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:1055
+/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:490
+
+ERRORS!
+Tests: 1, Assertions: 0, Errors: 1.
+```
+
+---
+
+[.hide-footer]
+
+```yml,[.highlight: 1, 7-10]
+# tdd_blog.info.yml
+
+name: 'TDD Dublin'
+description: 'A demo module to show test driven module development.'
core: 8.x
type: module
dependencies:
- - drupal:node
- - drupal:views
+ - 'drupal:node'
+ - 'drupal:views'
```
---
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+[.hide-footer]
-Testing modules/tdd_dublin/tests/
-.
+```[.highlight: 10-13]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
-Time: 29.58 seconds, Memory: 6.00MB
+Testing modules/custom/tdd_blog
+E 1 / 1 (100%)
-OK (1 test, 1 assertion)
+Time: 20 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
+Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by tdd_blog
+have unmet dependencies: views.view.blog (node.type.article)
+
+/var/www/web/core/lib/Drupal/Core/Config/UnmetDependenciesException.php:98
+/var/www/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:469
+/var/www/web/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:132
+/var/www/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:145
+/var/www/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83
+/var/www/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:437
+/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:1055
+/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:490
+
+ERRORS!
+Tests: 1, Assertions: 0, Errors: 1.
```
---
-```php
-public function testOnlyPublishedPagesAreShown() {
- // Given I have a mixture of published and unpublished pages,
- // as well as other types of content.
-
- // When I view the pages list.
-
- // I should only see the published pages.
-}
-```
+- Add the article content type
---
-```php
-public function testOnlyPublishedPagesAreShown() {
- $this->drupalCreateContentType(['type' => 'article']);
+[.hide-footer]
- $nodeA = $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]);
- $nodeB = $this->drupalCreateNode(['type' => 'article']);
- $nodeC = $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]);
+```[.highlight: 5, 9]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
- // When I view the pages list.
+Testing modules/custom/tdd_blog
+. 1 / 1 (100%)
- // I should only see the published pages.
-}
-```
-
----
-
-```php
-public function testOnlyPublishedPagesAreShown() {
- ...
-
- $this->drupalGet('/pages');
-
- $this->assertSession()->statusCodeEquals(200);
-
- $this->assertSession()->pageTextContains($nodeA->label());
-
- $this->assertSession()->pageTextNotContains($nodeB->label());
- $this->assertSession()->pageTextNotContains($nodeC->label());
-}
-```
-
----
-
-```php
-public function testOnlyPublishedPagesAreShown() {
- $this->drupalCreateContentType(['type' => 'article']);
-
- $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]);
- $this->drupalCreateNode(['type' => 'article']);
- $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]);
-
- $results = views_get_view_result('pages');
-
- $nids = array_column($results, 'nid'); // [1, 3]
-
- // I should only see the published pages.
-}
-```
-
----
-
-```php
-public function testOnlyPublishedPagesAreShown() {
- $this->drupalCreateContentType(['type' => 'article']);
-
- $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]);
- $this->drupalCreateNode(['type' => 'article']);
- $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]);
-
- $results = views_get_view_result('pages');
-
- $nids = array_column($results, 'nid'); // [1, 3]
-
- $this->assertEquals([1], $nids);
-}
-```
-
----
-
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
---filter=testOnlyPublishedPagesAreShown
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
-
-Testing modules/tdd_dublin/tests
-F
-
-Time: 26.4 seconds, Memory: 6.00MB
-
-There was 1 failure:
-```
-
----
-
-```
-1) PageListTest::testOnlyPublishedPagesAreShown
-Failed asserting that two arrays are equal.
---- Expected
-+++ Actual
-@@ @@
- Array (
-- 0 => 1
-+ 0 => '1'
-+ 1 => '3'
- )
-
-/var/www/tests/Drupal/Tests/BrowserTestBase.php:1240
-/var/www/modules/tdd_dublin/tests/src/PageListTest.php:25
-
-FAILURES!
-Tests: 1, Assertions: 3, Failures: 1.
-```
-
----
-
-[.build-lists: false]
-
-- Edit the view
-- Add the status filter
-- Update the module config
-
----
-
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
---filter=testOnlyPublishedPagesAreShown
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
-
-Testing modules/tdd_dublin/tests
-.
-
-Time: 26.53 seconds, Memory: 6.00MB
+Time: 23.36 seconds, Memory: 6.00MB
OK (1 test, 3 assertions)
```
---
+## _Tasks_
+
+- ~~Ensure the blog page exists~~
+- Ensure only published articles are shown
+- Ensure the articles are shown in the correct order
+
+---
+
+### _Task 2:_
+## Ensure only published articles are shown
+
+---
+
+[.hide-footer]
+
```php
-public function testPagesAreOrderedAlphabetically() {
- // Given I have multiple pages with different titles.
+public function testOnlyPublishedArticlesAreShown() {
+ // Given I have a mixture of published and unpublished articles,
+ // as well as other types of content.
- // When I view the pages list.
+ // When I view the blog page.
- // I see the pages in the correct order.
+ // I should only see the published articles.
}
```
---
-```php
-public function testPagesAreOrderedAlphabetically() {
- $this->drupalCreateNode(['title' => 'Page A']);
- $this->drupalCreateNode(['title' => 'Page D']);
- $this->drupalCreateNode(['title' => 'Page B']);
- $this->drupalCreateNode(['title' => 'Page C']);
+[.header: alignment(center)]
- $results = views_get_view_result('pages');
+### _Option 1:_ Functional tests
- $nids = array_column($results, 'nid');
+---
- $this->assertEquals([1, 3, 4, 2], $nids);
+[.hide-footer]
+
+```php,[.highlight: 1, 4-8]
+// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
+
+public function testOnlyPublishedArticlesAreShown() {
+ // Given I have a mixture of published and unpublished articles,
+ // as well as other types of content.
+ $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]);
+ $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]);
+ $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]);
+
+ // When I view the blog page.
+ $this->drupalGet('/blog');
+
+ // I should only see the published articles.
+ $assert = $this->assertSession();
+ $assert->pageTextContains($node2->label());
+ $assert->pageTextNotContains($node1->label());
+ $assert->pageTextNotContains($node3->label());
+}
+```
+
+^ Different ways to achieve this. This is taking the functional test approach.
+
+---
+
+[.hide-footer]
+
+```php,[.highlight: 10-12]
+// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
+
+public function testOnlyPublishedArticlesAreShown() {
+ // Given I have a mixture of published and unpublished articles,
+ // as well as other types of content.
+ $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]);
+ $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]);
+ $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]);
+
+ // When I view the blog page.
+ $this->drupalGet('/blog');
+
+ // I should only see the published articles.
+ $assert = $this->assertSession();
+ $assert->pageTextContains($node2->label());
+ $assert->pageTextNotContains($node1->label());
+ $assert->pageTextNotContains($node3->label());
}
```
---
+[.hide-footer]
+
+```php, [.highlight: 13-17]
+// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
+
+public function testOnlyPublishedArticlesAreShown() {
+ // Given I have a mixture of published and unpublished articles,
+ // as well as other types of content.
+ $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]);
+ $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]);
+ $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]);
+
+ // When I view the blog page.
+ $this->drupalGet('/blog');
+
+ // I should only see the published articles.
+ $assert = $this->assertSession();
+ $assert->pageTextContains($node2->label());
+ $assert->pageTextNotContains($node1->label());
+ $assert->pageTextNotContains($node3->label());
+}
```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
--filter=testPagesAreOrderedAlphabetically
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
-Testing modules/tdd_dublin/tests
-F
+---
-Time: 28.03 seconds, Memory: 6.00MB
+[.header: alignment(center)]
+
+### _Option 2:_ Kernel tests
+
+---
+
+[.hide-footer]
+
+```php
+createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+ }
+
+}
+```
+
+^ Kernel test approach
+Dropping down a level
+No need for the brower, not asserting against HTML
+Faster to run
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 3-8]
+createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 10]
+createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 14-18]
+createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```[.highlight: 9-16]
+docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog/tests/src/Kernel/
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing modules/custom/tdd_blog/tests/src/Kernel/
+E 1 / 1 (100%)
+
+Time: 6.22 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown
+Error: Call to a member function id() on boolean
+
+/var/www/web/core/modules/filter/filter.module:212
+/var/www/web/core/modules/node/tests/src/Traits/NodeCreationTrait.php:73
+/var/www/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:13
+
+ERRORS!
+Tests: 1, Assertions: 2, Errors: 1.
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 2]
+public function testOnlyPublishedArticlesAreShown() {
+ $this->installConfig(['filter']);
+
+ $this->createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 8]
+public function testOnlyPublishedArticlesAreShown() {
+ $this->installConfig(['filter']);
+
+ $this->createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+
+ $results = views_get_view_result('blog');
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 3]
+...
+
+public static $modules = ['node', 'tdd_blog', 'views'];
+
+public function testOnlyPublishedArticlesAreShown() {
+ $this->installConfig(['filter', 'tdd_blog']);
+
+ $this->createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+
+ $results = views_get_view_result('blog');
+
+ $this->assertCount(1, $results);
+ $this->assertEquals(2, $results[0]->_entity->id());
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 6]
+...
+
+public static $modules = ['node', 'tdd_blog', 'views'];
+
+public function testOnlyPublishedArticlesAreShown() {
+ $this->installConfig(['filter', 'tdd_blog']);
+
+ $this->createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+
+ $results = views_get_view_result('blog');
+
+ $this->assertCount(1, $results);
+ $this->assertEquals(2, $results[0]->_entity->id());
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 8-15]
+...
+
+public static $modules = ['node', 'tdd_blog', 'views'];
+
+public function testOnlyPublishedArticlesAreShown() {
+ $this->installConfig(['filter', 'tdd_blog']);
+
+ $this->createNode(['type' => 'page', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 1]);
+ $this->createNode(['type' => 'article', 'status' => 0]);
+
+ $results = views_get_view_result('blog');
+
+ $this->assertCount(1, $results);
+ $this->assertEquals(2, $results[0]->_entity->id());
+}
+```
+
+^ Assert
+Should only be one result, should be node 2
+Node IDs are reset on each test method
+
+---
+
+[.hide-footer]
+
+```
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+F 1 / 1 (100%)
+
+Time: 2.16 seconds, Memory: 6.00MB
There was 1 failure:
+
+1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown
+Failed asserting that actual size 3 matches expected size 1.
+
+/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:23
+
+FAILURES!
+Tests: 1, Assertions: 4, Failures: 1.
```
---
+[.hide-footer]
+
+```[.highlight: 8-13]
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+F 1 / 1 (100%)
+
+Time: 2.16 seconds, Memory: 6.00MB
+
+There was 1 failure:
+
+1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown
+Failed asserting that actual size 3 matches expected size 1.
+
+/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:23
+
+FAILURES!
+Tests: 1, Assertions: 4, Failures: 1.
```
-1) PageListTest::testPagesAreOrderedAlphabetically
+
+---
+
+>- _There are no filters on the view_
+- Add the filters
+- Export and save the view
+
+---
+
+```[.highlight: 3-8]
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+. 1 / 1 (100%)
+
+Time: 2.02 seconds, Memory: 6.00MB
+
+OK (1 test, 6 assertions)
+```
+
+---
+
+## _Tasks_
+
+- ~~Ensure the blog page exists~~
+- ~~Ensure only published articles are shown~~
+- Ensure the articles are shown in the correct order
+
+---
+
+### _Task 3:_
+## Ensure the articles are shown in the correct order
+
+---
+
+[.hide-footer]
+
+```php
+// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
+
+public function testArticlesAreOrderedByDate() {
+ // Given that I have numerous articles with different post dates.
+
+ // When I go to the blog page.
+
+ // The articles are ordered by post date.
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 4-9]
+// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
+
+public function testArticlesAreOrderedByDate() {
+ // Given that I have numerous articles with different post dates.
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]);
+
+ // When I go to the blog page.
+
+ // The articles are ordered by post date.
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 10-11]
+// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
+
+public function testArticlesAreOrderedByDate() {
+ // Given that I have numerous articles with different post dates.
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]);
+
+ // When I go to the blog page.
+ $results = views_get_view_result('blog');
+
+ // The articles are ordered by post date.
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight:10-15]
+// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
+
+public function testArticlesAreOrderedByDate() {
+ // Given that I have numerous articles with different post dates.
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]);
+
+ // When I go to the blog page.
+ $results = views_get_view_result('blog');
+
+ $nids = array_map(function(ResultRow $result) {
+ return $result->_entity->id();
+ }, $results);
+
+ // The articles are ordered by post date.
+}
+```
+
+---
+
+[.hide-footer]
+
+```php, [.highlight: 5-9, 17-18]
+// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
+
+public function testArticlesAreOrderedByDate() {
+ // Given that I have numerous articles with different post dates.
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]);
+ $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]);
+
+ // When I go to the blog page.
+ $results = views_get_view_result('blog');
+
+ $nids = array_map(function(ResultRow $result) {
+ return $result->_entity->id();
+ }, $results);
+
+ // The articles are ordered by post date.
+ $this->assertEquals([4, 1, 3, 2], $nids);
+}
+```
+
+---
+
+[.hide-footer]
+
+```
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
+
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+F 1 / 1 (100%)
+
+Time: 1.42 seconds, Memory: 6.00MB
+
+There was 1 failure:
+
+1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testArticlesAreOrderedByDate
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
Array (
-- 0 => 1
-- 1 => 3
-- 2 => 4
+- 0 => 4
+- 1 => 1
+- 2 => 3
- 3 => 2
-+ 0 => '1'
++ 0 => '3'
+ 1 => '2'
-+ 2 => '3'
-+ 3 => '4'
- )
++ 2 => '4'
++ 3 => '1'
-/var/www/tests/Drupal/Tests/BrowserTestBase.php:1240
-/var/www/modules/tdd_dublin/tests/src/PageListTest.php:36
+/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114
+/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43
+
+FAILURES!
+Tests: 1, Assertions: 4, Failures: 1.
```
---
-- Edit the view
-- Remove the default sort criteria (created on)
-- Add new sort criteria
-- Update the module config
+[.hide-footer]
----
+```[.highlight: 8-26]
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
---filter=testPagesAreOrderedAlphabetically
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+F 1 / 1 (100%)
-Testing modules/tdd_dublin/tests
-.
+Time: 1.42 seconds, Memory: 6.00MB
-Time: 27.67 seconds, Memory: 6.00MB
+There was 1 failure:
-OK (1 test, 2 assertions)
+1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testArticlesAreOrderedByDate
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 4
+- 1 => 1
+- 2 => 3
+- 3 => 2
++ 0 => '3'
++ 1 => '2'
++ 2 => '4'
++ 3 => '1'
+
+/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114
+/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43
+
+FAILURES!
+Tests: 1, Assertions: 4, Failures: 1.
```
---
-```
-docker@cli:/var/www$ vendor/bin/phpunit -c core modules/tdd_dublin/tests
-PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+- _There is no sort order defined on the view_
+- Add the sort order
+- Re-export the view
-Testing modules/tdd_dublin/tests
-...
+---
-Time: 1.17 minutes, Memory: 6.00MB
+```[.highlight:3-8]
+PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
-OK (3 tests, 6 assertions)
+Testing web/modules/custom/tdd_blog/tests/src/Kernel
+. 1 / 1 (100%)
+
+Time: 1.74 seconds, Memory: 6.00MB
+
+OK (1 test, 5 assertions)
```
---
-## __Downgrading to Kernel Tests__
+## _Tasks_
+
+- ~~Ensure the blog page exists~~
+- ~~Ensure only published articles are shown~~
+- ~~Ensure the articles are shown in the correct order~~
---
-```php
-// tests/src/Kernel/PageListTest.php
+[.header: alignment(center)]
-namespace Drupal\Tests\tdd_dublin\Kernel;
-
-use Drupal\KernelTests\KernelTestBase;
-
-class PageListTest extends KernelTestBase {
-}
-```
+## Take Aways
---
-```php
-public function testOnlyPublishedPagesAreShown() {
- $nids = array_column(views_get_view_result('pages'), 'nid');
-
- $this->assertEquals([1], $nids);
-}
-```
-
-^ Started with assertions and worked backwards
-"Outside in"
-
----
-
-```php
-protected static $modules = [
- 'node',
- 'system',
- 'tdd_dublin',
- 'user',
- 'views'
-];
-
-protected function setUp() {
- parent::setUp();
-
- $this->installConfig(['tdd_dublin']);
-
- $this->installEntitySchema('node');
- $this->installEntitySchema('user');
-}
-```
-
----
-
-```php
-use Drupal\node\Entity\Node;
-use Drupal\node\Entity\NodeType;
-
-public function testOnlyPublishedPagesAreShown() {
- NodeType::create(['type' => 'article', 'name' => t('Article')]);
-
- Node::create($this->getValidParams(['status' => TRUE]))->save();
- Node::create($this->getValidParams(['type' => 'article']))->save();
- Node::create($this->getValidParams(['status' => FALSE]))->save();
-
- $nids = array_column(views_get_view_result('pages'), 'nid');
-
- $this->assertEquals([1], $nids);
-}
-
-private function getValidParams(array $overrides = []) {
- return array_merge([
- 'status' => TRUE,
- 'title' => $this->randomString(),
- 'type' => 'page',
- ], $overrides);
-}
-```
-
----
-
-```
-Testing modules/custom/tdd_dublin/tests/src/Kernel
-.
-
-Time: 8.9 seconds, Memory: 6.00MB
-
-OK (1 test, 4 assertions)
-```
-
-^ Previously 26 seconds
-
----
-
-
-
----
-
-## __Demo__
-
----
-
-- Testing has made me a better developer
-- Testing can produce better quality code
-- Use the right type of test for the right situation
-- Writing tests is an investment
-- OK to start small, introduce tests gradually
-- Easier to refactor
-- Tests can pass, but things can still be broken. Tests only report on what they cover.
+- Testing has made me a _better developer_
+- Testing can produce _better quality code_
+- Use the _right type of test_ for the right situation
+- Use the _right base class_, use available _traits_
+- Writing tests is an _investment_
+- OK to _start small_, introduce tests gradually
+- Easier to _refactor_
+- Tests can pass, but things can _still be broken_. Tests only report on what they cover.
^ Made me think about how I'm going to do something more starting to do it
Less cruft, only write code that serves a purpose
@@ -1241,16 +1806,40 @@ Manual testing is still important
---
-- https://github.com/opdavies/tdd_dublin
-- https://www.oliverdavies.uk/blog/2017/11/07/writing-drupal-module-test-driven-development-tdd
-- https://www.oliverdavies.uk/blog/tdd-drupal-part-2-kernel-tests
-- https://knpuniversity.com/screencast/phpunit
-- https://adamwathan.me/test-driven-laravel
-- https://laracasts.com
-- https://drupalize.me/series/testing-drupal-7-simpletest
-- https://www.lullabot.com/articles/an-overview-of-testing-in-drupal-8
-- https://www.youtube.com/watch?v=jcdEp3YGa94
+[.hide-footer]
+[.text: alignment(center)]
+
+> 
---
-## __Questions?__
+## _Resources_
+
+- github.com/opdavies/drupal-module-tdd-dublin
+- drupalize.me/series/testing-drupal-7-simpletest
+- lullabot.com/articles/an-overview-of-testing-in-drupal-8
+- mediacurrent.com/blog/writing-simple-simpletest-tests-your-d7-module
+- mediacurrent.com/blog/writing-simple-phpunit-tests-your-d8-module
+- knpuniversity.com/screencast/phpunit
+- adamwathan.me/test-driven-laravel
+- laracasts.com
+
+---
+
+- oliverdavies.uk/_talks_
+- oliverdavies.uk/_twitter_
+- oliverdavies.uk/_drupal_
+- oliverdavies.uk/_github_
+- oliverdavies.uk/_youtube_
+
+---
+
+[.header: alignment(center)]
+
+## Questions?
+
+---
+
+[.header: alignment(center)]
+
+# Thanks
diff --git a/tdd-test-driven-drupal/todo.md b/tdd-test-driven-drupal/todo.md
index 8e96c0c..63b93e0 100644
--- a/tdd-test-driven-drupal/todo.md
+++ b/tdd-test-driven-drupal/todo.md
@@ -1,3 +1,2 @@
- Show composer.json setup
-- Remove D7 code samples, focus on D8
- Show `fin phpunit`