Testing
- Who tests stuff?
- Manual testing?
- Simpletest?
- PHPUnit?
- Behat?
- Why do you not do it?
Daniel Wehner
- Drupal Core contributor
- Chapter Three, Tag1 Consulting ...
- Curios person
We are ignorant
* The daily life is hard as we are incredible stupid.
It worked when I tested it
Things work on one computer but not on the other, maybe some additional stuff has to be installed / build?
It worked last month
Things that used to work break at some point. We want to reduce the amount of them ...
The code is too slow, let's fix that
We often write really slow code, which is sort of fine, as most of the time we don't need to scale. At some
point though we potentially need to scale/fix that code. How do we ensure that things still work?
More problems
- Sites get more complex
- New members comes into the team
- Everyone wants to be able to sleep at night
* Sites get more and more complex over time
* Not a single person knows everything ... how do you document how stuff is supposed to work?
... for when members come into a team there should be a way for them to figure it out.
* Finally we want to not worry about the state, everything should be nice.
* Other points: You should be able to iterate more quickly when you no, nothing breaks.
Let's test
End-to-end testing
Unit testing
End-to-end testing tests the entire system, not just a small aspect of it.
End-to-end testing
-
Behat + Selenium
- CasperJS
- Drupal BrowserTestBase | JavascriptTestBase (new in Drupal 8.1)
Behat: documentation of the test, client language => tests for free ;;;
CasperJS: in JS => easier testing of JS ;;;
There is plenty of documentation out there for the other ones.
BrowserTestBase|JavscripTestBase: Tools by Drupal ... written in PHP;
Sets up the complete Drupal + the module you want to test.
Focus on JTB, as it will be useful when you write modules; port stuff.
Browser Test
- Based upon PHPUnit / Mink
- New since Drupal 8
- Execute via command line or PHPStorm
* Installs a fresh drupal
* Installs some modules
* advantage over simpletest: you can run it via phpstorm ...
Browser Test
// modules/example/tests/src/Function/ExampleTest.php
class ExampleTest extends BrowserTestBase {
public static $modules = ['example'];
/**
* Tests basic page test.
*/
public function testGoTo() {
$account = $this->drupalCreateUser();
$this->drupalLogin($account);
// Visit a Drupal page that requires login.
$this->drupalGet('test-page');
$this->assertSession()->statusCodeEquals(200);
// Test page contains some text.
$this->assertSession()->pageTextContains('Test page text.');
}
}
Basic actions
- ::setup()
- drupalGet
- drupalPostForm
- clickLink
More useful stuff
- drupalCreateUser
drupalLogin
drupalLogout
- drupalCreateNode
use \Behat\Mink\WebAssert;
$this->webAssert = new WebAssert($this->getSession());
$this->webAssert->statusCodeEquals(200);
$this->webAssert->pageTextContains('The content was saved.');
$this->webAssert->elementsCount('css', 'div.views ul li', 3);
$this->webAssert->fieldExists('title[0][value]');
$this->webAssert->checkboxNotChecked('published');
JavascriptTestBase
Static sites so far ;;
Want to test javascript ;;
You need sort of a browser ;;
We use phantomjs ;;
based upon webkit, is headless for itself ;;
Still take screenshots
JavascriptTestBase
// modules/toolbar/tests/src/
// FunctionalJavascript/ToolbarIntegrationTest.php
class ToolbarIntegrationTest extends JavascriptTestBase {
public static $modules = ['toolbar', 'node'];
public function testToolbarToggling() {
$this->drupalLogin($admin);
$this->drupalGet('< front>');
$this->assertElementVisible('#toolbar-link-admin_content');
$this->click('#toolbar-item-administration');
$this->assertElementNotVisible('#toolbar-link-admin_content');
}
}
Blog post about running javascript tests
Run them
phantomjs --ssl-protocol=any --ignore-ssl-errors=true \\
vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768
SIMPLETEST_BASE_URL="http://drupal.loc"
SIMPLETEST_DB="sqlite://localhost/sites/default/files/.ht.sqlite"
$ sudo -u _www ./vendor/bin/phpunit -c core core/modules/toolbar/\\
tests/src/FunctionalJavascript/ToolbarIntegrationTest.php
Time: 10.25 seconds, Memory: 5.50Mb
Run them all
sudo -u _www ./vendor/bin/phpunit -c core modules/example/tests/src
Problems with end to end testing
Problems with end to end testing
- Tests too much
- Slow
- Error prone
- Feedback cycle
For a given input expect a given output.
Tools
- Qunit
- Jasmine
- Mocha
- Karma
- Chai
- Tape
- more ...
- even more ... ?
Step 0: Think about the problem
TodoTxt
x 2016-04-18 Finish JS testing presentation @dcampEs +js +testing
Step 1: Define a test
// test/todo-parser.js
var assert = require('chai').assert;
var TodoParser = require('../todo-parser');
describe('todo-parser', function() {
describe('parse', function() {
it('parses a simple string', function() {
var todo = TodoParser.parse('hello');
assert.isOk(todo);
assert.equal('hello', todo.text);
});
});
});
Step 2: Make the test pass
// todo-parser.js
TodoParser = {
parse(string) {
var text = string;
return new Todo(text);
}
};
// todo.js
Todo = function(text) {
this.text = text;
};
Step 3: Write another test
it('parse string with priority', function() {
var todo = TodoParser.parse('(A) hello');
assert.isOk(todo);
assert.equal('hello', todo.text);
assert.equal('A', todo.priority);
});
Test driven development (TDD)
This kind of testin gis called TDD ...
Test driven development (TDD)
- Code is testable
- Code is tested
- Code is easy to use
- Less premature optimization
- Uncle Bob
Mocha
- Testing framework
- No assertions/mocking
- Runs in the shell
{
"name": "My project",
"devDependencies": {
"mocha": "^2.4.5",
"chai": "^3.5.0"
},
"scripts": {
"test": "node_modules/mocha/bin/mocha",
"test-watch": "node_modules/mocha/bin/mocha --watch"
}
}
--watch
-R --reporter min,json,xunit,nyan
Chai
- Assertion library
- Different flavours:
- Expect
expect(todo.text).to.equal('hello');
expect(todo.priority)
.to.not.equal('A');
expect(todo)
.to.have.property('text')
.and.not.equal('hola');
- Should
todo.text.should.equal('hello');
todo.priority.should.not.equal(A');
todo.should.have.property('text');
- Assert
assert.equal('hello', todo.text);
assert.notEqual('A', todo.priority);
assert.property(todo, 'text');
Mocking
- Fake external code (libraries, databases, etc.)
- Just test your code
- Shows code with too many dependencies
- Sinon is a good library for that
Your projects
Start with testing now, there is no excuse. Behat/CasperJS are good tools.
Module authors should use BTB/JTB for their stuff.
Drupal
- You can start using it now. Just add a package.json with the dependencies, run npm install and do it.
- There is a core issue ...
- Many open questions:
- Do we want those testing libraries?
- Do we want to run them in the browser?
- Other ideas
Testing
Who tests stuff?
Manual testing?
Simpletest?
PHPUnit?
Behat?
Why do you not do it?