Top Banner
How to test complex SaaS solutions The Family 16th july 2014
38
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: How to test complex SaaS applications - The family july 2014

How to test complex SaaS solutions!!

The Family!16th july 2014

Page 2: How to test complex SaaS applications - The family july 2014

Founder & CTO!!

@guillaumepotier!http://imctobitch.com

Page 3: How to test complex SaaS applications - The family july 2014

By the numbers• 4 years old!• 23 employes and counting!- ~ 10 tech / product!- ~ 10 sales!- ~ 3 support, market, administrative !

• 400+ clients!- Total, Orange, Areva, Air Liquide, Google, SNCF, AXA, Société

Générale, Sanofi, L’Oréal, Crédit Agricole, Danone, Deloitte, Capgemini, Auchan…!

• 4000+ tests!- UT backend, functional backend!- UT javascript, functional javascript!

!!!

!

Page 4: How to test complex SaaS applications - The family july 2014

What we’ll talk about

• Why testing?!• What need to be tested?!• How to test?!• Tools!• Limits..!• Going further!

!

Page 5: How to test complex SaaS applications - The family july 2014

Why testing?

Sometimes shit may happen

Page 6: How to test complex SaaS applications - The family july 2014

Why testing?

Tests are here to prevent that (at least they try..)

Page 7: How to test complex SaaS applications - The family july 2014

Why testing?

Tests also allow you refactor without fearing to break things

Page 8: How to test complex SaaS applications - The family july 2014

Why testing?

Tests are great to rely on other people code (and other people on yours)

Page 9: How to test complex SaaS applications - The family july 2014

Why testing?

Ultimately, tests allow you to be faster!

Page 10: How to test complex SaaS applications - The family july 2014

Why testing?

A little more seriously..!Let’s see a real Parsley.js example here

Page 11: How to test complex SaaS applications - The family july 2014

Why testing?

Page 12: How to test complex SaaS applications - The family july 2014

Why testing?

• 10+ classes!• 2k+ lines!• ~200 tests (UT & functional)!• ran in < 3sec in browser!• ran in < 1sec in CLI!

!!

http://parsleyjs.org/doc/tests.html

Page 13: How to test complex SaaS applications - The family july 2014

Why testing?

UT : validate your methods API and behavior

! it('should have a max validator', function () { expect(parsleyValidator.validate('foo', parsleyValidator.max(10))).to.be(false); expect(parsleyValidator.validate('5', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('10', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('42', parsleyValidator.max(10))).to.be(false); });

max: function (value) { return $.extend(new Validator.Assert().LessThanOrEqual(value), { priority: 30 }); }

✓ should have a max validator

Code

Test

Result

Page 14: How to test complex SaaS applications - The family july 2014

Why testing?

Prevent regressions, ensure 3rd party libs consistency

! it('should have a max validator', function () { expect(parsleyValidator.validate('foo', parsleyValidator.max(10))).to.be(false); expect(parsleyValidator.validate('5', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('10', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('42', parsleyValidator.max(10))).to.be(false); });

max: function (value) { return $.extend(new Validator.Assert().LessThan(value), { priority: 30 }); }

1) should have a max validator

Code

Test

Result

Page 15: How to test complex SaaS applications - The family july 2014

Why testing?

Page 16: How to test complex SaaS applications - The family july 2014

Why testing?

Page 17: How to test complex SaaS applications - The family july 2014

Why testing?

Fixes bugs found to ensure they’ll never show up again

! it('should have a max validator', function () { expect(parsleyValidator.validate('foo', parsleyValidator.max(10))).to.be(false); expect(parsleyValidator.validate('5', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('10', parsleyValidator.max(10))).to.be(true); expect(parsleyValidator.validate('42', parsleyValidator.max(10))).to.be(false); expect(parsleyValidator.validate('5', parsleyValidator.max(”10”))).to.be(true); });

✓ should have a max validator

Code

Test

Result

max: function (value) { return $.extend(new Validator.Assert().LessThan(value), { priority: 30, requirementsTransformer: function () { return 'string' === typeof value && !isNaN(value) ? parseInt(value, 10) : value; } }); }

Page 18: How to test complex SaaS applications - The family july 2014

Why testing?

it('should show custom error message with variabilized parameters', function () { $('body').append('<input type="text" id="element" value="bar" data-parsley-minlength="7" data-parsley-minlength-message="foo %s bar"/>'); var parsleyField = $('#element').psly(); parsleyField.validate(); ! expect($('ul#parsley-id-' + parsleyField.__id__ + ' li').text()).to.be('foo 7 bar'); });

Functional test : validate your end-user behavior

Page 19: How to test complex SaaS applications - The family july 2014

Why testing?it('should save some calls for querries already done', function (done) { $('body').append('<input type="text" data-parsley-remote="http://foo.bar" id="element" required name="element" value="foo" />'); var parsleyInstance = $('#element').parsley(); ! sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } })); parsleyInstance.asyncIsValid() .done(function () { expect($.ajax.calledOnce).to.be(true); expect($.ajax.calledWithMatch({ data: { "element": "foo" } })).to.be(true); $.ajax.restore(); sinon.stub($, 'ajax').returns($.Deferred().reject({ status: 400, state: function () { return 'rejected' } }, 'error', 'error')); ! $('#element').val('bar'); parsleyInstance.asyncIsValid() .fail(function () { expect($.ajax.calledOnce).to.be(true); expect($.ajax.calledWithMatch({ data: { "element": "bar" } })).to.be(true); ! $.ajax.restore(); sinon.stub($, 'ajax').returns($.Deferred().resolve({}, 'success', { status: 200, state: function () { return 'resolved' } })); $('#element').val('foo'); ! parsleyInstance.asyncIsValid() .done(function () { expect($.ajax.callCount).to.be(0); expect($.ajax.calledOnce).to.be(false); $.ajax.restore(); done(); }); }); }); });

