SlideShare une entreprise Scribd logo
1  sur  28
About Me
Questo non riguarda la
tecnologia
Ma se non c’e’ tecnologia poi
mi dicono che il tdd e’ solo per
il dominio
Il Gioco
• Si chiama “Boss”, e’ una specie di GTA su
browser
– Il giocatore ha una vista a volo d’uccello sulla città
e sul personaggio
– Quando il giocatore clicca sulla mappa il
personaggio si sposta
– Il giocatore vede gli altri personaggi sulla mappa
– ….
Il Primo Test
Il Primo Test
public class BossBehavior {
@Test
public void shouldAnswerHttpCall() throws IOException {
new Boss(8080);
WebClient client = new WebClient();
Page page = client.getPage("http://localhost:8080");
assertThat(page.getWebResponse().getStatusCode(), is(200));
}
}
La Soluzione
public class Boss {
public Boss(int port) throws IOException {
SelectorThread selector = new SelectorThread();
selector.setPort(port);
selector.setAdapter(new AlwaysReturn200Ok());
selector.listen();
}
}
Un po’ di refactoring
@Test
public void shouldAnswerHttpCall() throws Exception {
new Boss(PORT);
assertThat(Http.callOn(PORT), is(OK));
}
• Se non posso parlare di un’entità non posso farne
il design
• Per fare il design di un sistema ho bisogno di “new
Sistema()”
• Quindi, l’application server, se c’e’, deve essere un
dettaglio implementativo
Il Secondo Test
Il Secondo Test
@Test
public void shouldAnswerWithAnHtmlDocument() throws Exception {
new Boss(PORT);
assertThat(Http.callOn(PORT),
is(HttpAnswer.with("<html><body></body></html>")));
}
public class Boss {
...
public Boss(int port) throws IOException, InstantiationException {
selector = new SelectorThread();
selector.setPort(port);
HttpAnswer answer = HttpAnswer.with("<html><body></body></html>");
selector.setAdapter(new AlwaysReturn(answer));
selector.listen();
}
...
}
Tutto verde?
@Test
public void shouldAnswerWithAnHtmlDocument() {
new Boss(PORT);
assertThat(Http.callOn(PORT),
is(HttpAnswer.with("<html><body></body></html>")));
}
@Test
public void shouldAnswerHttpCall() {
new Boss(PORT);
assertThat(Http.callOn(PORT), is(OK));
}
Sfruttare le microdivergenze
Il concetto di Screen nasce per conciliare due tests
@Test
public void shouldAnswerHttpCall() throws Exception {
Boss boss = new Boss(PORT, new BlankScreen());
HttpAnswer answer = Http.callOn(PORT);
boss.stop();
assertThat(answer, is(HttpAnswer.ok()));
}
@Test
public void shouldAnswerWithAnHtmlDocument() throws Exception {
Boss boss = new Boss(PORT, new HtmlScreen());
HttpAnswer answer = Http.callOn(PORT);
boss.stop();
assertThat(answer, is(HttpAnswer.with("<html><body></body></html>")));
}
La Nascita Della Gui
Il Movimento Verso il Basso
public class HtmlScreenBehavior {
@Test
public void shouldRenderAnHtmlDocument() {
assertThat(new HtmlScreen().render(), is("<html><body></body></html>"));
}
}
L’Asserzione a Specchio
@Test
public void shouldAnswerWithTheScreenContents() throws Exception {
Screen screen = new HtmlScreen();
boss = new Boss(PORT, screen);
assertThat(Http.callOn(PORT), is(HttpAnswer.with(screen.render())));
}
Un Edificio
La grafica vettoriale secondo Raphael
<html>
<head>
<script type="text/javascript" src="raphael-min.js"></script>
<script type="text/javascript" charset="utf-8">
window.onload = function() {
var map = new Raphael(0,0,600,400);
map.rect(10,10,50,40);
};
</script>
</head>
<body>
</body>
</html>
Testare un sacco di sintassi?
@Test
public void shouldRenderABuildingAsARectangle() {
assertThat(new HtmlScreen().render(), is("<html>n" +
"<head>n" +
" <script type="text/javascript" src="raphael-min.js"></script>n" +
" <script type="text/javascript" charset="utf-8">n" +
" window.onload = function() {n" +
" var map = new Raphael(0,0,600,400);n" +
" var building = map.rect(10,10,50,40);n" +
" };n" +
" </script>n" +
"</head>n" +
"<body>n" +
"</body>n" +
"</html>"));
}
O dichiarare il comportamento?
@Test
public void shouldRenderABuildingAsARectangle() throws Exception {
User user = new User().lookAt(new HtmlScreen().render());
assertThat(user.currentSight(),
is("A Rectangle at [10,10], 40px high and 50px wide"));
}
Cosa voglio veramente dichiarare?
Si, bello, ma come?
function Raphael(x, y, width, height){
this.rect = function(x, y, width, height) {
output = "A Rectangle at [" + x + "," + y + "], " +
height + "px high and " + width + "px wide";
}
}
var output = “”;
Come stubbare una libreria di grafica vettoriale?
function Window() {
}
var window = new Window();
Come stubbare un browser?
Ma chi e’ ‘sto User?
public class User {
…
public User lookAt(String htmlPage) {
JavaScriptSource source = new XomJavaScriptSource(htmlPage);
source.evaluateWith(javaScript);
triggerOnLoad();
result.readOutput(javaScript);
return this;
}
…
}
Il risultato
public class HtmlScreen implements Screen {
private Building building = new Building(10, 10, 40, 50);
public String render() {
String start = "<html><head>" +
" <script type="text/javascript" src="raphael-min.js"></script>" +
" <script type="text/javascript" charset="utf-8">" +
" window.onload = function() {" +
" var map = new Raphael(0,0,600,400);";
String end = "}</script></head><body></body></html>";
return start + building.render() + end;
}
Mantenere sempre l’omogeneità
public class HtmlScreen {
...
public String render() {
return header() +
vectorGraphics.include() +
openScript() +
openFunction() +
vectorGraphics.init() +
building.render(vectorGraphics) +
closeFunction() +
closeScript() +
ending();
}
...
}
Tanti Edifici!
@Test
public void shouldRenderMultipleBuildings() throws Exception {
HtmlScreen htmlScreen = new HtmlScreen();
htmlScreen.addBuilding(10,10,50,40);
htmlScreen.addBuilding(80,10,30,40);
htmlScreen.addBuilding(10,70,100,40);
User user = new User().lookAt(htmlScreen.render());
assertThat(user.currentSight(), is(aRectangle(10, 10, 50, 40)));
assertThat(user.currentSight(), is(aRectangle(80, 10, 30, 40)));
assertThat(user.currentSight(), is(aRectangle(10, 70, 100, 40)));
}
Il Personaggio
@Test
public void shouldRenderACharacter() {
HtmlScreen htmlScreen = new HtmlScreen().addCharacter(70,60);
User user = new User().lookAt(htmlScreen.render());
assertThat(user.currentSight(), is(aCircle(70, 60, 5)));
}
Generalizzazione
private String renderViewElements() {
String renderedElements = "";
for (ViewElement element : viewElements) {
renderedElements += element.render(vectorGraphics);
}
return renderedElements;
}
L’HtmlScreen smette di parlare di buildings e characters
public HtmlScreen addViewElement(ViewElement element) {
viewElements.add(element);
return this;
}
Un’ultima volta verso il basso
@Test
public void shouldBeARedCircle() {
GameCharacter character = new GameCharacter(10,10);
VectorGraphics vectorGraphics = new TextualVectorGraphics();
assertThat(character.render(vectorGraphics),
is("A Circle at [10,10], 5px in diameter"));
}
public class TextualVectorGraphics implements VectorGraphics {
@Override
public String rect(int x, int y, int width, int height) {
return aRectangle(x,y,width,height);
}
@Override
public String circle(int x, int y, int size) {
return aCircle(x,y,size);
}
}
Questo non riguarda solo la vista
Un’occhiata al futuro di questa applicazione…
Interazione :
@Test
public void characterShouldMoveOnClick() {
String page = Http.callOn(PORT).payload();
user.lookAt(page);
user.clickOn(60, 60);
page = Http.callOn(PORT).payload();
user.lookAt(page);
assertThat(user.currentSight, is("A Circle at [60,60], 5px in diameter"));
}
Il protocollo si stacca dalla logica del gioco :
@Test
public void shouldAnswerHttpCall() throws Exception {
httpServer = new HttpServer(PORT).publish(boss);
assertThat(Http.callOn(PORT), is(HttpAnswer.ok()));
}
Questo non riguarda solo la vista
Avendo le buone primitive ogni asserzione e’ possibile…
Arriva la persistenza :
@Test
public void characterPositionShouldPersist() {
Boss boss1 = new Boss(persistence, screen1);
boss1.moveCharacterTo(30,30);
Boss boss2 = new Boss(persistence, screen2);
assertThat(screen2.render(), is("A Circle at [30,30], 5px in diameter"));
}
Ajax :
@Test
public void characterShouldMoveOnClick() {
page = new HtmlScreen().render();
user.lookAt(page);
user.clickOn(60, 60);
assertThat(user.currentSight, is("A Circle at [60,60], 5px in diameter"));
}
Grazie!

Contenu connexe

Tendances

TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionHans Höchtl
 
Laporan multiclient chatting client server
Laporan multiclient chatting client serverLaporan multiclient chatting client server
Laporan multiclient chatting client servertrilestari08
 
RAILWAY RESERWATION PROJECT PROGRAM
RAILWAY RESERWATION PROJECT PROGRAMRAILWAY RESERWATION PROJECT PROGRAM
RAILWAY RESERWATION PROJECT PROGRAMKrishna Raj
 
RxJS ‘Marble’ programming
RxJS ‘Marble’ programmingRxJS ‘Marble’ programming
RxJS ‘Marble’ programmingStas Rivkin
 
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)Stas Rivkin
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEDarwin Durand
 
