testing 101
TRANSCRIPT
Testing 123 101Mike Francis@_mikefrancis
Who likes fixing bugs?
Put your bloody hand down.
Exactly 💁
Development without testing
Inefficient
Expensive
Human reliant
“Known unknowns”
Development with testing
Efficient
Autonomous
Confident
Safe
WTF is testing?
“Software testing involves the execution of a software component or system component to evaluate one or more properties of interest.”
“Software testing involves the execution of a software component or system component to evaluate one or more properties of interest.”
Software Testing
Plethora of testing frameworks for each language
Usually run from the command line
Can be configured
Split into suites
WTF do I test?
What should I test?
●Everything!
●Only what you “own”
●The “critical path”
User stories help!
In order to buy products
As a customer
I need to be able to put interesting products into a basket
Testing Fundamentals
●Arrange
●Act
●Assert
Testing Suitesor “Folders”
Testing SuitesUnit
Unit
1. Here’s some code I wrote
2. I give it these values
3. These other things get called
4. I check this is the response/signature
Unit
var MyService = require('./myService');
var assert = require('assert');
it('Checks that a query string can be parsed into an object', function () {
// ARRANGE
var myService = new MyService();
// ACT
var obj = myService.parse('a=c');
// ASSERT
assert.equal(obj, { a: 'c' });
});
Test Doubles
When you might need a double:
Your tests rely on an internet connection (calling an external API)
You’re using the filesystem
You have complex dependencies
You are sending an email
You are using the database
Other fancy things 💅
Unit - Stubs
class Temperature {
constructor(service) {
this.service = service;
}
average() {
var total = 0;
for (var i = 0; i < 3; i++) {
total += this.service.readTemp();
}
return total / 3;
}
}
class ServiceStub {
readTemp() {
return 15;
}
}
it('Checks avg. temp. can be calc’d', function
() {
var temperature = new
Temperature(ServiceStub);
assert.equals(15, temperature.average());
});
Mocks
class TweetFetcher {
get() {
$.ajax({
// ...
});
}
}
var jsmock = require('jsmock');
var jQuery = jsmock.mockGlobal('$');
var TweetFetcher = require('./TweetFetcher');
it('Gets some tweets', function () {
jQuery.expect().ajax.once();
TweetFetcher.get('#harambe', function ()
{});
// Don't forget to restore the original
function
jquery.restore();
});
Unit
Quick summary:
Carried out in isolation
Mock anything complex
API responses can change
Low code coverage
Code Coverage
●High is great but difficult to maintain.
●Low means a lot of code being left to chance.
●Badges
●Badges
●BADGES
Testing SuitesFunctional
Functional
1. I’m this user/I’m a guest/I’m the command line
2. I do this thing/Visit this page/Run the command
3. I see this text or element/get redirected to this URL or I don’t see this/expect this Exception
4. I look in the database and this gets stored/updated/deleted
Functional
var assert = require('assert');
var User = require('./UserORM');
var app = require('./ExpressApp');
var request = require('supertest')(app);
it('Should display a user profile', function (done) {
// ARRANGE
User.create({ id: 1 });
// ACT
request.get('/users/1');
// ASSERT
request.expect(200, done);
});
Functional
class LoginTest extends TestCase {
public function testValidUserCanLogin()
{
// ARRANGE
$this->amOnRoute('auth.login');
// ACT
$this->fillField('form.login-form #email', '[email protected]');
$this->fillField('form.login-form #password', 'password');
$this->press('form.login-form button[type=submit]');
// ASSERT
$this->seeCurrentRouteIs('projects.index');
$this->seeAuthentication();
}
Functional
it('Should not create a new user from invalid input', function (done) {
// ACT
request.post('/users').send({ email: 'notAnEmailAddressLOL123123!!!' });
// ASSERT
request.expect(400, done);
});
Functional
Quick summary:
●Test per controller/route/resource
●Typically done using framework helpers to aid setup
●Great for avoiding regressions
●Biggest “bang for your buck”
Test-driven Development(TDD)
TDD
●Write test first, then build functionality
●No browser needed
●Build features with confidence
●Packages to aid development
Behaviour-driven Development (BDD)
BDD
Example (from Behat):
In order to buy products
As a customer
I need to be able to put interesting products into a basket
Visual Regression
Check for rendering issues
Selenium
Summary
Free yourself from fixing bugs
Functional testing gives great coverage
Unit test your services
Double anything tricky
Extra Credit
Build tools
In memory testing for databases
Continuous Integration
Thanks!Questions?@_mikefrancis