testing 101

38
Testing 123 101 Mike Francis @_mikefrancis

Upload: mike-francis

Post on 14-Feb-2017

118 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Testing 101

Testing 123 101Mike Francis@_mikefrancis

Page 2: Testing 101
Page 3: Testing 101

Who likes fixing bugs?

Page 4: Testing 101

Put your bloody hand down.

Page 5: Testing 101

Exactly 💁

Page 6: Testing 101

Development without testing

Inefficient

Expensive

Human reliant

“Known unknowns”

Page 7: Testing 101

Development with testing

Efficient

Autonomous

Confident

Safe

Page 8: Testing 101

WTF is testing?

Page 9: Testing 101

“Software testing involves the execution of a software component or system component to evaluate one or more properties of interest.”

Page 10: Testing 101

“Software testing involves the execution of a software component or system component to evaluate one or more properties of interest.”

Page 11: Testing 101

Software Testing

Plethora of testing frameworks for each language

Usually run from the command line

Can be configured

Split into suites

Page 12: Testing 101

WTF do I test?

Page 13: Testing 101

What should I test?

●Everything!

●Only what you “own”

●The “critical path”

Page 14: Testing 101

User stories help!

In order to buy products

As a customer

I need to be able to put interesting products into a basket

Page 15: Testing 101

Testing Fundamentals

●Arrange

●Act

●Assert

Page 16: Testing 101

Testing Suitesor “Folders”

Page 17: Testing 101

Testing SuitesUnit

Page 18: Testing 101

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

Page 19: Testing 101

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' });

});

Page 20: Testing 101

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 💅

Page 21: Testing 101

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());

});

Page 22: Testing 101

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();

});

Page 23: Testing 101

Unit

Quick summary:

Carried out in isolation

Mock anything complex

API responses can change

Low code coverage

Page 24: Testing 101

Code Coverage

●High is great but difficult to maintain.

●Low means a lot of code being left to chance.

●Badges

●Badges

●BADGES

Page 25: Testing 101

Testing SuitesFunctional

Page 26: Testing 101

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

Page 27: Testing 101

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);

});

Page 28: Testing 101

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();

}

Page 29: Testing 101

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);

});

Page 30: Testing 101

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”

Page 31: Testing 101

Test-driven Development(TDD)

Page 32: Testing 101

TDD

●Write test first, then build functionality

●No browser needed

●Build features with confidence

●Packages to aid development

Page 33: Testing 101

Behaviour-driven Development (BDD)

Page 34: Testing 101

BDD

Example (from Behat):

In order to buy products

As a customer

I need to be able to put interesting products into a basket

Page 35: Testing 101

Visual Regression

Check for rendering issues

Selenium

Page 36: Testing 101

Summary

Free yourself from fixing bugs

Functional testing gives great coverage

Unit test your services

Double anything tricky

Page 37: Testing 101

Extra Credit

Build tools

In memory testing for databases

Continuous Integration

Page 38: Testing 101

Thanks!Questions?@_mikefrancis