Rx.NET, from the inside out - Codemotion 2018
Rx.NET, from the inside out - Codemotion 2018Rx.NET, from the inside out - Codemotion 2018
Rx.NET, from the inside out - Codemotion 2018Stas Rivkin
 
Spicy javascript: Create your first Chrome extension for web analytics QA
Spicy javascript: Create your first Chrome extension for web analytics QASpicy javascript: Create your first Chrome extension for web analytics QA
Spicy javascript: Create your first Chrome extension for web analytics QAAlban Gérôme
 
ONLINE STUDENT MANAGEMENT SYSTEM
ONLINE STUDENT MANAGEMENT SYSTEMONLINE STUDENT MANAGEMENT SYSTEM
ONLINE STUDENT MANAGEMENT SYSTEMRohit malav
 
Writing good std::future&lt;c++>
Writing good std::future&lt;c++>Writing good std::future&lt;c++>
Writing good std::future&lt;c++>Anton Bikineev
 
Telephone billing system in c++
Telephone billing system in c++Telephone billing system in c++
Telephone billing system in c++vikram mahendra
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutineDaehee Kim
 
The Ring programming language version 1.5.4 book - Part 54 of 185
The Ring programming language version 1.5.4 book - Part 54 of 185The Ring programming language version 1.5.4 book - Part 54 of 185
The Ring programming language version 1.5.4 book - Part 54 of 185Mahmoud Samir Fayed
 