Page 20: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 21: How to test complex SaaS applications - The family july 2014

What need to be tested?

• Application logic (services, algorithms, microapps)!• API responses!• Application behavior, End-user responses!

!

TO  BE  TESTED

Page 22: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 23: How to test complex SaaS applications - The family july 2014

What need to be tested?

• getters / setters!• already tested 3rd party libraries!• ORM, all exceptions, errors!

!

NOT  TO  BE  TESTED

Page 24: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 25: How to test complex SaaS applications - The family july 2014

What need to be tested?

100%  coverage!

Page 26: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 27: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 28: How to test complex SaaS applications - The family july 2014

What need to be tested?

Page 29: How to test complex SaaS applications - The family july 2014

How to test?

Page 30: How to test complex SaaS applications - The family july 2014

How to test?

Page 31: How to test complex SaaS applications - The family july 2014

How to test?class SynchronizedUserTest extends PHPUnit_Framework_TestCase { /** * @covers ::construct() * @expectedException InvalidArgumentException * @expectedExceptionMessage User and IntercomUser are not the same. */ public function testConstructWithWrongEmails() { $intercomUser = new IntercomUser(1, '[email protected]'); $user = (new User)->setEmail('[email protected]'); $this->setProperty($user, 'id', 1); ! new SynchronizedUser($intercomUser, $user); } ! /** * @covers ::construct() * @expectedException InvalidArgumentException * @expectedExceptionMessage User and IntercomUser are not the same. */ public function testConstructWithWrongIds() { $intercomUser = new IntercomUser(2, '[email protected]'); $user = (new User)->setEmail('[email protected]'); $this->setProperty($user, 'id', 1); ! new SynchronizedUser($intercomUser, $user); } }

Page 32: How to test complex SaaS applications - The family july 2014

How to test?class SynchronizedUser { private $intercomUser; private $user; ! /** * @throws InvalidArgumentException If the user intercom and user wisembly doesn't match */ public function __construct(IntercomUser $intercomUser, User $user) { if ($intercomUser->getUserId() !== $user->getId() || $intercomUser->getEmail() !== mb_strtolower($user->getEmail(), mb_detect_encoding($user->getEmail()))) { throw new InvalidArgumentException('User and IntercomUser are not the same.'); } ! $this->intercomUser = $intercomUser; $this->user = $user; } ! /** * @return IntercomUser */ public function getIntercomUser() { return $this->intercomUser; } ! /** * @return User */ public function getUser() { return $this->user; } }

Page 33: How to test complex SaaS applications - The family july 2014

How to test?

Page 34: How to test complex SaaS applications - The family july 2014

How to test?

Page 35: How to test complex SaaS applications - The family july 2014

Tools

• PHPUnit!• Behat, PHPSpec..!• Mocha, Jasmine, QUnit..!• Karma, PhantomJS, TestEM..!• Travis, Jenkins, Shipper, CodeShip..!

!

Page 36: How to test complex SaaS applications - The family july 2014

Limits

• CSS glitches!• User experience!• Browser compatibility!• Do not take to much time to code / maintain tests!!• Do not have too long test suites!!• Fixtures for functional tests!• Isolate tests among themselves!!

!

Page 37: How to test complex SaaS applications - The family july 2014

Going further

• Script & test deploy scripts..!• SLA & performance tests..!

!

Page 38: How to test complex SaaS applications - The family july 2014