SlideShare a Scribd company logo
1 of 31
#socialcommerce #onlinecommunities #socialmedia
Communify - Unit testing
#socialcommerce #onlinecommunities #socialmedia
Com funciona
A
?
A
>
?
Widgets socials Dashboard de comunitat
Com funciona
?
A
>
?
Sistema basat en generar converses sobre
els teus productes i continguts
Comentaris sobre els teus productes o articles del blog
Discusions generals sobre interessos
Valoracions de productes o serveis
Preguntes amb objectius de feedback
Votacions populars
Sortejos i concursos amb incentius
Preguntes i ajuda bàsica
Com funciona
Gestió versàtil i senzilla de continguts
i usuaris
Dashboard de comunitat i captació
Gestió de temes, respostes i comentaris
Supervisió, gestió i exportació d’usuaris
Configuració i personalització
A
Moltes cares, una comunitat
Engagement pills
Content discussionsSocial reviews
Customer notifications
Rewards
User intelligence
Equip
Producte
Disseny
Desenvolupament web
Desenvolupament mòbil
Integracions
Workflow de desenvolupament
Màster i devel
Màster conté la versió de producció. Devel la versió en desenvolupament.
Una branca per funcionalitat
Cada developer treballa amb una branca pròpia
Pull requests
Les branques de cada developer es passen a devel amb una validació prèvia
Treball amb la branca propia
És important mantenir-se actualitzat amb devel.
Estructura de branques
Developer 1
Developer 2
Developer 3
Devel
Branch
Production
Branch
Integració contínua
GitHub
Repositoris separats segons projectes (frontend, backend, sdk-php).
Database
PHPMig + Iluminate per a modificar i actualitzar la BD
Team City
Servidor d’integració contínua. Execució de tests + deploys
Deploy
El deploy es fa de forma automàtica després d’un push a master acceptat.
Arquitectura Backend (PHP)
Apis Actions
Background
Actions
Managers
Objects
Providers
DbHelpers
Core
Services
Arquitectura Frontend (angularJS)
Controllers
Services Api Services
Modules
Angular JS
Directives Model
Apps
STUPID VS SOLID development
Singleton
Complica el testing en alguns llenguatges (*).
Tight coupling
L’alt acoblament entre classes en dificulta l’evolució.
Untestability
Estructura intestejables. Gran refactor.
Premature optimization
Optimitzar sota segur i amb dades de millora.
Idescriptive naming
Un codi que no s’entén no és un bon codi
Duplication
Una mala arquitectura et porta a duplicar codi.
Single responsibility principle
Una i només una responsabilitat (classes i mètodes).
Open/Closed principle
Augmentar funcionalitat sense modificar internament.
Liskov substitution Principle
Dues instàncies de la mateixa interfície s’usen igual.
Interface segregation principle
Separar en interfícies i no en classes abstractes.
Dependency inversion principle
Una classe mai ha de dependre d’una implementació.
Test Driven Development
TDD a backend (PHPUnit)
Unit testing
El test només depèn de la pròpia classe
• Un test prova una i només una cosa.
• Separar en tests diferents asserts de
tipus de diferents.
• Detectar refactors mentre testegem.
• Identificar responsabilitats mentre
testegem.
• Cobertura del codi.
Integration testing
No hi ha injecció de dependencies
• DbHelpers, comprovem el resultat de
la query
• Cal recrear situacions reals per a
executar el test.
• En alguns casos són més sofisticats de
crear
Exemple test unitari backend
/**

* @param array $ideasIds

* @param $highlight

*/

public function highlightIdeas($ideasIds, $highlight)

{

/** @var applibmodelideaIdea[] $ideas */

$ideas = $this->getIdeaManager()->getObjects($ideasIds);



foreach($ideas as $idea)

{

$idea->setHighlighted($highlight);

$idea->save();

}

}
/**

* dataProvider getHighlightIdeasNoObjectsCorrectData

*/

public function getHighlightIdeasNoObjectsCorrectData()

{

return array(

array($this->once()),

array($this->any())

);

}