Tendances (18)

TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
Laporan multiclient chatting client server
Laporan multiclient chatting client serverLaporan multiclient chatting client server
Laporan multiclient chatting client server
 
RAILWAY RESERWATION PROJECT PROGRAM
RAILWAY RESERWATION PROJECT PROGRAMRAILWAY RESERWATION PROJECT PROGRAM
RAILWAY RESERWATION PROJECT PROGRAM
 
RxJS ‘Marble’ programming
RxJS ‘Marble’ programmingRxJS ‘Marble’ programming
RxJS ‘Marble’ programming
 
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)(Rx).NET' way of async programming (.NET summit 2017 Belarus)
(Rx).NET' way of async programming (.NET summit 2017 Belarus)
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Ccc
CccCcc
Ccc
 
Rx.NET, from the inside out - Codemotion 2018
Rx.NET, from the inside out - Codemotion 2018Rx.NET, from the inside out - Codemotion 2018
Rx.NET, from the inside out - Codemotion 2018
 
Hospital management
Hospital managementHospital management
Hospital management
 
Spicy javascript: Create your first Chrome extension for web analytics QA
Spicy javascript: Create your first Chrome extension for web analytics QASpicy javascript: Create your first Chrome extension for web analytics QA
Spicy javascript: Create your first Chrome extension for web analytics QA
 
