diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/appnovation.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/appnovation.png
new file mode 100644
index 0000000..49e432c
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/appnovation.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-1.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-1.png
new file mode 100644
index 0000000..3c1d004
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-1.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-2.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-2.png
new file mode 100644
index 0000000..09be34e
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/collection-class-2.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/dcbristol.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/dcbristol.png
new file mode 100644
index 0000000..552904f
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/dcbristol.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/me.jpg b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/me.jpg
new file mode 100644
index 0000000..4b3e031
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/me.jpg differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/phpunit.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/phpunit.png
new file mode 100644
index 0000000..d22c405
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/phpunit.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-1.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-1.png
new file mode 100644
index 0000000..368de76
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-1.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-2.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-2.png
new file mode 100644
index 0000000..f823167
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-2.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-3.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-3.png
new file mode 100644
index 0000000..c413758
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-3.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-4.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-4.png
new file mode 100644
index 0000000..fcce824
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest-4.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest.png
new file mode 100644
index 0000000..76c497c
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/simpletest.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/tdd-circle-of-life.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/tdd-circle-of-life.png
new file mode 100644
index 0000000..78e5f34
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/tdd-circle-of-life.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/timmillwood-ono.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/timmillwood-ono.png
new file mode 100644
index 0000000..be4eda4
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/timmillwood-ono.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/title.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/title.png
similarity index 100%
rename from tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/title.png
rename to tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/title.png
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-1.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-1.png
new file mode 100644
index 0000000..8378788
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-1.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-2.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-2.png
new file mode 100644
index 0000000..4112014
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-2.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-3.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-3.png
new file mode 100644
index 0000000..8339887
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-3.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-button.png b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-button.png
new file mode 100644
index 0000000..7f8db5f
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/images/toggle-optional-fields-button.png differ
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.md b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.md
index d73a3d8..654585f 100644
--- a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.md
+++ b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.md
@@ -1,62 +1,1120 @@
autoscale: true
build-lists: true
-theme: poster, 7
+theme: next, 9
-![](title.png)
+![](images/title.png)
-# TDD - Test
Driven Drupal
+# [fit] TDD - Test
Driven Drupal
---
-agenda
+- PHP code
+- Mixture of D7 and D8
+- SimpleTest (D7)
+- PHPUnit (D8)
---
[.build-lists: false]
-![right](../../me-phpnw2.png)
-
-- Web Developer
-- System Administrator
- Senior Developer at Microserve
+- Contrib module maintainer
+- Occasional core contributor
+- Sticker collector and elePHPant herder
- @opdavies
- oliverdavies.uk
-^ - Acquia certified Drupal 8 Developer and Back-end Specialist
-- Drupal Bristol, PHPSW, DrupalCamp Bristol co-organiser
-- TDD, community, contribution advocate
+![right](../../me-phpnw.png)
---
-summary
+![inline fit](images/timmillwood-ono.png)
+
+
+^ 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.
---
-## Types of tests
+## Why Test?
+
+- Catch bugs earlier
+- Piece of mind
+- Prevent regressions
+- Write less code
+- Documentation
+- 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)
+Refer to tests when writing implementation code
+ONO merge conflict
+
+---
+
+## Why Not Test?
+
+- Don't know how
+- No time/budget to write tests
+
+^ "I'd love to write tests, but I don't have the time to learn."
+
+---
+
+## Core Testing Gate
+
+New features should be accompanied by automated tests.
+
+If the feature does not have an implementation, provide a test implementation.
+
+Bug fixes should be accompanied by changes to a test (either modifying an existing test case or adding a new one) that demonstrate the bug.
+
+[.footer: https://www.drupal.org/core/gates#testing]
+
+---
+
+## Testing in Drupal - SimpleTest
+
+- Based on
+- In D7 core
+- `*.test` files
+- All test classes in one file
+
+---
+
+## Testing in Drupal - PHPUnit
+
+- Used in other PHP projects (e.g. Symfony, Laravel)
+- In D8 core, but not default
+- `*.php` files
+- One test class per file
+
+---
+
+## The PHPUnit Initiative
+
+-
+- D8 core tests to change to PHPUnit
+- Deprecate SimpleTest, remove in D9
+- "A big chunk of old tests" converted on Feb 21st
+
+---
+
+## The PHPUnit Initiative
+
+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]
+
+---
+
+## Types of Tests
+### Unit Tests
+
+- `UnitTestCase`
+- Tests PHP logic
+- No database interaction
+- Fast to run
+
+---
+
+## Types of Tests
+### Unit Tests
+
+Pros:
+
+- Verify individual parts
+- Quickly find problems in code
+- Fast execution
+- No system setup for the test run
+
+---
+
+## Types of Tests
+### Unit Tests
+
+Cons:
+
+- Rewrite on every refactoring
+- Complicated mocking
+- No guarantee that the whole system actually works
+
+---
+
+## Types of Tests
+### 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]
+
+---
+
+## Types of Tests
+### Kernel Tests
+
+Pros:
+
+- Verify that components actually work together
+- Somewhat easy to locate bugs
+
+---
+
+## Types of Tests
+### Kernel Tests
+
+Cons:
+
+- Slower execution
+- System setup required
+- No guarantee that end user features actually work
+
+---
+
+
+## Types of Tests
+### Web/Functional/FunctionalJavascript Tests
+
+- `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
+
+![right 100%](images/tdd-circle-of-life.png)
+
+[.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)
+
+---
+
+[.hide-footer]
+
+```ini
+# example.info
+
+name = Example
+core = 7.x
+files[] = example.test
+```
+
+---
+
+[.hide-footer]
+
+```php
+// example.test
+
+class ExampleTestCase extends DrupalWebTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Example tests',
+ 'description' => 'Web tests for the example module.',
+ 'group' => 'Example',
+ );
+ }
+
+}
+```
+
+---
+
+[.hide-footer]
+
+```php
+class ExampleTestCase extends DrupalWebTestCase {
+
+ ...
+
+ public function testSomething {
+ $this->assertTrue(TRUE);
+ }
+
+}
+```
+
+---
+
+## Writing Tests (PHPUnit)
+
+- No need to load test classes expicitly.
+- Add classes into `tests/src` directory.
+- Extend `BrowserTestBase`.
+- No `getInfo` method.
+
+^ Classes get autoloaded PSR-4
+
+---
+
+[.hide-footer]
+
+## Creating the World
+
+```php
+public function setUp() {
+ // Enable any other required modules.
+ parent::setUp(['foo', 'bar']);
+
+ // Anything else we need to do.
+}
+```
+
+---
+
+[.hide-footer]
+
+## Creating the World
+
+```php
+$this->drupalCreateUser();
+
+$this->drupalLogin();
+
+$this->drupalCreateNode();
+
+$this->drupalLogout();
+```
+
+---
+
+## Assertions
+
+- `assertTrue`
+- `assertFalse`
+- `assertNull`
+- `assertNotNull`
+- `assertEqual`
+ `assertEquals`
+
+---
+
+## Assertions
+
+- `assertRaw`
+- `assertResponse`
+ `assertSession()->statusCodeEquals()`
+- `assertField`
+- `assertFieldById`
+- `assertTitle`
+
+---
+
+## [fit] Running Tests
+
+---
+
+## SimpleTest UI
+
+---
+
+![fit](images/simpletest-1.png)
+
+---
+
+![fit](images/simpletest-2.png)
+
+---
+
+![fit](images/simpletest-3.png)
+
+---
+
+![fit](images/simpletest-4.png)
+
+---
+
+## Running SimpleTest From The Command Line
+
+[.hide-footer]
+
+```bash
+# Drupal 7
+$ php scripts/run-tests.sh
+
+# Drupal 8
+$ php core/scripts/run-tests.sh
+```
+
+---
+
+[.hide-footer]
+
+## Running SimpleTest From The Command Line
+
+```bash
+--color
+
+--verbose
+
+--all
+
+--module
+
+--class
+
+--file
+```
+
+---
+
+[.hide-footer]
+
+## Running PHPUnit From The Command Line
+
+```bash
+$ vendor/bin/phpunit
+
+$ vendor/bin/phpunit [directory]
+
+$ vendor/bin/phpunit --filter [method]
+```
+
+---
+
+## Example: Collection Class
+
+---
+
+## Collection Class
+
+-
+- Adds a `Collection` class, based on Laravel’s
+- Provides helper methods for array methods
+- Drupal 7, uses xautoload
+
+^ xautoload gives PSR-4 namespaces and autoloading similar to Drupal 8.
+
+---
+
+[.hide-footer]
+
+```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();
+```
+
+---
+
+[.hide-footer]
+
+```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();
+ }
+
+ ...
+```
+
+---
+
+[.hide-footer]
+
+```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);
+}
+```
+
+---
+
+[.hide-footer]
+
+## Testing
+
+```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();
+}
+```
+
+---
+
+[.hide-footer]
+
+## Testing
+
+```php
+public function testCollectFunction() {
+ $this->assertEqual(
+ get_class($this->firstCollection),
+ 'Drupal\collection_class\Collection'
+ );
+}
+```
+
+---
+
+[.hide-footer]
+
+## Testing
+
+```php
+public function testAll() {
+ $this->assertEqual(
+ array('foo', 'bar', 'baz'),
+ $this->firstCollection->all()
+ );
+}
+```
+
+---
+
+[.hide-footer]
+
+## Testing
+
+```php
+public function testCount() {
+ $this->assertEqual(
+ 3,
+ $this->firstCollection->count()
+ );
+}
+```
+
+---
+
+[.hide-footer]
+
+## 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()
+ );
+}
+```
+
+---
+
+![fit](images/collection-class-1.png)
+
+---
+
+![fit](images/collection-class-2.png)
+
+---
+
+[.hide-footer]
+
+## 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
+
+![right 85%](images/toggle-optional-fields-button.png)
+
+---
+
+[.hide-footer]
+
+## Example
+
+```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
--
+[.hide-footer]
+
+```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_';
+}
+```
---
-## Functional Tests
+[.hide-footer]
--
+## Unit Tests
+
+```php
+$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')
+);
+```
---
-## Kernel Tests
-
-- New in Drupal 8
+![fit](images/toggle-optional-fields-1.png)
---
-feedback link
+[.hide-footer]
+
+## 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();
+}
+```
---
-## @opdavies
-## *oliverdavies.uk*
+[.hide-footer]
+
+## Custom Assertions
+
+```php
+private function assertTagsFieldNotHidden() {
+ $this->assertFieldByName(
+ 'field_tags[und]',
+ NULL,
+ t('Tags field visible.')
+ );
+}
+```
+
+---
+
+## Testing Hidden Fields
+
+[.hide-footer]
+
+```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();
+
+ ...
+```
+
+---
+
+[.hide-footer]
+
+## Testing Hidden Fields
+
+```php
+ ...
+
+ $this->drupalPost(
+ 'node/add/article',
+ array(),
+ t('Show optional fields')
+ );
+
+ $this->assertHideOptionalFieldsButtonFound();
+ $this->assertShowOptionalFieldsButtonNotFound();
+ $this->assertTagsFieldNotHidden();
+}
+```
+
+---
+
+![fit](images/toggle-optional-fields-2.png)
+
+---
+
+![fit](images/toggle-optional-fields-3.png)
+
+---
+
+## [fit] Building a new
D8 module
with TDD
+
+---
+
+As a site visitor
+
+I want to see a list of all published pages at `/pages`
+
+Ordered alphabetically by title.
+
+---
+
+```yml
+# dublintest.yml
+
+name: DrupalCamp Dublin test
+core: 8.x
+type: module
+```
+
+---
+
+```php
+// tests/src/Functional/ListingPageTest.php
+
+class ListingPageTest extends BrowserTestBase {
+
+ protected static $modules = ['dublintest'];
+
+ public function testListingPageExists() {
+ $this->drupalGet('pages');
+
+ $this->assertSession()->statusCodeEquals(200);
+ }
+}
+```
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests/
+E
+
+Time: 25.94 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) PageListTest::testListingPage
+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:130
+/var/www/modules/dublintest/tests/src/PageListTest.php:11
+```
+
+---
+
+- Add the view.
+- Copy the config into `config/install`.
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests/
+E
+
+Time: 19.07 seconds, Memory: 6.00MB
+
+There was 1 error:
+
+1) PageListTest::testListingPage
+Drupal\Core\Config\UnmetDependenciesException:
+Configuration objects provided by dublintest
+have unmet dependencies:
+node.type.page (node),
+views.view.pages (node, views)
+```
+
+---
+
+```yml
+name: DrupalCamp Dublin tests
+core: 8.x
+type: module
+
+dependencies:
+ - drupal:node
+ - drupal:views
+```
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests/
+.
+
+Time: 29.58 seconds, Memory: 6.00MB
+
+OK (1 test, 1 assertion)
+```
+
+---
+
+```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.
+}
+```
+
+---
+
+```php
+public function testOnlyPublishedPagesAreShown() {
+ $this->drupalCreateContentType(['type' => 'article']);
+
+ $this->drupalCreateNode(['type' => 'page', 'status' => TRUE]);
+
+ $this->drupalCreateNode(['type' => 'article']);
+
+ $this->drupalCreateNode(['type' => 'page', 'status' => FALSE]);
+
+ // When I view the pages list.
+
+ // I should only see the published pages.
+}
+```
+
+---
+
+```php
+public function testOnlyPublishedPagesAreShown() {
+ ...
+
+ $results = views_get_view_result('pages');
+
+ $nids = collect($results)->pluck('nid')->all();
+ // [1, 3]
+
+ // I should only see the published pages.
+}
+```
+
+---
+
+```php
+public function testOnlyPublishedPagesAreShown() {
+ ...
+
+ $results = views_get_view_result('pages');
+
+ $nids = collect($results)->pluck('nid')->all();
+ // [1, 3]
+
+ $this->assertEquals([1], $nids);
+}
+```
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+--filter=testOnlyPublishedPagesAreShown
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/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/core/tests/Drupal/Tests/BrowserTestBase.php:1240
+/var/www/modules/dublintest/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/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+--filter=testOnlyPublishedPagesAreShown
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests
+.
+
+Time: 26.53 seconds, Memory: 6.00MB
+
+OK (1 test, 3 assertions)
+```
+
+---
+
+```php
+public function testPagesAreOrderedAlphabetically() {
+ // Given I have multiple pages with different titles.
+
+ // When I view the pages list.
+
+ // I see the pages in the correct order.
+}
+```
+
+---
+
+```php
+public function testPagesAreOrderedAlphabetically() {
+ $this->drupalCreateNode(['title' => 'Page A']);
+ $this->drupalCreateNode(['title' => 'Page D']);
+ $this->drupalCreateNode(['title' => 'Page B']);
+ $this->drupalCreateNode(['title' => 'Page C']);
+
+ $results = views_get_view_result('pages');
+
+ $nids = collect($results)->pluck('nid')->all();
+
+ $this->assertEquals([1, 3, 4, 2], $nids);
+}
+```
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+-filter=testPagesAreOrderedAlphabetically
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests
+F
+
+Time: 28.03 seconds, Memory: 6.00MB
+
+There was 1 failure:
+```
+
+---
+
+```
+1) PageListTest::testPagesAreOrderedAlphabetically
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
+- 1 => 3
+- 2 => 4
+- 3 => 2
++ 0 => '1'
++ 1 => '2'
++ 2 => '3'
++ 3 => '4'
+ )
+
+/var/www/core/tests/Drupal/Tests/BrowserTestBase.php:1240
+/var/www/modules/dublintest/tests/src/PageListTest.php:36
+```
+
+---
+
+- Edit the view
+- Remove the default sort criteria (created on)
+- Add new sort criteria
+- Update the module config
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+--filter=testPagesAreOrderedAlphabetically
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests
+.
+
+Time: 27.67 seconds, Memory: 6.00MB
+
+OK (1 test, 2 assertions)
+```
+
+---
+
+```
+docker@cli:/var/www/core$ ../vendor/bin/phpunit ../modules/dublintest/tests
+PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
+
+Testing ../modules/dublintest/tests
+...
+
+Time: 1.17 minutes, Memory: 6.00MB
+
+OK (3 tests, 6 assertions)
+```
+
+---
+
+## Takeaways
+
+- Testing has made me a better developer
+- Testing can produce better quality code
+- 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
+Spending time writing tests pays dividends later on
+Start by introducing tests for new features or regression tests when fixing bugs
+If you know things pass, then you can refactor code knowing if something is broken
+Manual testing is still important
+
+---
+
+## Thanks!
+# Questions?
+### @opdavies
+### oliverdavies.uk
diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf
new file mode 100644
index 0000000..e0f910a
Binary files /dev/null and b/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf differ