/**

* method: highlightIdeas

* when: called

* with: noObjectsWithPassedIds

* should: correct

* @dataProvider getHighlightIdeasNoObjectsCorrectData

*/

public function
test_highlightIdeas_called_noObjectsWithPassedIds_correct($timesGetObjects)

{

$ideaIds = array( 11 , 9 , 17 , 14);

$ideas = array();

$highlight = true;



$this->ideaManager->expects($timesGetObjects)

->method('getObjects')

->with($ideaIds)

->will($this->returnValue($ideas));



$this->configureSut()->highlightIdeas($ideaIds, $highlight);

}
/**

* method: highlightIdeas

* when: called

* with:

* should: correct

* @dataProvider getHighlightIdeasCorrectData

*/

public function test_highlightIdeas_called__correct($timesGetObjects, $timesSetHighlight
{

$ideaIds = array( 17 , 14);

$idea1 = $this->getMock('applibmodelideaIdea');

$idea2 = $this->getMock('applibmodelideaIdea');

$ideas = array($idea1, $idea2);

$highlight = 'dummy highlight value';



$this->ideaManager->expects($timesGetObjects)

->method('getObjects')

->with($ideaIds)

->will($this->returnValue($ideas));



$this->exerciciSetAndSaveAttribute($idea1, 'highlighted', $highlight, $
$this->exerciciSetAndSaveAttribute($idea1, 'highlighted', $highlight, $


$this->configureSut()->highlightIdeas($ideaIds, $highlight);

}





private function exerciciSetAndSaveAttribute($object, $attribute, $attributeValue, $time
{

$object->expects($timesSet)

->method('set'.ucfirst($attribute))

->with($attributeValue);



$object->expects($timesSave)

TDD a frontend (JasmineJS)
Unit testing
Mateixa estratègia de test
• Molts exemples de Google de com
testejar unitàriament AngularJS no
són unitaris.
• Un test és unitari quan el seu resultat
no depèn de cap classe acoblada.
• La sintaxi de JasmineJS és menys
intuïtiva.
• Important identificar les
responsabilitats
Patró de disseny: Promises
/**

* Init Ctrl function

*/

sc.init = function()

{

categoriesSrv.getAll()

.then(ctrl.getAllCategoriesSuccess, ctrl.getAllCategoriesError);



locationsSrv.getAll()

.then(ctrl.getAllLocationsSuccess, ctrl.getAllLocationsError);



if(ctrl.topicSlug)

{

topicsSrv.get(ctrl.topicSlug)

.then(ctrl.getTopicSuccess, ctrl.getTopicError);

}

};
Exemple de test unitari frontend
/**

* method: getByUrl

* toCheck: success callback

* should: correct

*/

it('getByUrl success callback correct', function(){

var url = 'dummy url',

expected = q.defer(),

deferred = q.defer(),

data = {dummy: "value"},

actual;

spyOn(topicsSrv, 'getSuccess');

actual = configureGetTopicByURrl(q, expected, publicApiSrv, deferred, topics
expect(actual).toBe(expected.promise);

deferred.resolve(data);

rootScope.$digest();

expect(topicsSrv.getSuccess).toHaveBeenCalledWith(data);

});
Exemple de test unitari frontend
function configureAndExecuteGetByUrl(getDeferred, url)

{

spyOn(q, 'defer').andReturn(getDeferred);

spyOn(publicApiSrv, 'getTopic').andReturn(deferred.promise);

spyOn(deferred.promise, 'then');

topicsSrv.getByUrl(url);

}



/**

* method: getByUrl

* toCheck: inner calls

* should: correct

*/

it('getByUrl inner calls correct', function()

{

var url = 'dummy url',

getDeferred = q.defer();

deferred = q.defer();

configureAndExecuteGetByUrl(getDeferred, url);

expect(q.defer).toHaveBeenCalled();

expect(publicApiSrv.getTopic).toHaveBeenCalledWith({url: url});

expect(deferred.promise.then)
.toHaveBeenCalledWith(topicsSrv.getSuccess, topicsSrv.getError)

});
E2E testing (JasmineJS + Protractor)
End to End testing
Validació de la interfície i experiència d’usuari
• Degut a les exigències de timings per la release els hem deixat per un
cop treta la beta.
• Simula la interacció de l’usuari
• Es necessita un server de veritat
• Les crides a les apis són reals
• Permet validar que tot funciona en la seva globalitat
Exemple test E2E (JasmineJS + Protractor)
/**

* functionality: register user

* toCheck: password equal

* should: display password ok message

*/

it('register user password equal display password ok message', function()

{

registerPage.clearElements();

registerPage.password.sendKeys('test12345');

registerPage.confirmPassword.sendKeys('test12345');



expect(element(by.id('passwordOk')).isDisplayed()).toBeTruthy();

expect(button.isEnabled()).toBe(false);



});
Exemple test E2E (JasmineJS + Protractor)
/**

* functionality: register user

* toCheck: no single email @

* should: display error message

*/

it('register user no single email @ display error message', function()

{

registerPage.email.sendKeys('test');

registerPage.password.click();



expect(element(by.id('emailFirstError')).isDisplayed()).toBeTruthy();

expect(button.isEnabled()).toBe(false);



});
var RegisterPage = function() {

var self = this;

this.firstname = element(by.model('user.name'));

this.lastname = element(by.model('user.surname'));

this.email = element(by.model('user.email'));

this.password = element(by.model('user.password'));

this.confirmPassword = element(by.model('user.passwordConfirm'));

this.registerButton = element(by.id('registerButton'));



this.registerUser = function() {

var date = new Date().getTime() / 1000;

self.firstname.sendKeys('name');

self.lastname.sendKeys('surname');

self.email.sendKeys('name' + date + '@name.es');

self.password.sendKeys('password1234');

self.confirmPassword.sendKeys('password1234');

self.registerButton.click();

browser.waitForAngular();

};



this.clearElements = function() {

self.firstname.clear();

self.lastname.clear();

self.email.clear();

self.password.clear();

self.confirmPassword.clear();

}

};

module.exports = new RegisterPage();
Unit VS Integration VS E2E
Unit Integration E2E
APIs, SDKs, Libs…
Database connectors,
file working, arrays…
UIs
Petits Llargs Molts llargs
Orientat al codi Orientat a l’acció
Orientat a l’interacció
de l’usuari
Caixa blanca Caixa negra Caixa negra
Aïllat de la resta Depenent de la resta Depenent de la resta
Amazon Web Services
Elastic Compute Cloud (EC2)
Relational Database Service (RDS)
Simple Storage Service (S3)
AWS - Infraestructura (Please)
PHP
RDS (MySQL)
S3 (static files)
User
User
MongoDB
EC2
AWS - Infraestructura (Communify)
Auto Scaling group
Elastic Load
Balancing
Auto Scaling group
EC2 instances
PHP
RDS (MySQL)
DynamoDB
S3 (static files)
Assets (JS + CSS)
CloudFront (cdn)
User
User
#socialcommerce #onlinecommunities #socialmedia
Moltes gràcies!
pitu@communify.com
@pitusabadi

More Related Content

Viewers also liked

Typography analysis
Typography analysisTypography analysis
Typography analysis09froudeden
 
Ukázky první pomoci pro děti předškolního a školního věku a kurzy PP pro uči...
Ukázky první pomoci pro děti předškolního a školního věku a  kurzy PP pro uči...Ukázky první pomoci pro děti předškolního a školního věku a  kurzy PP pro uči...
Ukázky první pomoci pro děti předškolního a školního věku a kurzy PP pro uči...NET University, s.r.o.
 
Financial Regulation
Financial Regulation Financial Regulation
Financial Regulation Evan Rassman
 
Mobile 3-D
Mobile 3-DMobile 3-D
Mobile 3-DCurvSurf
 
Bus rental paris
Bus rental parisBus rental paris
Bus rental parisArunagiri a
 

Viewers also liked (12)

It 090210116057
It 090210116057It 090210116057
It 090210116057
 
Typography analysis
Typography analysisTypography analysis
Typography analysis
 
Job Interview
Job Interview Job Interview
Job Interview
 
Ukázky první pomoci pro děti předškolního a školního věku a kurzy PP pro uči...
Ukázky první pomoci pro děti předškolního a školního věku a  kurzy PP pro uči...Ukázky první pomoci pro děti předškolního a školního věku a  kurzy PP pro uči...
Ukázky první pomoci pro děti předškolního a školního věku a kurzy PP pro uči...
 
Financial Regulation
Financial Regulation Financial Regulation
Financial Regulation
 
Phillip-Charles-Ashwood April 2016
Phillip-Charles-Ashwood April 2016Phillip-Charles-Ashwood April 2016
Phillip-Charles-Ashwood April 2016
 
Mobile 3-D
Mobile 3-DMobile 3-D
Mobile 3-D
 
Kowshikaa consultancy overseas
Kowshikaa consultancy overseas Kowshikaa consultancy overseas
Kowshikaa consultancy overseas
 
portofolio
portofolioportofolio
portofolio
 
MKP
MKPMKP
MKP
 
looseleaf_Portfolio
looseleaf_Portfoliolooseleaf_Portfolio
looseleaf_Portfolio
 
Bus rental paris
Bus rental parisBus rental paris
Bus rental paris
 

Similar to Communify - Unit Testing

Wellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingWellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingMarçal Berga
 
Cas d’us de Framework web desenvolupat amb llibreries Lliures
Cas d’us de Framework web desenvolupat amb llibreries LliuresCas d’us de Framework web desenvolupat amb llibreries Lliures
Cas d’us de Framework web desenvolupat amb llibreries LliuresJordi Catà
 
TALLER TIC TAC: Webquests i caceres
TALLER TIC TAC: Webquests i caceres TALLER TIC TAC: Webquests i caceres
TALLER TIC TAC: Webquests i caceres Sandra Lodeiro
 
Display suite - Drupal.cat
Display suite - Drupal.catDisplay suite - Drupal.cat
Display suite - Drupal.catAtenea tech
 
Microtaller webquest
Microtaller webquestMicrotaller webquest
Microtaller webquestgosanje
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i EnginyeriaDavid Rodenas
 
Taller Tic Tac Webquest I Caceres Del Tresor
Taller Tic Tac Webquest I Caceres Del TresorTaller Tic Tac Webquest I Caceres Del Tresor
Taller Tic Tac Webquest I Caceres Del TresorSandra Lodeiro
 
Turbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions WebTurbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions WebTomàs Reverter
 
Introducció a Phing php - digitals girona setembre 2014
Introducció a Phing php - digitals girona setembre 2014Introducció a Phing php - digitals girona setembre 2014
Introducció a Phing php - digitals girona setembre 2014Àlex Corretgé
 
El framework Cakephp
El framework CakephpEl framework Cakephp
El framework Cakephpherotyc
 
Introducció a Scrum
Introducció a ScrumIntroducció a Scrum
Introducció a ScrumJordi Catà
 

Similar to Communify - Unit Testing (14)

Wellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testingWellcome to the wonderful world of unit testing
Wellcome to the wonderful world of unit testing
 
Cas d’us de Framework web desenvolupat amb llibreries Lliures
Cas d’us de Framework web desenvolupat amb llibreries LliuresCas d’us de Framework web desenvolupat amb llibreries Lliures
Cas d’us de Framework web desenvolupat amb llibreries Lliures
 
TALLER TIC TAC: Webquests i caceres
TALLER TIC TAC: Webquests i caceres TALLER TIC TAC: Webquests i caceres
TALLER TIC TAC: Webquests i caceres
 
Display suite - Drupal.cat
Display suite - Drupal.catDisplay suite - Drupal.cat
Display suite - Drupal.cat
 
Webquests I Caceres
Webquests I CaceresWebquests I Caceres
Webquests I Caceres
 
Microtaller webquest
Microtaller webquestMicrotaller webquest
Microtaller webquest
 
Les Web Quest
Les Web QuestLes Web Quest
Les Web Quest
 
Tests nunit nunitforms
Tests nunit nunitformsTests nunit nunitforms
Tests nunit nunitforms
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i Enginyeria
 
Taller Tic Tac Webquest I Caceres Del Tresor
Taller Tic Tac Webquest I Caceres Del TresorTaller Tic Tac Webquest I Caceres Del Tresor
Taller Tic Tac Webquest I Caceres Del Tresor
 
Turbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions WebTurbo Gears, Framework De Python Per Aplicacions Web
Turbo Gears, Framework De Python Per Aplicacions Web
 
Introducció a Phing php - digitals girona setembre 2014
Introducció a Phing php - digitals girona setembre 2014Introducció a Phing php - digitals girona setembre 2014
Introducció a Phing php - digitals girona setembre 2014
 
El framework Cakephp
El framework CakephpEl framework Cakephp
El framework Cakephp
 
Introducció a Scrum
Introducció a ScrumIntroducció a Scrum
Introducció a Scrum
 

Communify - Unit Testing

  • 1. #socialcommerce #onlinecommunities #socialmedia Communify - Unit testing #socialcommerce #onlinecommunities #socialmedia
  • 2. Com funciona A ? A > ? Widgets socials Dashboard de comunitat
  • 3. Com funciona ? A > ? Sistema basat en generar converses sobre els teus productes i continguts Comentaris sobre els teus productes o articles del blog Discusions generals sobre interessos Valoracions de productes o serveis Preguntes amb objectius de feedback Votacions populars Sortejos i concursos amb incentius Preguntes i ajuda bàsica
  • 4. Com funciona Gestió versàtil i senzilla de continguts i usuaris Dashboard de comunitat i captació Gestió de temes, respostes i comentaris Supervisió, gestió i exportació d’usuaris Configuració i personalització A
  • 5. Moltes cares, una comunitat Engagement pills Content discussionsSocial reviews Customer notifications Rewards User intelligence
  • 7. Workflow de desenvolupament Màster i devel Màster conté la versió de producció. Devel la versió en desenvolupament. Una branca per funcionalitat Cada developer treballa amb una branca pròpia Pull requests Les branques de cada developer es passen a devel amb una validació prèvia Treball amb la branca propia És important mantenir-se actualitzat amb devel.
  • 8. Estructura de branques Developer 1 Developer 2 Developer 3 Devel Branch Production Branch
  • 9. Integració contínua GitHub Repositoris separats segons projectes (frontend, backend, sdk-php). Database PHPMig + Iluminate per a modificar i actualitzar la BD Team City Servidor d’integració contínua. Execució de tests + deploys Deploy El deploy es fa de forma automàtica després d’un push a master acceptat.
  • 10. Arquitectura Backend (PHP) Apis Actions Background Actions Managers Objects Providers DbHelpers Core Services
  • 11. Arquitectura Frontend (angularJS) Controllers Services Api Services Modules Angular JS Directives Model Apps
  • 12. STUPID VS SOLID development Singleton Complica el testing en alguns llenguatges (*). Tight coupling L’alt acoblament entre classes en dificulta l’evolució. Untestability Estructura intestejables. Gran refactor. Premature optimization Optimitzar sota segur i amb dades de millora. Idescriptive naming Un codi que no s’entén no és un bon codi Duplication Una mala arquitectura et porta a duplicar codi. Single responsibility principle Una i només una responsabilitat (classes i mètodes). Open/Closed principle Augmentar funcionalitat sense modificar internament. Liskov substitution Principle Dues instàncies de la mateixa interfície s’usen igual. Interface segregation principle Separar en interfícies i no en classes abstractes. Dependency inversion principle Una classe mai ha de dependre d’una implementació.
  • 14. TDD a backend (PHPUnit) Unit testing El test només depèn de la pròpia classe • Un test prova una i només una cosa. • Separar en tests diferents asserts de tipus de diferents. • Detectar refactors mentre testegem. • Identificar responsabilitats mentre testegem. • Cobertura del codi. Integration testing No hi ha injecció de dependencies • DbHelpers, comprovem el resultat de la query • Cal recrear situacions reals per a executar el test. • En alguns casos són més sofisticats de crear
  • 15. Exemple test unitari backend /**
 * @param array $ideasIds
 * @param $highlight
 */
 public function highlightIdeas($ideasIds, $highlight)
 {
 /** @var applibmodelideaIdea[] $ideas */
 $ideas = $this->getIdeaManager()->getObjects($ideasIds);
 
 foreach($ideas as $idea)
 {
 $idea->setHighlighted($highlight);
 $idea->save();
 }
 }
  • 16. /**
 * dataProvider getHighlightIdeasNoObjectsCorrectData
 */
 public function getHighlightIdeasNoObjectsCorrectData()
 {
 return array(
 array($this->once()),
 array($this->any())
 );
 }
 
 /**
 * method: highlightIdeas
 * when: called
 * with: noObjectsWithPassedIds
 * should: correct
 * @dataProvider getHighlightIdeasNoObjectsCorrectData
 */
 public function test_highlightIdeas_called_noObjectsWithPassedIds_correct($timesGetObjects)
 {
 $ideaIds = array( 11 , 9 , 17 , 14);
 $ideas = array();
 $highlight = true;
 
 $this->ideaManager->expects($timesGetObjects)
 ->method('getObjects')
 ->with($ideaIds)
 ->will($this->returnValue($ideas));
 
 $this->configureSut()->highlightIdeas($ideaIds, $highlight);
 }
  • 17. /**
 * method: highlightIdeas
 * when: called
 * with:
 * should: correct
 * @dataProvider getHighlightIdeasCorrectData
 */
 public function test_highlightIdeas_called__correct($timesGetObjects, $timesSetHighlight {
 $ideaIds = array( 17 , 14);
 $idea1 = $this->getMock('applibmodelideaIdea');
 $idea2 = $this->getMock('applibmodelideaIdea');
 $ideas = array($idea1, $idea2);
 $highlight = 'dummy highlight value';
 
 $this->ideaManager->expects($timesGetObjects)
 ->method('getObjects')
 ->with($ideaIds)
 ->will($this->returnValue($ideas));
 
 $this->exerciciSetAndSaveAttribute($idea1, 'highlighted', $highlight, $ $this->exerciciSetAndSaveAttribute($idea1, 'highlighted', $highlight, $ 
 $this->configureSut()->highlightIdeas($ideaIds, $highlight);
 }
 
 
 private function exerciciSetAndSaveAttribute($object, $attribute, $attributeValue, $time {
 $object->expects($timesSet)
 ->method('set'.ucfirst($attribute))
 ->with($attributeValue);
 
 $object->expects($timesSave)

  • 18. TDD a frontend (JasmineJS) Unit testing Mateixa estratègia de test • Molts exemples de Google de com testejar unitàriament AngularJS no són unitaris. • Un test és unitari quan el seu resultat no depèn de cap classe acoblada. • La sintaxi de JasmineJS és menys intuïtiva. • Important identificar les responsabilitats
  • 19. Patró de disseny: Promises /**
 * Init Ctrl function
 */
 sc.init = function()
 {
 categoriesSrv.getAll()
 .then(ctrl.getAllCategoriesSuccess, ctrl.getAllCategoriesError);
 
 locationsSrv.getAll()
 .then(ctrl.getAllLocationsSuccess, ctrl.getAllLocationsError);
 
 if(ctrl.topicSlug)
 {
 topicsSrv.get(ctrl.topicSlug)
 .then(ctrl.getTopicSuccess, ctrl.getTopicError);
 }
 };
  • 20. Exemple de test unitari frontend /**
 * method: getByUrl
 * toCheck: success callback
 * should: correct
 */
 it('getByUrl success callback correct', function(){
 var url = 'dummy url',
 expected = q.defer(),
 deferred = q.defer(),
 data = {dummy: "value"},
 actual;
 spyOn(topicsSrv, 'getSuccess');
 actual = configureGetTopicByURrl(q, expected, publicApiSrv, deferred, topics expect(actual).toBe(expected.promise);
 deferred.resolve(data);
 rootScope.$digest();
 expect(topicsSrv.getSuccess).toHaveBeenCalledWith(data);
 });
  • 21. Exemple de test unitari frontend function configureAndExecuteGetByUrl(getDeferred, url)
 {
 spyOn(q, 'defer').andReturn(getDeferred);
 spyOn(publicApiSrv, 'getTopic').andReturn(deferred.promise);
 spyOn(deferred.promise, 'then');
 topicsSrv.getByUrl(url);
 }
 
 /**
 * method: getByUrl
 * toCheck: inner calls
 * should: correct
 */
 it('getByUrl inner calls correct', function()
 {
 var url = 'dummy url',
 getDeferred = q.defer();
 deferred = q.defer();
 configureAndExecuteGetByUrl(getDeferred, url);
 expect(q.defer).toHaveBeenCalled();
 expect(publicApiSrv.getTopic).toHaveBeenCalledWith({url: url});
 expect(deferred.promise.then) .toHaveBeenCalledWith(topicsSrv.getSuccess, topicsSrv.getError)
 });
  • 22. E2E testing (JasmineJS + Protractor) End to End testing Validació de la interfície i experiència d’usuari • Degut a les exigències de timings per la release els hem deixat per un cop treta la beta. • Simula la interacció de l’usuari • Es necessita un server de veritat • Les crides a les apis són reals • Permet validar que tot funciona en la seva globalitat
  • 23. Exemple test E2E (JasmineJS + Protractor) /**
 * functionality: register user
 * toCheck: password equal
 * should: display password ok message
 */
 it('register user password equal display password ok message', function()
 {
 registerPage.clearElements();
 registerPage.password.sendKeys('test12345');
 registerPage.confirmPassword.sendKeys('test12345');
 
 expect(element(by.id('passwordOk')).isDisplayed()).toBeTruthy();
 expect(button.isEnabled()).toBe(false);
 
 });
  • 24. Exemple test E2E (JasmineJS + Protractor) /**
 * functionality: register user
 * toCheck: no single email @
 * should: display error message
 */
 it('register user no single email @ display error message', function()
 {
 registerPage.email.sendKeys('test');
 registerPage.password.click();
 
 expect(element(by.id('emailFirstError')).isDisplayed()).toBeTruthy();
 expect(button.isEnabled()).toBe(false);
 
 });
  • 25. var RegisterPage = function() {
 var self = this;
 this.firstname = element(by.model('user.name'));
 this.lastname = element(by.model('user.surname'));
 this.email = element(by.model('user.email'));
 this.password = element(by.model('user.password'));
 this.confirmPassword = element(by.model('user.passwordConfirm'));
 this.registerButton = element(by.id('registerButton'));
 
 this.registerUser = function() {
 var date = new Date().getTime() / 1000;
 self.firstname.sendKeys('name');
 self.lastname.sendKeys('surname');
 self.email.sendKeys('name' + date + '@name.es');
 self.password.sendKeys('password1234');
 self.confirmPassword.sendKeys('password1234');
 self.registerButton.click();
 browser.waitForAngular();
 };
 
 this.clearElements = function() {
 self.firstname.clear();
 self.lastname.clear();
 self.email.clear();
 self.password.clear();
 self.confirmPassword.clear();
 }
 };
 module.exports = new RegisterPage();
  • 26. Unit VS Integration VS E2E Unit Integration E2E APIs, SDKs, Libs… Database connectors, file working, arrays… UIs Petits Llargs Molts llargs Orientat al codi Orientat a l’acció Orientat a l’interacció de l’usuari Caixa blanca Caixa negra Caixa negra Aïllat de la resta Depenent de la resta Depenent de la resta
  • 27.
  • 28. Amazon Web Services Elastic Compute Cloud (EC2) Relational Database Service (RDS) Simple Storage Service (S3)
  • 29. AWS - Infraestructura (Please) PHP RDS (MySQL) S3 (static files) User User MongoDB EC2
  • 30. AWS - Infraestructura (Communify) Auto Scaling group Elastic Load Balancing Auto Scaling group EC2 instances PHP RDS (MySQL) DynamoDB S3 (static files) Assets (JS + CSS) CloudFront (cdn) User User
  • 31. #socialcommerce #onlinecommunities #socialmedia Moltes gràcies! pitu@communify.com @pitusabadi