ONLINE STUDENT MANAGEMENT SYSTEM
ONLINE STUDENT MANAGEMENT SYSTEMONLINE STUDENT MANAGEMENT SYSTEM
ONLINE STUDENT MANAGEMENT SYSTEM
 
Writing good std::future&lt;c++>
Writing good std::future&lt;c++>Writing good std::future&lt;c++>
Writing good std::future&lt;c++>
 
Telephone billing system in c++
Telephone billing system in c++Telephone billing system in c++
Telephone billing system in c++
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
PyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into CoroutinePyconKR 2018 Deep dive into Coroutine
PyconKR 2018 Deep dive into Coroutine
 
Object oriented JavaScript
Object oriented JavaScriptObject oriented JavaScript
Object oriented JavaScript
 
The Ring programming language version 1.5.4 book - Part 54 of 185
The Ring programming language version 1.5.4 book - Part 54 of 185The Ring programming language version 1.5.4 book - Part 54 of 185
The Ring programming language version 1.5.4 book - Part 54 of 185
 
Ss
SsSs
Ss
 

Similaire à TDD per Webapps

HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?Ankara JUG
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1Bitla Software
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensionserwanl
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeLaurence Svekis ✔
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web developmentJohannes Brodwall
 
HTML5って必要?
HTML5って必要?HTML5って必要?
HTML5って必要?GCS2013
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageabilityDaniel Fisher
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaFrank Lyaruu
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
Node lt
Node ltNode lt
Node ltsnodar
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011Stephen Chin
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAAiman Hud
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 

Similaire à TDD per Webapps (20)

A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?
 
How to build a html5 websites.v1
How to build a html5 websites.v1How to build a html5 websites.v1
How to build a html5 websites.v1
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Paris js extensions
Paris js extensionsParis js extensions
Paris js extensions
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
HTML5って必要?
HTML5って必要?HTML5って必要?
HTML5って必要?
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
mobl
moblmobl
mobl
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Node lt
Node ltNode lt
Node lt
 
JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011JavaFX 2.0 With Alternative Languages - JavaOne 2011
JavaFX 2.0 With Alternative Languages - JavaOne 2011
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 

Dernier

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 

