Run prettier
This commit is contained in:
parent
49b98d0681
commit
81640d24ed
3
dist/getting-your-data-into-drupal-8/todo.md
vendored
3
dist/getting-your-data-into-drupal-8/todo.md
vendored
|
@ -1,4 +1,5 @@
|
|||
- Demonstrate plugins
|
||||
- Writing own source/process plugins
|
||||
- Core source plugins (Drupal to Drupal)
|
||||
- Demo `hook_migrate_prepare_row()` and `hook_migrate_MIGRATION_ID_prepare_row()`
|
||||
- Demo `hook_migrate_prepare_row()` and
|
||||
`hook_migrate_MIGRATION_ID_prepare_row()`
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
autoscale: true
|
||||
build-lists: true
|
||||
code: line-height(1.2)
|
||||
header-emphasis: #53B0EB
|
||||
text: alignment(left)
|
||||
theme: simple, 8
|
||||
autoscale: true build-lists: true code: line-height(1.2) header-emphasis:
|
||||
#53B0EB text: alignment(left) theme: simple, 8
|
||||
|
||||
# [fit] **Deploying PHP applications** <br>using Ansible, Ansible Vault <br>and Ansistrano
|
||||
|
||||
^ I work primarily with PHP, and there will be some PHP-isms in this talk (LAMP stack, Composer).
|
||||
Will be using a Drupal 8 application as the example, but the tools are tool and language agnostic.
|
||||
^ I work primarily with PHP, and there will be some PHP-isms in this talk (LAMP
|
||||
stack, Composer). Will be using a Drupal 8 application as the example, but the
|
||||
tools are tool and language agnostic.
|
||||
|
||||
---
|
||||
|
||||
|
@ -18,14 +15,13 @@ Will be using a Drupal 8 application as the example, but the tools are tool and
|
|||
|
||||
## **What we'll be looking at**
|
||||
|
||||
* **Ansible** crash course
|
||||
* Keeping secrets with **Ansible Vault**
|
||||
* Deployments with **Ansistrano**
|
||||
- **Ansible** crash course
|
||||
- Keeping secrets with **Ansible Vault**
|
||||
- Deployments with **Ansistrano**
|
||||
|
||||
---
|
||||
|
||||
[.build-lists: false]
|
||||
[.header: #111111]
|
||||
[.build-lists: false][.header: #111111]
|
||||
|
||||

|
||||
|
||||
|
@ -37,31 +33,28 @@ Will be using a Drupal 8 application as the example, but the tools are tool and
|
|||
- @opdavies
|
||||
- www.oliverdavies.uk
|
||||
|
||||
^ Maintain Drupal modules, PHP CLI tools and libraries, Ansible roles
|
||||
Blog on my website
|
||||
I work primarily with Drupal and Symfony
|
||||
I work for Inviqa, but this based on my personal and side projects.
|
||||
I've been using Ansible for a number of years, initially only for provisioning and setting up my laptop, and later for application deployments
|
||||
^ Maintain Drupal modules, PHP CLI tools and libraries, Ansible roles Blog on my
|
||||
website I work primarily with Drupal and Symfony I work for Inviqa, but this
|
||||
based on my personal and side projects. I've been using Ansible for a number of
|
||||
years, initially only for provisioning and setting up my laptop, and later for
|
||||
application deployments
|
||||
|
||||
---
|
||||
|
||||

|
||||

|
||||

|
||||
 
|
||||
|
||||
^ Large, well-known managed hosting companies
|
||||
Optimised servers for PHP/Drupal applications
|
||||
Include some sort of deployment system
|
||||
This workflow doesn't apply to this scenario
|
||||
^ Large, well-known managed hosting companies Optimised servers for PHP/Drupal
|
||||
applications Include some sort of deployment system This workflow doesn't apply
|
||||
to this scenario
|
||||
|
||||
---
|
||||
|
||||

|
||||

|
||||
 
|
||||

|
||||
|
||||
^ More applicable to virtual or dedicated servers with no existing deployment process
|
||||
Not enough budget for fully-managed, or using internal infrastructure
|
||||
^ More applicable to virtual or dedicated servers with no existing deployment
|
||||
process Not enough budget for fully-managed, or using internal infrastructure
|
||||
This is where the this workflow would be useful
|
||||
|
||||
---
|
||||
|
@ -82,17 +75,18 @@ This is where the this workflow would be useful
|
|||
|
||||
### **What is Ansible?**
|
||||
|
||||
* CLI tool
|
||||
* Written in Python
|
||||
* Configured with YAML
|
||||
* Executes ad-hoc remote commands
|
||||
* Installs software packages
|
||||
* Performs deployment steps
|
||||
* Batteries included
|
||||
- CLI tool
|
||||
- Written in Python
|
||||
- Configured with YAML
|
||||
- Executes ad-hoc remote commands
|
||||
- Installs software packages
|
||||
- Performs deployment steps
|
||||
- Batteries included
|
||||
|
||||
^ Written in Python but you don't need to write or know Python to use it
|
||||
Drupal, Symfony and a lot of other projects use YAML
|
||||
First-party modules (SSH keys, file and directory management, package repositories, stopping/starting/restarting services, DO/Linode/AWS integration)
|
||||
^ Written in Python but you don't need to write or know Python to use it Drupal,
|
||||
Symfony and a lot of other projects use YAML First-party modules (SSH keys, file
|
||||
and directory management, package repositories, stopping/starting/restarting
|
||||
services, DO/Linode/AWS integration)
|
||||
|
||||
---
|
||||
|
||||
|
@ -100,15 +94,15 @@ First-party modules (SSH keys, file and directory management, package repositori
|
|||
|
||||
### **What is Ansible?**
|
||||
|
||||
* Hosts/Inventories
|
||||
* Commands
|
||||
* Playbooks
|
||||
* Tasks
|
||||
* Roles
|
||||
- Hosts/Inventories
|
||||
- Commands
|
||||
- Playbooks
|
||||
- Tasks
|
||||
- Roles
|
||||
|
||||
^ Hosts: where your managed nodes/hosts are. Can be static or dynamic.
|
||||
Commands: run from a control node onto managed nodes
|
||||
Playbooks and Tasks: YAML representation of a series of commands/steps
|
||||
^ Hosts: where your managed nodes/hosts are. Can be static or dynamic. Commands:
|
||||
run from a control node onto managed nodes Playbooks and Tasks: YAML
|
||||
representation of a series of commands/steps
|
||||
|
||||
---
|
||||
|
||||
|
@ -116,17 +110,16 @@ Playbooks and Tasks: YAML representation of a series of commands/steps
|
|||
|
||||
### **Why Ansible?**
|
||||
|
||||
* Familiar syntax
|
||||
* Easily readable
|
||||
* No server dependencies
|
||||
* Easy to add to an existing project
|
||||
* Includes relevant modules (e.g. Composer)
|
||||
* Idempotency
|
||||
- Familiar syntax
|
||||
- Easily readable
|
||||
- No server dependencies
|
||||
- Easy to add to an existing project
|
||||
- Includes relevant modules (e.g. Composer)
|
||||
- Idempotency
|
||||
|
||||
^ Drupal 8, Symfony, Ansible all use YAML
|
||||
Runs on any server with Python
|
||||
Plugins into Drupal via CLI apps like Drush and Drupal Console
|
||||
Changes are only made when needed (once)
|
||||
^ Drupal 8, Symfony, Ansible all use YAML Runs on any server with Python Plugins
|
||||
into Drupal via CLI apps like Drush and Drupal Console Changes are only made
|
||||
when needed (once)
|
||||
|
||||
---
|
||||
|
||||
|
@ -175,7 +168,7 @@ webservers | SUCCESS => {
|
|||
|
||||
---
|
||||
|
||||
# `ansible all `<br>`-i hosts.yml `<br>`-m command `<br>`-a 'git pull `<br>`--chdir=/app'`
|
||||
# `ansible all`<br>`-i hosts.yml`<br>`-m command`<br>`-a 'git pull`<br>`--chdir=/app'`
|
||||
|
||||
---
|
||||
|
||||
|
@ -206,7 +199,7 @@ webservers | SUCCESS => {
|
|||
|
||||
---
|
||||
|
||||
# `ansible-playbook `<br>`playbook.yml -i hosts.yml`
|
||||
# `ansible-playbook`<br>`playbook.yml -i hosts.yml`
|
||||
|
||||
---
|
||||
|
||||
|
@ -313,7 +306,7 @@ ok: [webservers]
|
|||
TASK [geerlingguy.apache : Include OS-specific variables.] *************************************************************
|
||||
ok: [webservers]
|
||||
|
||||
TASK [geerlingguy.apache : Include variables for Amazon Linux.]
|
||||
TASK [geerlingguy.apache : Include variables for Amazon Linux.]
|
||||
skipping: [webservers]
|
||||
|
||||
TASK [geerlingguy.apache : Define apache_packages.] ********************************************************************
|
||||
|
@ -444,9 +437,9 @@ $ANSIBLE_VAULT;1.1;AES256
|
|||
```yaml
|
||||
# vars/vars.yml
|
||||
---
|
||||
database_name: "{{ vault_database_name }}"
|
||||
database_user: "{{ vault_database_user }}"
|
||||
database_password: "{{ vault_database_password }}"
|
||||
database_name: '{{ vault_database_name }}'
|
||||
database_user: '{{ vault_database_user }}'
|
||||
database_password: '{{ vault_database_password }}'
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -488,7 +481,7 @@ tasks:
|
|||
|
||||
- name: Uploading application
|
||||
synchronize:
|
||||
src: "{{ playbook_dir }}/../"
|
||||
src: '{{ playbook_dir }}/../'
|
||||
dest: /app
|
||||
|
||||
- name: Installing Composer dependencies
|
||||
|
@ -501,9 +494,9 @@ tasks:
|
|||
|
||||
# Disadvantages
|
||||
|
||||
* Single point of failure
|
||||
* No ability to roll back
|
||||
* Sensitive data stored in plain text
|
||||
- Single point of failure
|
||||
- No ability to roll back
|
||||
- Sensitive data stored in plain text
|
||||
|
||||
---
|
||||
|
||||
|
@ -513,20 +506,19 @@ tasks:
|
|||
|
||||

|
||||
|
||||
^ Just another role, specifically for deployments
|
||||
Ansible port of Capistrano
|
||||
^ Just another role, specifically for deployments Ansible port of Capistrano
|
||||
|
||||
---
|
||||
|
||||
# Features
|
||||
|
||||
* Multiple release directories
|
||||
* Shared paths and files
|
||||
* Customisable
|
||||
* Multiple deployment strategies
|
||||
* Multi-stage environments
|
||||
* Prune old releases
|
||||
* Rollbacks
|
||||
- Multiple release directories
|
||||
- Shared paths and files
|
||||
- Customisable
|
||||
- Multiple deployment strategies
|
||||
- Multi-stage environments
|
||||
- Prune old releases
|
||||
- Rollbacks
|
||||
|
||||
^ rsync, Git, SVN etc
|
||||
|
||||
|
@ -544,7 +536,6 @@ Ansible port of Capistrano
|
|||
|
||||
```yaml
|
||||
# deploy.yml
|
||||
|
||||
---
|
||||
- hosts: all
|
||||
|
||||
|
@ -557,14 +548,14 @@ Ansible port of Capistrano
|
|||
```yaml
|
||||
# deploy.yml
|
||||
---
|
||||
# ...
|
||||
vars:
|
||||
project_deploy_dir: /app
|
||||
# ...
|
||||
vars:
|
||||
project_deploy_dir: /app
|
||||
|
||||
ansistrano_deploy_to: '{{ project_deploy_dir }}'
|
||||
ansistrano_deploy_via: git
|
||||
ansistrano_git_branch: master
|
||||
ansistrano_git_repo: 'git@github.com:opdavies/dransible'
|
||||
ansistrano_deploy_to: '{{ project_deploy_dir }}'
|
||||
ansistrano_deploy_via: git
|
||||
ansistrano_git_branch: master
|
||||
ansistrano_git_repo: 'git@github.com:opdavies/dransible'
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -673,10 +664,9 @@ drwxr-xr-x 9 4096 Jul 22 20:30 20190722203038Z
|
|||
|
||||

|
||||
|
||||
^ Shared = files directory, logs
|
||||
Before/after symlink shared = run tests
|
||||
Symlink = 'current' symlink, site is live
|
||||
Clean up = remove node_modules, database export, sqlite testing DB
|
||||
^ Shared = files directory, logs Before/after symlink shared = run tests Symlink
|
||||
= 'current' symlink, site is live Clean up = remove node_modules, database
|
||||
export, sqlite testing DB
|
||||
|
||||
---
|
||||
|
||||
|
@ -685,16 +675,19 @@ Clean up = remove node_modules, database export, sqlite testing DB
|
|||
---
|
||||
# ...
|
||||
|
||||
ansistrano_after_symlink_shared_tasks_file: '{{ playbook_dir }}/deploy/after-symlink-shared.yml'
|
||||
ansistrano_after_symlink_tasks_file: '{{ playbook_dir }}/deploy/after-symlink.yml'
|
||||
ansistrano_after_update_code_tasks_file: '{{ playbook_dir }}/deploy/after-update-code.yml'
|
||||
ansistrano_after_symlink_shared_tasks_file:
|
||||
'{{ playbook_dir }}/deploy/after-symlink-shared.yml'
|
||||
ansistrano_after_symlink_tasks_file:
|
||||
'{{ playbook_dir }}/deploy/after-symlink.yml'
|
||||
ansistrano_after_update_code_tasks_file:
|
||||
'{{ playbook_dir }}/deploy/after-update-code.yml'
|
||||
|
||||
release_web_path: '{{ ansistrano_release_path.stdout }}/web'
|
||||
release_drush_path: '{{ ansistrano_release_path.stdout }}/vendor/bin/drush'
|
||||
```
|
||||
|
||||
^ Each step has a 'before' and 'after' step
|
||||
Ansistrano allows us to add more things by providing a path to a playbook and adding additional steps.
|
||||
^ Each step has a 'before' and 'after' step Ansistrano allows us to add more
|
||||
things by providing a path to a playbook and adding additional steps.
|
||||
|
||||
---
|
||||
|
||||
|
@ -722,7 +715,8 @@ Ansistrano allows us to add more things by providing a path to a playbook and ad
|
|||
# deploy/after-symlink.yml
|
||||
---
|
||||
- name: Clear Drupal cache
|
||||
command: '{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
|
||||
command:
|
||||
'{{ release_drush_path }} --root {{ release_web_path }} cache-rebuild'
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -741,7 +735,7 @@ Ansistrano allows us to add more things by providing a path to a playbook and ad
|
|||
vars:
|
||||
# ...
|
||||
ansistrano_shared_paths:
|
||||
- "{{ drupal_root }}/sites/default/files"
|
||||
- '{{ drupal_root }}/sites/default/files'
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -786,15 +780,16 @@ vault_database_user: user
|
|||
vault_database_password: secret
|
||||
vault_hash_salt: dfgiy$fd2!34gsf2*34g74
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```yaml
|
||||
# vars/vars.yml
|
||||
---
|
||||
database_name: "{{ vault_database_name }}"
|
||||
database_password: "{{ vault_database_password }}"
|
||||
database_user: "{{ vault_database_user }}"
|
||||
hash_salt: "{{ vault_hash_salt }}"
|
||||
database_name: '{{ vault_database_name }}'
|
||||
database_password: '{{ vault_database_password }}'
|
||||
database_user: '{{ vault_database_user }}'
|
||||
hash_salt: '{{ vault_hash_salt }}'
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -864,7 +859,9 @@ $base_url = '{{ item.1.settings.base_url }}';
|
|||
- name: Create settings files
|
||||
template:
|
||||
src: settings.php.j2
|
||||
dest: '{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{ item.1.filename|default("settings.php") }}'
|
||||
dest:
|
||||
'{{ item.0.drupal_root }}/sites/{{ item.1.name|default("default") }}/{{
|
||||
item.1.filename|default("settings.php") }}'
|
||||
with_subelements:
|
||||
- '{{ drupal_settings }}'
|
||||
- sites
|
||||
|
@ -874,6 +871,7 @@ $base_url = '{{ item.1.settings.base_url }}';
|
|||
---
|
||||
|
||||
# **Multiple environments**
|
||||
|
||||
## Dev, test, production
|
||||
|
||||
---
|
||||
|
@ -907,7 +905,7 @@ all:
|
|||
project_deploy_path: /app
|
||||
git_branch: master
|
||||
|
||||
drupal_hash_salt: "{{ vault_drupal_hash_salt }}"
|
||||
drupal_hash_salt: '{{ vault_drupal_hash_salt }}'
|
||||
drupal_install: true
|
||||
|
||||
drupal_settings:
|
||||
|
@ -928,7 +926,7 @@ all:
|
|||
project_deploy_path: /app-test
|
||||
git_branch: develop
|
||||
|
||||
drupal_hash_salt: "{{ vault_drupal_hash_salt }}"
|
||||
drupal_hash_salt: '{{ vault_drupal_hash_salt }}'
|
||||
drupal_install: true
|
||||
|
||||
drupal_settings:
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
autoscale: true
|
||||
build-lists: true
|
||||
header-emphasis: #3D85C6
|
||||
header: alignment(left)
|
||||
text: alignment(left)
|
||||
text-emphasis: #3D85C6
|
||||
theme: poster, 8
|
||||
autoscale: true build-lists: true header-emphasis: #3D85C6 header:
|
||||
alignment(left) text: alignment(left) text-emphasis: #3D85C6 theme: poster, 8
|
||||
code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5)
|
||||
|
||||
[.header: alignment(center)]
|
||||
|
@ -12,6 +7,7 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5)
|
|||

|
||||
|
||||
# [fit] Drupal Testing Workshop
|
||||
|
||||
### _September 2018_
|
||||
|
||||
---
|
||||
|
@ -32,15 +28,16 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.5)
|
|||
- Drupal core requirement - _<https://www.drupal.org/core/gates#testing>_
|
||||
- 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
|
||||
^ 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
|
||||
|
||||
---
|
||||
|
||||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _Having tests does not mean_
|
||||
|
||||
## [fit] there will be no bugs
|
||||
|
||||
---
|
||||
|
@ -48,6 +45,7 @@ ONO merge conflict
|
|||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _Testing may add time now_
|
||||
|
||||
## [fit] but save more time in the future
|
||||
|
||||
---
|
||||
|
@ -68,7 +66,7 @@ ONO merge conflict
|
|||
|
||||
- PHP class with _.php_ extension
|
||||
- _tests/src_ directory within each module
|
||||
- Within the *Drupal\Tests\module_name* namespace
|
||||
- Within the _Drupal\Tests\module_name_ namespace
|
||||
- Class name must match the filename
|
||||
- Namespace must match the directory structure
|
||||
- One test class per feature
|
||||
|
@ -79,6 +77,7 @@ ONO merge conflict
|
|||
---
|
||||
|
||||
### _Exercise 1_
|
||||
|
||||
## Local site setup
|
||||
|
||||
---
|
||||
|
@ -109,11 +108,13 @@ ONO merge conflict
|
|||
---
|
||||
|
||||
### _Exercise 2_
|
||||
|
||||
## Running Tests
|
||||
|
||||
---
|
||||
|
||||
### _Option 1_
|
||||
|
||||
## Simpletest module (UI)
|
||||
|
||||
---
|
||||
|
@ -147,6 +148,7 @@ ONO merge conflict
|
|||
---
|
||||
|
||||
### _Option 2_
|
||||
|
||||
## Command line
|
||||
|
||||
---
|
||||
|
@ -181,7 +183,7 @@ cd web/core
|
|||
|
||||
---
|
||||
|
||||
## Pro-tip: Add paths to _$PATH_
|
||||
## Pro-tip: Add paths to _\$PATH_
|
||||
|
||||
```bash
|
||||
# ~/.zshrc
|
||||
|
@ -196,6 +198,7 @@ export PATH=node_modules/.bin:$PATH
|
|||
---
|
||||
|
||||
### _Option 2_
|
||||
|
||||
## CLI with Docksal
|
||||
|
||||
---
|
||||
|
@ -223,6 +226,7 @@ cd web/core
|
|||
---
|
||||
|
||||
### _Option 3_
|
||||
|
||||
## Docksal PHPUnit addon
|
||||
|
||||
---
|
||||
|
@ -234,8 +238,7 @@ cd web/core
|
|||
- Copies a stub phpunit.xml file if exists, or duplicates phpunit.xml.dist
|
||||
- Shorter command, combines two actions
|
||||
|
||||
^ Checks for core/phpunit.xml on each test run
|
||||
Will create one if is not present
|
||||
^ Checks for core/phpunit.xml on each test run Will create one if is not present
|
||||
|
||||
---
|
||||
|
||||
|
@ -271,6 +274,7 @@ fin phpunit web/modules/contrib/examples/phpunit_example
|
|||
Copying /var/www/web/core/phpunit.xml.dist to /var/www/web/core/phpunit.xml.
|
||||
Please edit it's values as needed and re-run 'fin phpunit'.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
|
@ -290,6 +294,7 @@ OK (34 tests, 41 assertions)
|
|||
---
|
||||
|
||||
### _Option 4_
|
||||
|
||||
## IDE/text editor integration
|
||||
|
||||
---
|
||||
|
@ -317,8 +322,6 @@ OK (34 tests, 41 assertions)
|
|||
|
||||
---
|
||||
|
||||
|
||||
|
||||
[.header: #3D85C6]
|
||||
|
||||
## Functional tests
|
||||
|
@ -327,12 +330,12 @@ OK (34 tests, 41 assertions)
|
|||
- Easiest to start with
|
||||
- Provide most value
|
||||
|
||||
^ Less setup steps
|
||||
No mocking etc.
|
||||
^ Less setup steps No mocking etc.
|
||||
|
||||
---
|
||||
|
||||
### _Exercise_
|
||||
|
||||
## Let's write a <br>functional test
|
||||
|
||||
---
|
||||
|
@ -357,7 +360,6 @@ type: module
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// ExampleFunctionalTest.php
|
||||
|
||||
|
@ -393,10 +395,8 @@ public function test_example_page_exists() {
|
|||
}
|
||||
```
|
||||
|
||||
^ Snake case test method names
|
||||
Still works because it has the 'test' prefix
|
||||
More readable than camel case?
|
||||
Works with Simpletest/D7
|
||||
^ Snake case test method names Still works because it has the 'test' prefix More
|
||||
readable than camel case? Works with Simpletest/D7
|
||||
|
||||
---
|
||||
|
||||
|
@ -410,8 +410,7 @@ public function example_page_exists() {
|
|||
}
|
||||
```
|
||||
|
||||
^ Remove the prefix, use annotation
|
||||
PHPUnit only
|
||||
^ Remove the prefix, use annotation PHPUnit only
|
||||
|
||||
---
|
||||
|
||||
|
@ -541,6 +540,7 @@ OK (1 test, 3 assertions)
|
|||
---
|
||||
|
||||
### _Exercise_
|
||||
|
||||
## Let's write a <br>kernel test
|
||||
|
||||
---
|
||||
|
@ -692,6 +692,7 @@ OK (1 test, 5 assertions)
|
|||
---
|
||||
|
||||
### _Exercise_
|
||||
|
||||
## Let's write a <br>unit test
|
||||
|
||||
---
|
||||
|
@ -775,7 +776,6 @@ OK (1 test, 1 assertion)
|
|||
|
||||
---
|
||||
|
||||
|
||||
## _Test Driven Development_
|
||||
|
||||
- Write a failing test
|
||||
|
@ -785,8 +785,8 @@ OK (1 test, 1 assertion)
|
|||
|
||||
---
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.footer: https://github.com/foundersandcoders/testing-tdd-intro]
|
||||
[.background-color:
|
||||
#FFFFFF][.footer: https://github.com/foundersandcoders/testing-tdd-intro]
|
||||
[.footer-style: #2F2F2F]
|
||||
|
||||

|
||||
|
@ -804,8 +804,8 @@ OK (1 test, 1 assertion)
|
|||
---
|
||||
|
||||
### _Exercise_
|
||||
## Let's build a blog using test driven development
|
||||
|
||||
## Let's build a blog using test driven development
|
||||
|
||||
---
|
||||
|
||||
|
@ -828,12 +828,14 @@ OK (1 test, 1 assertion)
|
|||
## _Implementation_
|
||||
|
||||
- Use views module
|
||||
- Do the mininum amount at each step, make no assumptions, let the tests guide us
|
||||
- Do the mininum amount at each step, make no assumptions, let the tests guide
|
||||
us
|
||||
- Start with functional test
|
||||
|
||||
---
|
||||
|
||||
### _Step 1_
|
||||
|
||||
## Create the module
|
||||
|
||||
---
|
||||
|
@ -849,6 +851,7 @@ type: 'module'
|
|||
---
|
||||
|
||||
### _Step 2_
|
||||
|
||||
## Ensure the blog page exists
|
||||
|
||||
---
|
||||
|
@ -869,7 +872,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
public function testBlogPageExists() {
|
||||
$this->drupalGet('/blog');
|
||||
|
@ -880,7 +882,6 @@ public function testBlogPageExists() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
There was 1 error:
|
||||
|
||||
|
@ -937,7 +938,7 @@ id: blog
|
|||
|
||||
```
|
||||
1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
|
||||
Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided
|
||||
Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided
|
||||
by <em class="placeholder">tdd_blog</em>
|
||||
have unmet dependencies: <em class="placeholder">views.view.blog
|
||||
(node.type.article, node, views)</em>
|
||||
|
@ -945,7 +946,6 @@ have unmet dependencies: <em class="placeholder">views.view.blog
|
|||
|
||||
---
|
||||
|
||||
|
||||
```yml,[.highlight: 1, 7-10]
|
||||
# tdd_blog.info.yml
|
||||
|
||||
|
@ -961,10 +961,9 @@ dependencies:
|
|||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists
|
||||
Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided
|
||||
Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided
|
||||
by <em class="placeholder">tdd_blog</em> have unmet dependencies:
|
||||
<em class="placeholder">views.view.blog (node.type.article)</em>
|
||||
```
|
||||
|
@ -975,7 +974,6 @@ by <em class="placeholder">tdd_blog</em> have unmet dependencies:
|
|||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
OK (1 test, 3 assertions)
|
||||
```
|
||||
|
@ -993,11 +991,11 @@ OK (1 test, 3 assertions)
|
|||
---
|
||||
|
||||
### _Step 3_
|
||||
|
||||
## Ensure only published articles are shown
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
public function testOnlyPublishedArticlesAreShown() {
|
||||
// Given I have a mixture of published and unpublished articles,
|
||||
|
@ -1012,11 +1010,11 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
---
|
||||
|
||||
### _Option 1_
|
||||
|
||||
## Functional tests
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1043,11 +1041,11 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
---
|
||||
|
||||
### _Option 2_
|
||||
|
||||
## Kernel tests
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
namespace Drupal\Tests\tdd_blog\Kernel;
|
||||
|
||||
|
@ -1074,10 +1072,8 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
}
|
||||
```
|
||||
|
||||
^ Kernel test approach
|
||||
Dropping down a level
|
||||
No need for the brower, not asserting against HTML
|
||||
Faster to run
|
||||
^ Kernel test approach Dropping down a level No need for the brower, not
|
||||
asserting against HTML Faster to run
|
||||
|
||||
---
|
||||
|
||||
|
@ -1156,7 +1152,8 @@ Failed asserting that actual size 2 matches expected size 1.
|
|||
|
||||
---
|
||||
|
||||
>- _There is no content type filter on the view_
|
||||
> - _There is no content type filter on the view_
|
||||
|
||||
- Add the filter
|
||||
- Re-export and save the view
|
||||
|
||||
|
@ -1183,11 +1180,11 @@ OK (1 test, 6 assertions)
|
|||
---
|
||||
|
||||
### _Step 4_
|
||||
|
||||
## Ensure the articles are ordered by date
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -1202,7 +1199,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -1232,7 +1228,6 @@ $this->createNode([
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -1267,7 +1262,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -1281,7 +1275,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
There was 1 failure:
|
||||
|
||||
|
@ -1346,14 +1339,14 @@ OK (1 test, 5 assertions)
|
|||
- 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.
|
||||
- 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
|
||||
^ 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
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Having fun with Drupal 8, PHP libraries Drupal.org API
|
||||
# Having fun with Drupal 8, PHP libraries Drupal.org API
|
||||
|
||||
- Open slides
|
||||
- Open Chrome tabs
|
||||
- Open PhpStorm for all projects
|
||||
- Open Sequel Pro for both DBs
|
||||
+ Clear cache tables
|
||||
- Clear cache tables
|
||||
- Start PHP server for each site
|
||||
- Start recording
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
|
||||
- Show in PhpStorm
|
||||
- Show readme with examples
|
||||
+ Run test.php
|
||||
- Run test.php
|
||||
- Show query classes
|
||||
+ Not drupal coding standards (PSR-2)
|
||||
+ Explain laravel collections
|
||||
- Not drupal coding standards (PSR-2)
|
||||
- Explain laravel collections
|
||||
- Show entity classes
|
||||
- Show tests
|
||||
+ Show fake query classes
|
||||
- Show fake query classes
|
||||
- Run tests
|
||||
|
||||
## Project statistics
|
||||
|
@ -26,18 +26,18 @@
|
|||
- Show /projects page
|
||||
- Show routing
|
||||
- Show ProjectController
|
||||
+ Using PHP 7 return types
|
||||
+ Explain dependency injection
|
||||
+ Explain about collection
|
||||
+ Explain render array
|
||||
+ Show how to change ordering
|
||||
- Using PHP 7 return types
|
||||
- Explain dependency injection
|
||||
- Explain about collection
|
||||
- Explain render array
|
||||
- Show how to change ordering
|
||||
- Show ProjectRetriever
|
||||
+ More dependency injection
|
||||
+ Show services file
|
||||
- More dependency injection
|
||||
- Show services file
|
||||
- Show settings form
|
||||
- Add another module (Sophie's simple integrations?)
|
||||
+ See it loading on projects page
|
||||
+ See it cached
|
||||
- See it loading on projects page
|
||||
- See it cached
|
||||
|
||||
## Drupalversary
|
||||
|
||||
|
@ -45,18 +45,18 @@
|
|||
- Show block
|
||||
- Show block form
|
||||
- Show accountretriever
|
||||
+ Highlight caching
|
||||
+ Services file
|
||||
+ Show cached items in the DB
|
||||
- Highlight caching
|
||||
- Services file
|
||||
- Show cached items in the DB
|
||||
- Show routing
|
||||
- Show UserController
|
||||
+ More dependency injection
|
||||
+ Services file
|
||||
- More dependency injection
|
||||
- Services file
|
||||
- Show date parser
|
||||
+ Show drupalversary model
|
||||
- Show drupalversary model
|
||||
- Show adding own username via form
|
||||
+ See it cached
|
||||
+ Show adding uid via form
|
||||
+ See it cached
|
||||
- See it cached
|
||||
- Show adding uid via form
|
||||
- See it cached
|
||||
- Show Dries' because this year drupalversary has passed
|
||||
- Try with attendee ID
|
||||
- Try with attendee ID
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
autoscale: true
|
||||
theme: Plain Jane, 1
|
||||
autoscale: true theme: Plain Jane, 1
|
||||
|
||||
# **Taking Flight with <br>Tailwind CSS**
|
||||
|
||||
|
@ -36,10 +35,8 @@ Going to be using Tailwind 1.0 which was released recently (May 13th)
|
|||
|
||||
# A **utility-first** CSS framework for rapidly building **custom designs**.
|
||||
|
||||
^ CSS utility class generator
|
||||
PostCSS
|
||||
Make different looking sites using the same class names
|
||||
No "Tailwind looking site" like there is with Bootstrap
|
||||
^ CSS utility class generator PostCSS Make different looking sites using the
|
||||
same class names No "Tailwind looking site" like there is with Bootstrap
|
||||
|
||||
---
|
||||
|
||||
|
@ -47,11 +44,9 @@ No "Tailwind looking site" like there is with Bootstrap
|
|||
|
||||
# Tailwind CSS is a **highly customizable**, **low-level** CSS framework
|
||||
|
||||
^ No components like Bootstrap or Bulma
|
||||
Configure it per project
|
||||
Extendable if needed via additional plugins
|
||||
Avoids the need to name things prematurely
|
||||
Can extract components if needed (reusability)
|
||||
^ No components like Bootstrap or Bulma Configure it per project Extendable if
|
||||
needed via additional plugins Avoids the need to name things prematurely Can
|
||||
extract components if needed (reusability)
|
||||
|
||||
---
|
||||
|
||||
|
@ -59,8 +54,10 @@ Can extract components if needed (reusability)
|
|||
|
||||
# Tailwind is more than a CSS framework, it's an engine for <br>**creating design systems**.
|
||||
|
||||
^ Good default values provided - colours, fonts, padding, widths
|
||||
Designing with constraints. Using inline styles, every value is a magic number. With utilities, you're choosing styles from a predefined design system, which makes it much easier to build visually consistent UIs.
|
||||
^ Good default values provided - colours, fonts, padding, widths Designing with
|
||||
constraints. Using inline styles, every value is a magic number. With utilities,
|
||||
you're choosing styles from a predefined design system, which makes it much
|
||||
easier to build visually consistent UIs.
|
||||
|
||||
---
|
||||
|
||||
|
@ -106,15 +103,22 @@ Designing with constraints. Using inline styles, every value is a magic number.
|
|||
---
|
||||
|
||||
## **Benefits**
|
||||
|
||||
- You aren't wasting time and energy inventing class names
|
||||
- Your CSS stops growing
|
||||
- Making changes feels safer
|
||||
|
||||
^ No more adding silly class names like sidebar-inner-wrapper just to be able to style something, and no more agonizing over the perfect abstract name for something that's really just a flex container.
|
||||
^ No more adding silly class names like sidebar-inner-wrapper just to be able to
|
||||
style something, and no more agonizing over the perfect abstract name for
|
||||
something that's really just a flex container.
|
||||
|
||||
^ Using a traditional approach, your CSS files get bigger every time you add a new feature. With utilities, everything is reusable so you rarely need to write new CSS.
|
||||
^ Using a traditional approach, your CSS files get bigger every time you add a
|
||||
new feature. With utilities, everything is reusable so you rarely need to write
|
||||
new CSS.
|
||||
|
||||
^ CSS is global and you never know what you're breaking when you make a change. Classes in your HTML are local, so you can change them without worrying about something else breaking.
|
||||
^ CSS is global and you never know what you're breaking when you make a change.
|
||||
Classes in your HTML are local, so you can change them without worrying about
|
||||
something else breaking.
|
||||
|
||||
---
|
||||
|
||||
|
@ -219,8 +223,9 @@ Designing with constraints. Using inline styles, every value is a magic number.
|
|||
## **To get the most out of Tailwind, <br>you really should install it via npm.**
|
||||
|
||||
^ - You can't customize Tailwind's default theme
|
||||
- You can't use any directives like *@apply*, *@variants*, etc.
|
||||
- You can't enable features like *group-hover*
|
||||
|
||||
- You can't use any directives like _@apply_, _@variants_, etc.
|
||||
- You can't enable features like _group-hover_
|
||||
- You can't install third-party plugins
|
||||
|
||||
---
|
||||
|
@ -244,9 +249,7 @@ Designing with constraints. Using inline styles, every value is a magic number.
|
|||
[.code-highlight: 2-7]
|
||||
|
||||
```css
|
||||
# src/css/style.css
|
||||
|
||||
@tailwind base;
|
||||
#src/css/style.css @tailwind base;
|
||||
|
||||
@tailwind components;
|
||||
|
||||
|
@ -277,8 +280,7 @@ Designing with constraints. Using inline styles, every value is a magic number.
|
|||
|
||||
## **Processing your CSS with Tailwind <br>with the build command**
|
||||
|
||||
^ Compile the generated CSS
|
||||
Pass through PostCSS and Tailwind
|
||||
^ Compile the generated CSS Pass through PostCSS and Tailwind
|
||||
|
||||
---
|
||||
|
||||
|
@ -288,19 +290,19 @@ Pass through PostCSS and Tailwind
|
|||
|
||||
```css
|
||||
.text-left {
|
||||
text-align: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-justify {
|
||||
text-align: justify;
|
||||
text-align: justify;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -317,9 +319,7 @@ Pass through PostCSS and Tailwind
|
|||
```js
|
||||
const mix = require('laravel-mix')
|
||||
|
||||
mix.postCss('src/css/app.css', 'dist/css', [
|
||||
require('tailwindcss')()
|
||||
])
|
||||
mix.postCss('src/css/app.css', 'dist/css', [require('tailwindcss')()])
|
||||
```
|
||||
|
||||
^ PostCSS - useful if you're including other PostCSS plugins like PostCSS Nested
|
||||
|
@ -331,8 +331,7 @@ const mix = require('laravel-mix')
|
|||
|
||||
require('laravel-mix-tailwind')
|
||||
|
||||
mix.postCss('src/css/app.css', 'dist/css')
|
||||
.tailwind()
|
||||
mix.postCss('src/css/app.css', 'dist/css').tailwind()
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -341,13 +340,11 @@ mix.postCss('src/css/app.css', 'dist/css')
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta charset="UTF-8" />
|
||||
<title>My new website</title>
|
||||
<link rel="stylesheet" href="/dist/css/app.css">
|
||||
<link rel="stylesheet" href="/dist/css/app.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
<body></body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
@ -359,10 +356,10 @@ mix.postCss('src/css/app.css', 'dist/css')
|
|||
|
||||
# `npm run prod`
|
||||
|
||||
|
||||
---
|
||||
|
||||
# **Interaction states**
|
||||
|
||||
## hover, focus, group-hover, focus-within
|
||||
|
||||
^ Start to differ from inline styles
|
||||
|
@ -371,9 +368,9 @@ mix.postCss('src/css/app.css', 'dist/css')
|
|||
|
||||
# `.[state][separator][class]`
|
||||
|
||||
^ State = hover, focus, group focus, focus within
|
||||
Separator = configurable, colon by default
|
||||
Class = the same utility class that you would have used normally
|
||||
^ State = hover, focus, group focus, focus within Separator = configurable,
|
||||
colon by default Class = the same utility class that you would have used
|
||||
normally
|
||||
|
||||
---
|
||||
|
||||
|
@ -594,11 +591,10 @@ colors: {
|
|||
```js
|
||||
const mix = require('laravel-mix')
|
||||
|
||||
mix.postCss('src/css/site.css', 'dist/css')
|
||||
.purgeCss({
|
||||
folders: ['templates'],
|
||||
extensions: ['html', 'php', 'twig']
|
||||
})
|
||||
mix.postCss('src/css/site.css', 'dist/css').purgeCss({
|
||||
folders: ['templates'],
|
||||
extensions: ['html', 'php', 'twig'],
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -610,14 +606,14 @@ const mix = require('laravel-mix')
|
|||
|
||||
require('laravel-mix-purgecss')
|
||||
|
||||
mix.postCss('src/css/site.css', 'dist/css')
|
||||
.purgeCss({
|
||||
folders: ['templates'],
|
||||
extensions: ['html', 'php', 'twig']
|
||||
})
|
||||
mix.postCss('src/css/site.css', 'dist/css').purgeCss({
|
||||
folders: ['templates'],
|
||||
extensions: ['html', 'php', 'twig'],
|
||||
})
|
||||
```
|
||||
|
||||
^ Can be tricky using Drupal/WordPress as you don't know where the classes could be coming from, no generated output directory
|
||||
^ Can be tricky using Drupal/WordPress as you don't know where the classes could
|
||||
be coming from, no generated output directory
|
||||
|
||||
---
|
||||
|
||||
|
@ -631,9 +627,7 @@ mix.postCss('src/css/site.css', 'dist/css')
|
|||
|
||||
# Could the duplication <br>**be moved elsewhere**?
|
||||
|
||||
^ Twig partials
|
||||
Vue components
|
||||
WordPress template parts
|
||||
^ Twig partials Vue components WordPress template parts
|
||||
|
||||
---
|
||||
|
||||
|
@ -672,8 +666,8 @@ WordPress template parts
|
|||
} %}
|
||||
```
|
||||
|
||||
^ Move the duplicate markup into a partial, so there's only one version
|
||||
Pass data in.
|
||||
^ Move the duplicate markup into a partial, so there's only one version Pass
|
||||
data in.
|
||||
|
||||
---
|
||||
|
||||
|
@ -689,9 +683,8 @@ a.btn:hover {
|
|||
}
|
||||
```
|
||||
|
||||
^ Use utilities as mixins
|
||||
Copy classes from markup
|
||||
Still re-using the same design system and constraints as before
|
||||
^ Use utilities as mixins Copy classes from markup Still re-using the same
|
||||
design system and constraints as before
|
||||
|
||||
---
|
||||
|
||||
|
@ -730,12 +723,13 @@ a.btn:hover {
|
|||
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {}
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
variants: {}
|
||||
variants: {},
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[.code-highlight: 5-7]
|
||||
|
@ -746,12 +740,12 @@ module.exports = {
|
|||
module.exports = {
|
||||
theme: {
|
||||
colors: {
|
||||
inherit: 'inherit'
|
||||
inherit: 'inherit',
|
||||
},
|
||||
extend: {}
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
variants: {}
|
||||
variants: {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -768,12 +762,12 @@ module.exports = {
|
|||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
inherit: 'inherit'
|
||||
}
|
||||
}
|
||||
inherit: 'inherit',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
variants: {}
|
||||
variants: {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -790,10 +784,10 @@ module.exports = {
|
|||
prefix: '',
|
||||
important: false,
|
||||
theme: {
|
||||
extend: {}
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
variants: {}
|
||||
variants: {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -818,12 +812,10 @@ module.exports = {
|
|||
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {}
|
||||
extend: {},
|
||||
},
|
||||
plugins: [
|
||||
require('tailwindcss-list-reset')()
|
||||
],
|
||||
variants: {}
|
||||
plugins: [require('tailwindcss-list-reset')()],
|
||||
variants: {},
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -841,13 +833,16 @@ module.exports = {
|
|||
```js
|
||||
// index.js
|
||||
|
||||
module.exports = (variants) => ({ addUtilities }) => {
|
||||
addUtilities({
|
||||
'.list-reset': {
|
||||
listStyle: 'none',
|
||||
padding: 0
|
||||
}
|
||||
}, variants)
|
||||
module.exports = variants => ({addUtilities}) => {
|
||||
addUtilities(
|
||||
{
|
||||
'.list-reset': {
|
||||
listStyle: 'none',
|
||||
padding: 0,
|
||||
},
|
||||
},
|
||||
variants,
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -874,10 +869,11 @@ module.exports = (variants) => ({ addUtilities }) => {
|
|||
---
|
||||
|
||||
# **Thanks!**
|
||||
|
||||
# opdavi.es/talks/tailwind
|
||||
|
||||
## _@opdavies_ <br>_oliverdavies.uk_
|
||||
|
||||
^ Find this talk at opdavi.es/talks/tailwind
|
||||
Follow me on Twitter
|
||||
oliverdavies.uk where I blog about PHP, Drupal, Symfony, automated testing, Tailwind etc.
|
||||
Subscribe to the RSS feed
|
||||
^ Find this talk at opdavi.es/talks/tailwind Follow me on Twitter
|
||||
oliverdavies.uk where I blog about PHP, Drupal, Symfony, automated testing,
|
||||
Tailwind etc. Subscribe to the RSS feed
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
theme: poster, 8
|
||||
autoscale: true
|
||||
build-lists: true
|
||||
header-emphasis: #53B0EB
|
||||
header: alignment(left)
|
||||
text: alignment(left)
|
||||
text-emphasis: #53B0EB
|
||||
code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3)
|
||||
theme: poster, 8 autoscale: true build-lists: true header-emphasis: #53B0EB
|
||||
header: alignment(left) text: alignment(left) text-emphasis: #53B0EB code:
|
||||
Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3)
|
||||
|
||||
[.header: alignment(center)]
|
||||
|
||||
|
@ -41,10 +36,8 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3)
|
|||
|
||||
---
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.build-lists: false]
|
||||
[.header: #111111]
|
||||
[.text: #111111, alignment(left)]
|
||||
[.background-color: #FFFFFF][.build-lists: false] [.header:
|
||||
#111111][.text: #111111, alignment(left)]
|
||||
|
||||

|
||||
|
||||
|
@ -57,9 +50,8 @@ code: Monaco, #6699FF, #999999, #6666FF, #66FF66, #66FF66, line-height(1.3)
|
|||
- @opdavies
|
||||
- www.oliverdavies.uk
|
||||
|
||||
^ Work at Microserve.
|
||||
Maintain Drupal modules, PHP CLI tools and libraries
|
||||
Blog on my website
|
||||
^ Work at Microserve. Maintain Drupal modules, PHP CLI tools and libraries Blog
|
||||
on my website
|
||||
|
||||
---
|
||||
|
||||
|
@ -74,8 +66,7 @@ Blog on my website
|
|||
|
||||
---
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.text: #111111, alignment(left)]
|
||||
[.background-color: #FFFFFF][.text: #111111, alignment(left)]
|
||||
|
||||

|
||||
|
||||
|
@ -89,10 +80,9 @@ Blog on my website
|
|||
|
||||
[.header: alignment(center)]
|
||||
|
||||
## test_driven_drupal_.com_
|
||||
## test*driven_drupal*.com\_
|
||||
|
||||
^ Book on automated testing in Drupal 8
|
||||
Building a conference website
|
||||
^ Book on automated testing in Drupal 8 Building a conference website
|
||||
|
||||
---
|
||||
|
||||
|
@ -129,12 +119,13 @@ Building a conference website
|
|||
- Become maintainer in 2012
|
||||
- Had some existing tests
|
||||
- Used on _11,046 sites_ in October 2012 (_84_ D5, _7,094_ D6, _3,868_ D7)
|
||||
- Used on _30,572 sites_ in March 2019 (_10_ D5, _1,180_ D6, _24,057_ D7, _5,335_ D8)
|
||||
- Used on _30,572 sites_ in March 2019 (_10_ D5, _1,180_ D6, _24,057_ D7,
|
||||
_5,335_ D8)
|
||||
- _#230_ most used module on Drupal.org
|
||||
- Crucial to preventing regressions
|
||||
|
||||
^ Preventing regressions when adding new features or fixing bugs, but also user submitted patches
|
||||
First module I ported to Drupal 8, aided by tests
|
||||
^ Preventing regressions when adding new features or fixing bugs, but also user
|
||||
submitted patches First module I ported to Drupal 8, aided by tests
|
||||
|
||||
---
|
||||
|
||||
|
@ -154,9 +145,9 @@ First module I ported to Drupal 8, aided by tests
|
|||
- Drupal core requirement - _<https://www.drupal.org/core/gates#testing>_
|
||||
- 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
|
||||
^ 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
|
||||
|
||||
---
|
||||
|
||||
|
@ -164,7 +155,8 @@ ONO merge conflict
|
|||
|
||||
- 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.
|
||||
- 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://opdavi.es/drupal-core-testing-gate]
|
||||
|
||||
|
@ -194,7 +186,7 @@ ONO merge conflict
|
|||
|
||||
- PHP class with _.php_ extension
|
||||
- _tests/src_ directory within each module
|
||||
- Within the *Drupal\Tests\module_name* namespace
|
||||
- Within the _Drupal\Tests\module_name_ namespace
|
||||
- Class name must match the filename
|
||||
- Namespace must match the directory structure
|
||||
- One test class per feature
|
||||
|
@ -206,7 +198,9 @@ ONO merge conflict
|
|||
[.header: alignment(center)]
|
||||
|
||||
## _1._ Arrange
|
||||
|
||||
## _2._ Act
|
||||
|
||||
## _3._ Assert
|
||||
|
||||
---
|
||||
|
@ -214,7 +208,9 @@ ONO merge conflict
|
|||
[.header: alignment(center)]
|
||||
|
||||
## _3._ Assert
|
||||
|
||||
## _2._ Act
|
||||
|
||||
## _1._ Arrange
|
||||
|
||||
---
|
||||
|
@ -239,11 +235,8 @@ class ExampleTest extends BrowserTestBase {
|
|||
}
|
||||
```
|
||||
|
||||
^ PHP class
|
||||
Filename matches class name
|
||||
Namespace matches directory structure
|
||||
Extend BrowserTestBase
|
||||
Add test method
|
||||
^ PHP class Filename matches class name Namespace matches directory structure
|
||||
Extend BrowserTestBase Add test method
|
||||
|
||||
---
|
||||
|
||||
|
@ -282,8 +275,8 @@ public function it_does_something() {}
|
|||
- What provides the most value to the client?
|
||||
- What would you not like to be fixing on a Friday afternoon or after hours?
|
||||
|
||||
^ Payments! Anything related to money.
|
||||
What would provide the largest negative impact to the client if it were to fail?
|
||||
^ Payments! Anything related to money. What would provide the largest negative
|
||||
impact to the client if it were to fail?
|
||||
|
||||
---
|
||||
|
||||
|
@ -293,7 +286,6 @@ What would provide the largest negative impact to the client if it were to fail?
|
|||
|
||||
---
|
||||
|
||||
|
||||
[.header: #53B0EB]
|
||||
|
||||
## What to test first?
|
||||
|
@ -301,10 +293,9 @@ What would provide the largest negative impact to the client if it were to fail?
|
|||
- Write a _new test_ when adding any _new functionality_
|
||||
- Write a _regression test_ when _fixing a bug_
|
||||
|
||||
^ Use tests to replicate the bug
|
||||
Could be a new test, or adding to an existing test
|
||||
Test passes when the bug is fixed
|
||||
That issue cannot be re-added without the test failing again
|
||||
^ Use tests to replicate the bug Could be a new test, or adding to an existing
|
||||
test Test passes when the bug is fixed That issue cannot be re-added without the
|
||||
test failing again
|
||||
|
||||
---
|
||||
|
||||
|
@ -352,9 +343,8 @@ class JobTest extends UnitTestCase {
|
|||
}
|
||||
```
|
||||
|
||||
^ Within a Unit directory and namespace
|
||||
Called JobTest because it's testing the Job class
|
||||
Called testCreate because it's testing the create method
|
||||
^ Within a Unit directory and namespace Called JobTest because it's testing the
|
||||
Job class Called testCreate because it's testing the create method
|
||||
|
||||
---
|
||||
|
||||
|
@ -404,8 +394,7 @@ class JobTest extends UnitTestCase {
|
|||
}
|
||||
```
|
||||
|
||||
^ Retrieve data from the object with getters
|
||||
Asssert that the data is correct.
|
||||
^ Retrieve data from the object with getters Asssert that the data is correct.
|
||||
|
||||
---
|
||||
|
||||
|
@ -539,8 +528,8 @@ protected function setUp() {
|
|||
}
|
||||
```
|
||||
|
||||
^ Because it's a kernel test, we have access to the container
|
||||
to get the AdvancedQueue processor service.
|
||||
^ Because it's a kernel test, we have access to the container to get the
|
||||
AdvancedQueue processor service.
|
||||
|
||||
---
|
||||
|
||||
|
@ -627,9 +616,7 @@ public function testProcessor() {
|
|||
- Slower to run
|
||||
- With/without JavaScript
|
||||
|
||||
^ testing profile
|
||||
Functional/FunctionalJavascript
|
||||
Nightwatch
|
||||
^ testing profile Functional/FunctionalJavascript Nightwatch
|
||||
|
||||
---
|
||||
|
||||
|
@ -666,8 +653,8 @@ protected function setUp() {
|
|||
}
|
||||
```
|
||||
|
||||
^ We have the ability to place blocks
|
||||
And create users with permissions and log them in
|
||||
^ We have the ability to place blocks And create users with permissions and log
|
||||
them in
|
||||
|
||||
---
|
||||
|
||||
|
@ -710,6 +697,7 @@ public function testQueueDeletion() {
|
|||
```
|
||||
|
||||
---
|
||||
|
||||
```php, [.highlight: 12-14]
|
||||
// tests/src/Functional/QueueTest.php
|
||||
|
||||
|
@ -761,21 +749,25 @@ public function testQueueDeletion() {
|
|||
[.header: #FFFFFF, alignment(left)]
|
||||
|
||||
### _How do I know_
|
||||
|
||||
## Which type of test to use?
|
||||
|
||||
---
|
||||
|
||||
### _Need a browser?_
|
||||
|
||||
## Use a functional test
|
||||
|
||||
---
|
||||
|
||||
### _Interact with other services?_
|
||||
|
||||
## Use a kernel test
|
||||
|
||||
---
|
||||
|
||||
### _Isolated PHP code?_
|
||||
|
||||
## Use a unit test
|
||||
|
||||
---
|
||||
|
@ -786,9 +778,9 @@ public function testQueueDeletion() {
|
|||
|
||||
## _Or should you test_ <br>your render array to generate the block?
|
||||
|
||||
^ The answer might be 'both'.
|
||||
The right type of test to use might not be that obvious.
|
||||
You may be able to use a different type of test if you take a different approach.
|
||||
^ The answer might be 'both'. The right type of test to use might not be that
|
||||
obvious. You may be able to use a different type of test if you take a different
|
||||
approach.
|
||||
|
||||
---
|
||||
|
||||
|
@ -876,8 +868,7 @@ statusCodeNotEquals()
|
|||
|
||||
---
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.footer-style: #2F2F2F]
|
||||
[.background-color: #FFFFFF][.footer-style: #2f2f2f]
|
||||
|
||||

|
||||
|
||||
|
@ -892,7 +883,8 @@ statusCodeNotEquals()
|
|||
- Jobs need to be linked to offices
|
||||
- Job 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
|
||||
- Application URL constructed from domain, includes role ID as a GET parameter
|
||||
and optionally UTM parameters
|
||||
|
||||
---
|
||||
|
||||
|
@ -941,9 +933,10 @@ $data = [
|
|||
|
||||
- Added route to accept data from API as XML
|
||||
- Added system 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*
|
||||
- _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_
|
||||
|
||||
---
|
||||
|
||||
|
@ -954,8 +947,7 @@ $data = [
|
|||
- If no error, create the job node, return OK response to Broadbean
|
||||
- If an Exception is thrown, return an error code and message
|
||||
|
||||
^ Required field missing
|
||||
Incorrect branch name
|
||||
^ Required field missing Incorrect branch name
|
||||
|
||||
---
|
||||
|
||||
|
@ -975,9 +967,12 @@ Incorrect branch name
|
|||
## 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)
|
||||
- _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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -998,6 +993,7 @@ Incorrect branch name
|
|||
---
|
||||
|
||||
### _Option 1_
|
||||
|
||||
## SimpleTest module (UI)
|
||||
|
||||
---
|
||||
|
@ -1031,6 +1027,7 @@ Incorrect branch name
|
|||
---
|
||||
|
||||
### _Option 2_
|
||||
|
||||
## Core script
|
||||
|
||||
---
|
||||
|
@ -1046,6 +1043,7 @@ $ php core/scripts/run-tests.sh --class ExampleTest
|
|||
---
|
||||
|
||||
### _Option 3_
|
||||
|
||||
## PHPUnit
|
||||
|
||||
---
|
||||
|
@ -1103,8 +1101,8 @@ fin addon install phpunit
|
|||
fin phpunit modules/custom
|
||||
```
|
||||
|
||||
^ Copies a stub phpunit.xml file or copies phpunit.xml.dist
|
||||
Runs the phpunit command within the correct directory
|
||||
^ Copies a stub phpunit.xml file or copies phpunit.xml.dist Runs the phpunit
|
||||
command within the correct directory
|
||||
|
||||
---
|
||||
|
||||
|
@ -1133,8 +1131,8 @@ Runs the phpunit command within the correct directory
|
|||
|
||||
---
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.footer: https://github.com/foundersandcoders/testing-tdd-intro]
|
||||
[.background-color:
|
||||
#FFFFFF][.footer: https://github.com/foundersandcoders/testing-tdd-intro]
|
||||
[.footer-style: #2F2F2F]
|
||||
|
||||

|
||||
|
@ -1174,6 +1172,7 @@ Runs the phpunit command within the correct directory
|
|||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _Building a new Drupal 8 Module with_
|
||||
|
||||
## [fit] test driven development
|
||||
|
||||
---
|
||||
|
@ -1203,12 +1202,14 @@ Runs the phpunit command within the correct directory
|
|||
## Implementation
|
||||
|
||||
- Use views module
|
||||
- Do the mininum amount at each step, make no assumptions, let the tests guide us
|
||||
- Do the mininum amount at each step, make no assumptions, let the tests guide
|
||||
us
|
||||
- Start with functional test
|
||||
|
||||
---
|
||||
|
||||
### _Step 1_
|
||||
|
||||
## Create the module
|
||||
|
||||
---
|
||||
|
@ -1224,6 +1225,7 @@ type: 'module'
|
|||
---
|
||||
|
||||
### _Step 2_
|
||||
|
||||
## Ensure the blog page exists
|
||||
|
||||
---
|
||||
|
@ -1250,7 +1252,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 3]
|
||||
// tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1273,7 +1274,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 5-7]
|
||||
// tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1296,7 +1296,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 9]
|
||||
// tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1319,7 +1318,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 11-15]
|
||||
// tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1342,7 +1340,6 @@ class BlogPageTest extends BrowserTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```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.
|
||||
|
@ -1367,7 +1364,6 @@ Tests: 1, Assertions: 3, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```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.
|
||||
|
@ -1392,7 +1388,6 @@ Tests: 1, Assertions: 3, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```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.
|
||||
|
@ -1417,7 +1412,6 @@ Tests: 1, Assertions: 3, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```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.
|
||||
|
@ -1442,7 +1436,6 @@ Tests: 1, Assertions: 3, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```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.
|
||||
|
@ -1542,7 +1535,6 @@ Tests: 1, Assertions: 0, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```yml,[.highlight: 1, 7-10]
|
||||
# tdd_blog.info.yml
|
||||
|
||||
|
@ -1558,7 +1550,6 @@ dependencies:
|
|||
|
||||
---
|
||||
|
||||
|
||||
```[.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.
|
||||
|
@ -1593,7 +1584,6 @@ Tests: 1, Assertions: 0, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```[.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.
|
||||
|
@ -1619,11 +1609,11 @@ OK (1 test, 3 assertions)
|
|||
---
|
||||
|
||||
### _Step 3_
|
||||
|
||||
## Ensure only published articles are shown
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
public function testOnlyPublishedArticlesAreShown() {
|
||||
// Given I have a mixture of published and unpublished articles,
|
||||
|
@ -1638,11 +1628,11 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
---
|
||||
|
||||
### _Option 1_
|
||||
|
||||
## Functional tests
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php,[.highlight: 1, 4-8]
|
||||
// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1668,7 +1658,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php,[.highlight: 10-12]
|
||||
// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1692,7 +1681,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 13-17]
|
||||
// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php
|
||||
|
||||
|
@ -1717,11 +1705,11 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
---
|
||||
|
||||
### _Option 2_
|
||||
|
||||
## Kernel tests
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
namespace Drupal\Tests\tdd_blog\Kernel;
|
||||
|
||||
|
@ -1743,10 +1731,8 @@ class BlogPageTest extends EntityKernelTestBase {
|
|||
}
|
||||
```
|
||||
|
||||
^ Kernel test approach
|
||||
Dropping down a level
|
||||
No need for the brower, not asserting against HTML
|
||||
Faster to run
|
||||
^ Kernel test approach Dropping down a level No need for the brower, not
|
||||
asserting against HTML Faster to run
|
||||
|
||||
---
|
||||
|
||||
|
@ -1819,7 +1805,6 @@ class BlogPageTest extends EntityKernelTestBase {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```[.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.
|
||||
|
@ -1844,7 +1829,6 @@ Tests: 1, Assertions: 2, Errors: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 2]
|
||||
public function testOnlyPublishedArticlesAreShown() {
|
||||
$this->installConfig(['filter']);
|
||||
|
@ -1857,7 +1841,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 8]
|
||||
public function testOnlyPublishedArticlesAreShown() {
|
||||
$this->installConfig(['filter']);
|
||||
|
@ -1872,7 +1855,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 3]
|
||||
...
|
||||
|
||||
|
@ -1894,7 +1876,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 6]
|
||||
...
|
||||
|
||||
|
@ -1916,7 +1897,6 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 8-15]
|
||||
...
|
||||
|
||||
|
@ -1936,13 +1916,11 @@ public function testOnlyPublishedArticlesAreShown() {
|
|||
}
|
||||
```
|
||||
|
||||
^ Assert
|
||||
Should only be one result, should be node 2
|
||||
Node IDs are reset on each test method
|
||||
^ Assert Should only be one result, should be node 2 Node IDs are reset on each
|
||||
test method
|
||||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
|
||||
|
||||
|
@ -1964,7 +1942,6 @@ Tests: 1, Assertions: 4, Failures: 1.
|
|||
|
||||
---
|
||||
|
||||
|
||||
```[.highlight: 8-13]
|
||||
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
|
||||
|
||||
|
@ -1990,7 +1967,8 @@ Tests: 1, Assertions: 4, Failures: 1.
|
|||
|
||||
---
|
||||
|
||||
>- _There is no content type filter on the view_
|
||||
> - _There is no content type filter on the view_
|
||||
|
||||
- Add the filter
|
||||
- Re-export and save the view
|
||||
|
||||
|
@ -2024,11 +2002,11 @@ OK (1 test, 6 assertions)
|
|||
---
|
||||
|
||||
### _Step 4_
|
||||
|
||||
## Ensure the articles are ordered by date
|
||||
|
||||
---
|
||||
|
||||
|
||||
```php
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -2043,7 +2021,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 4-9]
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -2073,7 +2050,6 @@ $this->createNode([
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 10-11]
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -2116,7 +2092,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```php, [.highlight: 5-9, 17-18]
|
||||
// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php
|
||||
|
||||
|
@ -2141,7 +2116,6 @@ public function testArticlesAreOrderedByDate() {
|
|||
|
||||
---
|
||||
|
||||
|
||||
```
|
||||
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
|
||||
|
||||
|
@ -2255,8 +2229,7 @@ OK (1 test, 5 assertions)
|
|||
|
||||

|
||||
|
||||
^ Using the minimal installation profile
|
||||
Post 3 is unpublished
|
||||
^ Using the minimal installation profile Post 3 is unpublished
|
||||
|
||||
---
|
||||
|
||||
|
@ -2277,45 +2250,49 @@ Post 3 is unpublished
|
|||
- 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.
|
||||
- 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
|
||||
^ 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
|
||||
|
||||
---
|
||||
|
||||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _Having tests does not mean_
|
||||
|
||||
## [fit] there will be no bugs
|
||||
|
||||
^ Only means that the tests you wrote are passing
|
||||
You may not have included a certain use case
|
||||
Be sure to test in the UI!
|
||||
We can test what happens in a test when a user has a permission, but in our site we still need to assign the permission to a role and the role to a user.
|
||||
^ Only means that the tests you wrote are passing You may not have included a
|
||||
certain use case Be sure to test in the UI! We can test what happens in a test
|
||||
when a user has a permission, but in our site we still need to assign the
|
||||
permission to a role and the role to a user.
|
||||
|
||||
---
|
||||
|
||||
### _You might be testing the wrong thing_
|
||||
|
||||
## Maybe it doesn't work the way you think it does
|
||||
|
||||
---
|
||||
|
||||
### _Have you written enough assertions?_
|
||||
|
||||
## Have you only covered the 'happy path' scenarios?
|
||||
|
||||
^ If your tests are passing but there is an issue, maybe you haven't written enough assertions
|
||||
Be sure to check for the negative use cases too
|
||||
Check that something is not included as well as what should be included
|
||||
What if you pass in an incorrect value?
|
||||
^ If your tests are passing but there is an issue, maybe you haven't written
|
||||
enough assertions Be sure to check for the negative use cases too Check that
|
||||
something is not included as well as what should be included What if you pass in
|
||||
an incorrect value?
|
||||
|
||||
---
|
||||
|
||||
### _Other modules can affect things_
|
||||
|
||||
## Tests may pass, but fail when other modules are enabled
|
||||
|
||||
---
|
||||
|
@ -2323,6 +2300,7 @@ What if you pass in an incorrect value?
|
|||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _Testing may add time now_
|
||||
|
||||
## [fit] but save more time in the future
|
||||
|
||||
---
|
||||
|
@ -2330,20 +2308,21 @@ What if you pass in an incorrect value?
|
|||
[.header: alignment(center)]
|
||||
|
||||
## [fit] _How do you get quicker at writing tests?_
|
||||
|
||||
# [fit] By writing more tests
|
||||
|
||||
^ Practice makes perfect
|
||||
Become more familar with and knowledge of recurring errors
|
||||
Find better practices and approaches. Different base classes? Less setup steps. Less time, more productive.
|
||||
^ Practice makes perfect Become more familar with and knowledge of recurring
|
||||
errors Find better practices and approaches. Different base classes? Less setup
|
||||
steps. Less time, more productive.
|
||||
|
||||
---
|
||||
|
||||
## _Start small_
|
||||
|
||||
## Some tests are better than no tests
|
||||
|
||||
---
|
||||
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
|
||||

|
||||
|
@ -2371,5 +2350,7 @@ Find better practices and approaches. Different base classes? Less setup steps.
|
|||
[.header: alignment(center)]
|
||||
|
||||
# Thanks
|
||||
|
||||
### _@opdavies_
|
||||
|
||||
### _oliverdavies.uk_
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
- Show composer.json setup
|
||||
- Add "things you can test" and "things you shouldn't test"
|
||||
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
theme: poster, 8
|
||||
autoscale: true
|
||||
build-lists: true
|
||||
header-emphasis: #53B0EB
|
||||
header: alignment(left)
|
||||
text: alignment(left)
|
||||
text-emphasis: #53B0EB
|
||||
code: Operator Mono, line-height(1.5)
|
||||
theme: poster, 8 autoscale: true build-lists: true header-emphasis: #53B0EB
|
||||
header: alignment(left) text: alignment(left) text-emphasis: #53B0EB code:
|
||||
Operator Mono, line-height(1.5)
|
||||
|
||||
[.background-color: #FFFFFF]
|
||||
[.hide-footer]
|
||||
[.header: #111111, alignment(center)]
|
||||
[.background-color: #FFFFFF][.hide-footer] [.header: #111111, alignment(center)]
|
||||
|
||||
## Using Laravel Collections... <br>Outside Laravel
|
||||
|
||||
|
@ -21,12 +14,11 @@ code: Operator Mono, line-height(1.5)
|
|||
|
||||
## Collections :thumbsup:
|
||||
|
||||
^ Became a fan of Collections whilst learning Laravel
|
||||
Powerful object orientated way to interact with arrays
|
||||
Store items within the collection, run methods, chainable
|
||||
More readable, less temporary variables
|
||||
Video on Laracasts, Adam Wathan's refactoring to Collections
|
||||
Wanted to use them with different PHP projects e.g. Drupal
|
||||
^ Became a fan of Collections whilst learning Laravel Powerful object orientated
|
||||
way to interact with arrays Store items within the collection, run methods,
|
||||
chainable More readable, less temporary variables Video on Laracasts, Adam
|
||||
Wathan's refactoring to Collections Wanted to use them with different PHP
|
||||
projects e.g. Drupal
|
||||
|
||||
---
|
||||
|
||||
|
@ -36,15 +28,13 @@ collect(['foo', 'bar']); // ['foo', 'bar']
|
|||
collect('foobar'); // ['foobar']
|
||||
|
||||
$object = new stdClass();
|
||||
$object->foo = 'bar';
|
||||
$object->foo = 'bar';
|
||||
collect($object); // ['foo' => 'bar']
|
||||
collect($object)->get('foo'); // bar
|
||||
```
|
||||
|
||||
^ How do you make a collection?
|
||||
collect function is provided
|
||||
String, array or object
|
||||
Stored as items within the Collection object
|
||||
^ How do you make a collection? collect function is provided String, array or
|
||||
object Stored as items within the Collection object
|
||||
|
||||
---
|
||||
|
||||
|
@ -68,10 +58,9 @@ $collection->filter(function ($item) {
|
|||
}); // [3, 4]
|
||||
```
|
||||
|
||||
^ Once you have a collection, what can you do with it?
|
||||
"contains" - no more needle/haystack, haystack/needle
|
||||
"filter" - filters false, null values
|
||||
Can pass callbacks to `first` and `filter`, return true or false as needed.
|
||||
^ Once you have a collection, what can you do with it? "contains" - no more
|
||||
needle/haystack, haystack/needle "filter" - filters false, null values Can pass
|
||||
callbacks to `first` and `filter`, return true or false as needed.
|
||||
|
||||
---
|
||||
|
||||
|
@ -96,12 +85,12 @@ $collection->filter(function ($person) {
|
|||
|
||||

|
||||
|
||||
^ This is great, but how can I do that in my Drupal code?
|
||||
How can I do that?
|
||||
^ This is great, but how can I do that in my Drupal code? How can I do that?
|
||||
|
||||
---
|
||||
|
||||
## There’s a module for that!
|
||||
|
||||
### _- Drupalers_
|
||||
|
||||
---
|
||||
|
@ -109,6 +98,7 @@ How can I do that?
|
|||
[.text: alignment(center)]
|
||||
|
||||
## [fit] There's not a module for that. :disappointed:
|
||||
|
||||
### _- Me_
|
||||
|
||||
---
|
||||
|
@ -119,12 +109,11 @@ How can I do that?
|
|||
|
||||
---
|
||||
|
||||
|
||||
### _Version 1.0_
|
||||
|
||||
## Write my own Collection class
|
||||
|
||||
^ Wrote my own Collection class
|
||||
Wrote my own tests
|
||||
^ Wrote my own Collection class Wrote my own tests
|
||||
|
||||
---
|
||||
|
||||
|
@ -140,13 +129,14 @@ Wrote my own tests
|
|||
|
||||
---
|
||||
|
||||
|
||||
### Collect - Illuminate Collections as a separate package.
|
||||
|
||||
#### _https://packagist.org/packages/tightenco/collect_
|
||||
|
||||
---
|
||||
|
||||
### Import Laravel's Collections into non-Laravel packages easily, without needing to require the entire Illuminate\Support package.
|
||||
|
||||
#### _https://packagist.org/packages/tightenco/collect_
|
||||
|
||||
---
|
||||
|
@ -162,6 +152,7 @@ Wrote my own tests
|
|||
## _composer require_<br>tightenco/collect
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
@ -171,6 +162,7 @@ Wrote my own tests
|
|||
---
|
||||
|
||||
### _Version 2.0_
|
||||
|
||||
## Use someone else’s Collection class
|
||||
|
||||
^ More fully featured, less code to maintain
|
||||
|
@ -215,9 +207,8 @@ $collection->each(function ($item) {
|
|||
});
|
||||
```
|
||||
|
||||
^ Require/include autoload.php
|
||||
Start using Collections!
|
||||
`collect` function is autoloaded
|
||||
^ Require/include autoload.php Start using Collections! `collect` function is
|
||||
autoloaded
|
||||
|
||||
---
|
||||
|
||||
|
@ -242,5 +233,7 @@ Start using Collections!
|
|||
[.header: alignment(center)]
|
||||
|
||||
# Thanks!
|
||||
|
||||
### _@opdavies_
|
||||
|
||||
### _oliverdavies.uk_
|
||||
|
|
Loading…
Reference in a new issue