front-end automated testing
DESCRIPTION
Actually testing is as important as development and we all want to write code that works. So, why not test our front-end code? To do that we can use some tools as Selenium, Jasmine but I will explain QUnit because it's used in Drupal8 testing. QUnit is a powerful, easy-to-use JavaScript unit testing framework. It's used by the jQuery, jQuery UI, jQuery Mobile projects, also by Drupal, and is capable of testing any generic JavaScript code. Session presented at Drupalcamp Gotemburg 2013 where I explained how to include QUnit testing in our Drupal projects.TRANSCRIPT
Front-end Automated TestingFront-end Automated Testing#drupal-fat#drupal-fat
I don't know what I like
more: Drupal or Beer
@rteijeiro
Ruben TeijeiroRuben Teijeiro
@rteijeiro
Web DevelopmentWeb Development
I'm configuring the server. It will be ready in a few weeks.
Dev OpsDev Ops
WTF!!
This design is really fancy. I made it shiny and edgy. Now it pops!!
DesignersDesigners
So what?
Content ManagersContent Managers
In-place Content Authoring
Holy shit!
We want something like Facebook, but we need it yesterday.
And banners with kittens. Everyone loves kittens.
We should use Comic Sans, it's such a fancy and funny font.
CustomersCustomers
OMG!!
BrowsersBrowsers
CSSCSS
I said "float: left"!!!
RefactoringRefactoring
Fixed Fixed Fixed
Fixed
Fixed Fixed
Fixed
Final ResultFinal Result
And now I will show you how it looks in Internet Explorer 7
Nowwhat?!!
FATFAT
Front-end Automated TestingFront-end Automated Testing
Because people likes code that works
Continuous IntegrationContinuous Integration
● Automated
● Repeteable
● Easy to understand
● Incremental
● Easy to run
● Fast
Unit TestUnit Test
● QUnit
● Selenium
● Jasmine
● PhantomJS
● YUI Test
Testing ToolsTesting Tools
QUnitQUnit
getInfo: function() {
return {
name: 'Drupal Test',
description: 'My first Drupal test',
group: 'Tests'
};
}
Test ConfigurationTest Configuration
Test ConfigurationTest Configuration
setup: function() {
this.bbq = "Put some bacon here...";
}
Test ConfigurationTest Configuration
teardown: function() {
this.bbq = "More bacon for the bbq.";
}
● ok● equal● notEqual● deepEqual● notDeepEqual● strictEqual● notStrictEqual● throws
AssertionsAssertions
this.bbq = true;
QUnit.ok(this.bbq,
Drupal.t('We have barbecue.'));
QUnit.okQUnit.ok
this.bbq = 'Bacon';
QUnit.equal(this.bbq, 'Bacon',
Drupal.t('This is a Bacon Barbecue'));
QUnit.equalQUnit.equal
this.bbq = 'Bacon';
QUnit.notEqual(this.bbq, 'Chicken',
Drupal.t('This is not a Chicken Barbecue'));
QUnit.notEqualQUnit.notEqual
this.bbq = { meat: 'Bacon' };
QUnit.deepEqual(this.bbq, {meat: 'Bacon' },
Drupal.t('This is a Bacon Barbecue'));
QUnit.deepEqualQUnit.deepEqual
this.bbq = { meat: 'Chicken' };
QUnit.notDeepEqual(this.bbq, {meat: 'Bacon' },
Drupal.t('This is not a Bacon Barbecue'));
QUnit.notDeepEqualQUnit.notDeepEqual
this.bbq = 'Bacon';
QUnit.strictEqual(this.bbq, 'Bacon',
Drupal.t('This is a Bacon Barbecue'));
QUnit.strictEqualQUnit.strictEqual
this.bbq = 5;
QUnit.notStrictEqual(this.bbq, '5',
Drupal.t('This is not a Barbecue for 5'));
QUnit.notStrictEqualQUnit.notStrictEqual
throws(
function() {
throw "No barbecue."
},
"There is no barbecue."
);
QUnit.throwsQUnit.throws
Synchronous CallbacksSynchronous Callbacks
QUnit.expect(3);
this.bbq = 'Bacon';
QUnit.ok(this.bbq = 'Bacon', Drupal.t('Bacon barbecue.'));
QUnit.equal(this.bbq, 'Bacon', Drupal.t('Bacon barbecue.'));
QUnit.deepEqual(this.bbq, 'Bacon', Drupal.t('Bacon barbecue.'));
Asynchronous CallbacksAsynchronous Callbacks
var delay = 1000;
this.bbq = 'Bacon';
QUnit.stop();
setTimeout( function() {
QUnit.ok(this.bbq == 'Bacon', Drupal.t('1 second barbecue.');
QUnit.start();
}, delay);
Testing User ActionsTesting User Actions
this.bbq.val('Bacon').trigger('keyup');
QUnit.ok(this.bbq.val == 'Bacon',
Drupal.t('Barbecue with keyup.'));
ResourcesResources
http://drupal.org/project/fat
TestSwarmTestSwarm
http://drupal.org/project/testswarm
BrowserStackBrowserStack
http://www.browserstack.com
DemoDemo