Dernier (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 

TDD per Webapps

  • 2. Questo non riguarda la tecnologia Ma se non c’e’ tecnologia poi mi dicono che il tdd e’ solo per il dominio
  • 3. Il Gioco • Si chiama “Boss”, e’ una specie di GTA su browser – Il giocatore ha una vista a volo d’uccello sulla città e sul personaggio – Quando il giocatore clicca sulla mappa il personaggio si sposta – Il giocatore vede gli altri personaggi sulla mappa – ….
  • 4.
  • 6. Il Primo Test public class BossBehavior { @Test public void shouldAnswerHttpCall() throws IOException { new Boss(8080); WebClient client = new WebClient(); Page page = client.getPage("http://localhost:8080"); assertThat(page.getWebResponse().getStatusCode(), is(200)); } }
  • 7. La Soluzione public class Boss { public Boss(int port) throws IOException { SelectorThread selector = new SelectorThread(); selector.setPort(port); selector.setAdapter(new AlwaysReturn200Ok()); selector.listen(); } }
  • 8. Un po’ di refactoring @Test public void shouldAnswerHttpCall() throws Exception { new Boss(PORT); assertThat(Http.callOn(PORT), is(OK)); }
  • 9. • Se non posso parlare di un’entità non posso farne il design • Per fare il design di un sistema ho bisogno di “new Sistema()” • Quindi, l’application server, se c’e’, deve essere un dettaglio implementativo
  • 11. Il Secondo Test @Test public void shouldAnswerWithAnHtmlDocument() throws Exception { new Boss(PORT); assertThat(Http.callOn(PORT), is(HttpAnswer.with("<html><body></body></html>"))); } public class Boss { ... public Boss(int port) throws IOException, InstantiationException { selector = new SelectorThread(); selector.setPort(port); HttpAnswer answer = HttpAnswer.with("<html><body></body></html>"); selector.setAdapter(new AlwaysReturn(answer)); selector.listen(); } ... }
  • 12. Tutto verde? @Test public void shouldAnswerWithAnHtmlDocument() { new Boss(PORT); assertThat(Http.callOn(PORT), is(HttpAnswer.with("<html><body></body></html>"))); } @Test public void shouldAnswerHttpCall() { new Boss(PORT); assertThat(Http.callOn(PORT), is(OK)); }
  • 13. Sfruttare le microdivergenze Il concetto di Screen nasce per conciliare due tests @Test public void shouldAnswerHttpCall() throws Exception { Boss boss = new Boss(PORT, new BlankScreen()); HttpAnswer answer = Http.callOn(PORT); boss.stop(); assertThat(answer, is(HttpAnswer.ok())); } @Test public void shouldAnswerWithAnHtmlDocument() throws Exception { Boss boss = new Boss(PORT, new HtmlScreen()); HttpAnswer answer = Http.callOn(PORT); boss.stop(); assertThat(answer, is(HttpAnswer.with("<html><body></body></html>"))); }
  • 14. La Nascita Della Gui Il Movimento Verso il Basso public class HtmlScreenBehavior { @Test public void shouldRenderAnHtmlDocument() { assertThat(new HtmlScreen().render(), is("<html><body></body></html>")); } } L’Asserzione a Specchio @Test public void shouldAnswerWithTheScreenContents() throws Exception { Screen screen = new HtmlScreen(); boss = new Boss(PORT, screen); assertThat(Http.callOn(PORT), is(HttpAnswer.with(screen.render()))); }
  • 15. Un Edificio La grafica vettoriale secondo Raphael <html> <head> <script type="text/javascript" src="raphael-min.js"></script> <script type="text/javascript" charset="utf-8"> window.onload = function() { var map = new Raphael(0,0,600,400); map.rect(10,10,50,40); }; </script> </head> <body> </body> </html>
  • 16. Testare un sacco di sintassi? @Test public void shouldRenderABuildingAsARectangle() { assertThat(new HtmlScreen().render(), is("<html>n" + "<head>n" + " <script type="text/javascript" src="raphael-min.js"></script>n" + " <script type="text/javascript" charset="utf-8">n" + " window.onload = function() {n" + " var map = new Raphael(0,0,600,400);n" + " var building = map.rect(10,10,50,40);n" + " };n" + " </script>n" + "</head>n" + "<body>n" + "</body>n" + "</html>")); }
  • 17. O dichiarare il comportamento? @Test public void shouldRenderABuildingAsARectangle() throws Exception { User user = new User().lookAt(new HtmlScreen().render()); assertThat(user.currentSight(), is("A Rectangle at [10,10], 40px high and 50px wide")); } Cosa voglio veramente dichiarare?
  • 18. Si, bello, ma come? function Raphael(x, y, width, height){ this.rect = function(x, y, width, height) { output = "A Rectangle at [" + x + "," + y + "], " + height + "px high and " + width + "px wide"; } } var output = “”; Come stubbare una libreria di grafica vettoriale? function Window() { } var window = new Window(); Come stubbare un browser?
  • 19. Ma chi e’ ‘sto User? public class User { … public User lookAt(String htmlPage) { JavaScriptSource source = new XomJavaScriptSource(htmlPage); source.evaluateWith(javaScript); triggerOnLoad(); result.readOutput(javaScript); return this; } … }
  • 20. Il risultato public class HtmlScreen implements Screen { private Building building = new Building(10, 10, 40, 50); public String render() { String start = "<html><head>" + " <script type="text/javascript" src="raphael-min.js"></script>" + " <script type="text/javascript" charset="utf-8">" + " window.onload = function() {" + " var map = new Raphael(0,0,600,400);"; String end = "}</script></head><body></body></html>"; return start + building.render() + end; }
  • 21. Mantenere sempre l’omogeneità public class HtmlScreen { ... public String render() { return header() + vectorGraphics.include() + openScript() + openFunction() + vectorGraphics.init() + building.render(vectorGraphics) + closeFunction() + closeScript() + ending(); } ... }
  • 22. Tanti Edifici! @Test public void shouldRenderMultipleBuildings() throws Exception { HtmlScreen htmlScreen = new HtmlScreen(); htmlScreen.addBuilding(10,10,50,40); htmlScreen.addBuilding(80,10,30,40); htmlScreen.addBuilding(10,70,100,40); User user = new User().lookAt(htmlScreen.render()); assertThat(user.currentSight(), is(aRectangle(10, 10, 50, 40))); assertThat(user.currentSight(), is(aRectangle(80, 10, 30, 40))); assertThat(user.currentSight(), is(aRectangle(10, 70, 100, 40))); }
  • 23. Il Personaggio @Test public void shouldRenderACharacter() { HtmlScreen htmlScreen = new HtmlScreen().addCharacter(70,60); User user = new User().lookAt(htmlScreen.render()); assertThat(user.currentSight(), is(aCircle(70, 60, 5))); }
  • 24. Generalizzazione private String renderViewElements() { String renderedElements = ""; for (ViewElement element : viewElements) { renderedElements += element.render(vectorGraphics); } return renderedElements; } L’HtmlScreen smette di parlare di buildings e characters public HtmlScreen addViewElement(ViewElement element) { viewElements.add(element); return this; }
  • 25. Un’ultima volta verso il basso @Test public void shouldBeARedCircle() { GameCharacter character = new GameCharacter(10,10); VectorGraphics vectorGraphics = new TextualVectorGraphics(); assertThat(character.render(vectorGraphics), is("A Circle at [10,10], 5px in diameter")); } public class TextualVectorGraphics implements VectorGraphics { @Override public String rect(int x, int y, int width, int height) { return aRectangle(x,y,width,height); } @Override public String circle(int x, int y, int size) { return aCircle(x,y,size); } }
  • 26. Questo non riguarda solo la vista Un’occhiata al futuro di questa applicazione… Interazione : @Test public void characterShouldMoveOnClick() { String page = Http.callOn(PORT).payload(); user.lookAt(page); user.clickOn(60, 60); page = Http.callOn(PORT).payload(); user.lookAt(page); assertThat(user.currentSight, is("A Circle at [60,60], 5px in diameter")); } Il protocollo si stacca dalla logica del gioco : @Test public void shouldAnswerHttpCall() throws Exception { httpServer = new HttpServer(PORT).publish(boss); assertThat(Http.callOn(PORT), is(HttpAnswer.ok())); }
  • 27. Questo non riguarda solo la vista Avendo le buone primitive ogni asserzione e’ possibile… Arriva la persistenza : @Test public void characterPositionShouldPersist() { Boss boss1 = new Boss(persistence, screen1); boss1.moveCharacterTo(30,30); Boss boss2 = new Boss(persistence, screen2); assertThat(screen2.render(), is("A Circle at [30,30], 5px in diameter")); } Ajax : @Test public void characterShouldMoveOnClick() { page = new HtmlScreen().render(); user.lookAt(page); user.clickOn(60, 60); assertThat(user.currentSight, is("A Circle at [60,60], 5px in diameter")); }