How to test complex SaaS applications - The family july 2014
-
Upload
guillaume-potier -
Category
Technology
-
view
194 -
download
5
Transcript of How to test complex SaaS applications - The family july 2014
![Page 1: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/1.jpg)
How to test complex SaaS solutions!!
The Family!16th july 2014
![Page 3: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/3.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/4.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/5.jpg)
Why testing?
Sometimes shit may happen
![Page 6: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/6.jpg)
Why testing?
Tests are here to prevent that (at least they try..)
![Page 7: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/7.jpg)
Why testing?
Tests also allow you refactor without fearing to break things
![Page 8: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/8.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/9.jpg)
Why testing?
Ultimately, tests allow you to be faster!
![Page 10: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/10.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/11.jpg)
Why testing?
![Page 12: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/12.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/13.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/14.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/15.jpg)
Why testing?
![Page 16: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/16.jpg)
Why testing?
![Page 17: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/17.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/18.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/19.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/20.jpg)
What need to be tested?
![Page 21: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/21.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/22.jpg)
What need to be tested?
![Page 23: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/23.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/24.jpg)
What need to be tested?
![Page 25: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/25.jpg)
What need to be tested?
100% coverage!
![Page 26: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/26.jpg)
What need to be tested?
![Page 27: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/27.jpg)
What need to be tested?
![Page 28: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/28.jpg)
What need to be tested?
![Page 29: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/29.jpg)
How to test?
![Page 30: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/30.jpg)
How to test?
![Page 31: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/31.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/32.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/33.jpg)
How to test?
![Page 34: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/34.jpg)
How to test?
![Page 35: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/35.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/36.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/37.jpg)
Going further
• Script & test deploy scripts..!• SLA & performance tests..!
!
![Page 38: How to test complex SaaS applications - The family july 2014](https://reader034.fdocuments.us/reader034/viewer/2022051516/55a4a64f1a28abfa728b4599/html5/thumbnails/38.jpg)