SlideShare uma empresa Scribd logo
1 de 19
Baixar para ler offline
Asynchronen 
Code testen 
@ndrssmn 
Andreas Simon
Synchron 
Übertragungszeit 
Wartezeit 
Bearbeitungszeit 
Wartezeit 
Antwortzeit
Asynchron 
Antwortzeit 
Wartezeit
Fehlertoleranz 
Verfügbarkeit 
Parallelisierung 
Performance 
Event-Driven Architecture
Listening 
Callback
Synchronisation 
TIMEOUT
Listening in JUnit 
@Test public void 
should_reply_with_Fibonacci_numbers() throws Exception { 
// Arrange 
NotificationTrace<Integer> trace = new NotificationTrace<>(TIMEOUT); 
String replyQueue = channel.queueDeclare().getQueue(); 
FibonacciCalculator.create(connection.createChannel()); 
new IntegerConsumer( 
connection.createChannel(), 
trace::append) 
.consumeQueue(replyQueue); 
// Act 
publishNumbers(MIN, MAX, replyQueue); 
// Assert 
trace.containsNotification(equalTo(FIB_MIN)); 
trace.containsNotification(equalTo(FIB_MAX)); 
}
Listening in Mocha 
describe('AMQP Fibonacci service', function() { 
it('calculates fib(' + MIN + ')', function(done) { 
connection.on('ready', function () { 
connection.queue('my-queue', function(q) { 
q.subscribe(function (message) { 
try { 
// Assert 
message.data.toString().should.eql(FIB_MIN); 
done(); 
} catch(e) { 
done(e); 
} 
}); 
// Act 
connection.publish( 
'calculate-fibonacci', MIN, 
{ replyTo: 'my-queue'} 
); 
}); 
}); 
});
Sampling 
POST localhost/ 
CREATED Location: localhost/30 
GET localhost/30 
NOT FOUND 
GET localhost/30 
NOT FOUND 
GET localhost/30 
OK :: 832040 
TIMEOUT
Sampling in JUnit 
@Test public void 
calculates_fib_30() throws Exception { 
// Act 
connection = POST("http://localhost:3000/", "30"); 
fibLocation = connection.getHeaderField("Location"); 
// Assert 
Probe probe = responseTo( 
fibLocation, 
equalTo(Integer.toString(FIB_30)) 
); 
new Poller(TIMEOUT, POLL_DELAY).check(probe); 
}
public class Poller { 
[…] 
public void check(Probe probe) { 
[…] 
while (!probe.isSatisfied()) { 
[…] 
Thread.sleep(pollDelayMillis); 
probe.sample(); 
} 
} 
} 
public interface Probe { 
void sample(); 
boolean isSatisfied(); 
void describeAcceptanceCriteriaTo(Description d); 
void describeFailureTo(Description d); 
}
Sampling in Mocha 
describe('Fibonacci server', function() { 
it('should calculate fib(20)', function(done) { 
var req = http.request(POST_fib, function(res) { 
res.setEncoding('utf8'); 
res.statusCode.should.eql(201); 
res.headers.location.should.be.ok; 
pollGET(res.headers.location, done); 
}).on('error', done); 
req.setHeader('Content-Type', 'application/x-www-form- 
urlencoded;charset=UTF-8'); 
req.write('n=20n'); 
req.end(); 
});
Sampling in Mocha 
function pollGET(url, done) { 
http.get(url, function(res) { 
if(200 != res.statusCode) { 
setTimeout(pollGET, POLL_DELAY, url, done); 
} 
res.on('data', function (chunk) { 
chunk.toString().should.eql('6765'); 
done(); 
}); 
}).on('error', done); 
}
Test the test 
@Test public void 
is_thread_safe() throws Exception { 
latch = startStressing(STRESSING_THREADS, () -> { 
for (int i = 0; i < ITERATIONS; i++) { 
trace.append("NOT-WANTED"); 
Thread.sleep(SLEEPTIME); 
} 
latch.countDown(); 
}); 
scheduler.schedule( 
() -> trace.append("WANTED"), 
100, TimeUnit.MILLISECONDS 
); 
trace.containsNotification(equalTo("WANTED")); 
latch.await(); 
assertThat( 
trace.getAppendCount(), 
is(equalTo((long) STRESSING_THREADS * ITERATIONS + 1)) 
); 
}
Thread-sicher implementieren 
public class NotificationTrace<T> { 
public void append(T message) { 
synchronized (traceLock) { 
trace.add(message); 
traceLock.notifyAll(); 
} 
} 
public void containsNotification(Matcher<? super T> criteria) 
throws AssertionError, InterruptedException { 
Timeout timeout = new Timeout(timeoutMs); 
synchronized (traceLock) { 
stream = new NotificationStream<>(trace, criteria); 
while (!stream.hasMatched()) { 
if (timeout.hasTimedOut()) { 
throw new AssertionError(); 
} 
timeout.waitOn(traceLock); 
} 
} 
}
Aufräumen 
@After 
public void tearDown() throws InterruptedException { 
executorService.shutdownNow(); 
scheduler.shutdownNow(); 
}
Fazit 
Listening vs. Sampling 
Synchronisierungsmechanismen kapseln (und durch Unit-Tests 
validieren) 
Brian Goetz: "Java Concurrency in Practice" 
Nat Pryce, Steve Freeman: "Growing Object-Oriented Software" 
https://github.com/andreassimon/talk-asynchronen-code-testen
Quagilis 
Andreas Simon 
Lazarettstr. 9 
48147 Münster 
Fon +49 (0) 251 - 590 491 55-0 
Fax +49 (0) 251 - 590 491 55-9 
a.simon@quagilis.de 
http://www.quagilis.de 
Quality in Agile.

Mais conteúdo relacionado

Mais procurados

for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...
hwbloom59
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
Tony Fabeen
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
lestrrat
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )
Joseph Scott
 

Mais procurados (20)

OWASP Proxy
OWASP ProxyOWASP Proxy
OWASP Proxy
 
for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...for this particular program how do i create the input innotepad 1st ? #includ...
for this particular program how do i create the input innotepad 1st ? #includ...
 
Gevent rabbit rpc
Gevent rabbit rpcGevent rabbit rpc
Gevent rabbit rpc
 
Relayd: a load balancer for OpenBSD
Relayd: a load balancer for OpenBSD Relayd: a load balancer for OpenBSD
Relayd: a load balancer for OpenBSD
 
Introducing to Asynchronous Programming
Introducing to Asynchronous  ProgrammingIntroducing to Asynchronous  Programming
Introducing to Asynchronous Programming
 
for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...for this particular program how do i create the input innotepad 1st ?#include...
for this particular program how do i create the input innotepad 1st ?#include...
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
The Ring programming language version 1.10 book - Part 35 of 212
The Ring programming language version 1.10 book - Part 35 of 212The Ring programming language version 1.10 book - Part 35 of 212
The Ring programming language version 1.10 book - Part 35 of 212
 
Send mail-oracle11g-det
Send mail-oracle11g-detSend mail-oracle11g-det
Send mail-oracle11g-det
 
Shell Script Disk Usage Report and E-Mail Current Threshold Status
Shell Script  Disk Usage Report and E-Mail Current Threshold StatusShell Script  Disk Usage Report and E-Mail Current Threshold Status
Shell Script Disk Usage Report and E-Mail Current Threshold Status
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )
 
The Ring programming language version 1.2 book - Part 16 of 84
The Ring programming language version 1.2 book - Part 16 of 84The Ring programming language version 1.2 book - Part 16 of 84
The Ring programming language version 1.2 book - Part 16 of 84
 
Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it
 
Cooking pies with Celery
Cooking pies with CeleryCooking pies with Celery
Cooking pies with Celery
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The Answer
 
Perl web app 테스트전략
Perl web app 테스트전략Perl web app 테스트전략
Perl web app 테스트전략
 
とにかく始めるClojure
とにかく始めるClojureとにかく始めるClojure
とにかく始めるClojure
 
Python event based network sniffer
Python event based network snifferPython event based network sniffer
Python event based network sniffer
 
ZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made SimpleZeroMQ: Messaging Made Simple
ZeroMQ: Messaging Made Simple
 

Destaque

Event Driven - Node.JS
Event Driven - Node.JSEvent Driven - Node.JS
Event Driven - Node.JS
Mike Bild
 
Buscadores y metabuscadores
Buscadores y metabuscadores Buscadores y metabuscadores
Buscadores y metabuscadores
Ddbere
 
Forderung arbeitnehmer 2012
Forderung arbeitnehmer 2012Forderung arbeitnehmer 2012
Forderung arbeitnehmer 2012
brassist
 
Socialmediarecruiting2015 120626023458 Phpapp02
Socialmediarecruiting2015 120626023458 Phpapp02Socialmediarecruiting2015 120626023458 Phpapp02
Socialmediarecruiting2015 120626023458 Phpapp02
dhoncu
 
Singaña vanessa analizar software educativo
Singaña vanessa analizar software educativoSingaña vanessa analizar software educativo
Singaña vanessa analizar software educativo
vane01si
 

Destaque (20)

Event Driven - Node.JS
Event Driven - Node.JSEvent Driven - Node.JS
Event Driven - Node.JS
 
Classifications in IBM Maximo Asset Management
Classifications in IBM Maximo Asset ManagementClassifications in IBM Maximo Asset Management
Classifications in IBM Maximo Asset Management
 
IBM Mobility Strategie - Zukunft der Informationstechnologie
IBM Mobility Strategie - Zukunft der InformationstechnologieIBM Mobility Strategie - Zukunft der Informationstechnologie
IBM Mobility Strategie - Zukunft der Informationstechnologie
 
Meters in IBM Maximo Asset Management
Meters in IBM Maximo Asset ManagementMeters in IBM Maximo Asset Management
Meters in IBM Maximo Asset Management
 
Buscadores y metabuscadores
Buscadores y metabuscadores Buscadores y metabuscadores
Buscadores y metabuscadores
 
Catalogo Calzados Narrow Invierno 2015
Catalogo Calzados Narrow Invierno 2015Catalogo Calzados Narrow Invierno 2015
Catalogo Calzados Narrow Invierno 2015
 
Das museum
Das museumDas museum
Das museum
 
Forderung arbeitnehmer 2012
Forderung arbeitnehmer 2012Forderung arbeitnehmer 2012
Forderung arbeitnehmer 2012
 
Importancia de la computación
Importancia de la computaciónImportancia de la computación
Importancia de la computación
 
Presentación
PresentaciónPresentación
Presentación
 
Socialmediarecruiting2015 120626023458 Phpapp02
Socialmediarecruiting2015 120626023458 Phpapp02Socialmediarecruiting2015 120626023458 Phpapp02
Socialmediarecruiting2015 120626023458 Phpapp02
 
Nancy nucete
Nancy nucete Nancy nucete
Nancy nucete
 
El internet
El internetEl internet
El internet
 
La Web 2.0
La Web 2.0 La Web 2.0
La Web 2.0
 
Rubrica competencia siglo 21
Rubrica competencia siglo 21Rubrica competencia siglo 21
Rubrica competencia siglo 21
 
CV ALDO SAAVEDRA
CV ALDO SAAVEDRACV ALDO SAAVEDRA
CV ALDO SAAVEDRA
 
Singaña vanessa analizar software educativo
Singaña vanessa analizar software educativoSingaña vanessa analizar software educativo
Singaña vanessa analizar software educativo
 
Grandes entrenadores baloncesto
Grandes entrenadores baloncestoGrandes entrenadores baloncesto
Grandes entrenadores baloncesto
 
Proyecto tic digaroba
Proyecto tic digarobaProyecto tic digaroba
Proyecto tic digaroba
 
LA WEB 2.0 Y NUESTRA VISIÓN INTEGRAL
LA WEB 2.0 Y NUESTRA VISIÓN INTEGRALLA WEB 2.0 Y NUESTRA VISIÓN INTEGRAL
LA WEB 2.0 Y NUESTRA VISIÓN INTEGRAL
 

Semelhante a Asynchronen Code testen

Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
Fwdays
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
 

Semelhante a Asynchronen Code testen (20)

Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Unit testing CourseSites Apache Filter
Unit testing CourseSites Apache FilterUnit testing CourseSites Apache Filter
Unit testing CourseSites Apache Filter
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015Akka Cluster in Java - JCConf 2015
Akka Cluster in Java - JCConf 2015
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Creating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdfCreating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdf
 
Embracing the-power-of-refactor
Embracing the-power-of-refactorEmbracing the-power-of-refactor
Embracing the-power-of-refactor
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In Depth
 
Jersey Guice AOP
Jersey Guice AOPJersey Guice AOP
Jersey Guice AOP
 
Ajax - a quick introduction
Ajax - a quick introductionAjax - a quick introduction
Ajax - a quick introduction
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
Distributed load testing with k6
Distributed load testing with k6Distributed load testing with k6
Distributed load testing with k6
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express Middleware
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Último (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
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...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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?
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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...
 
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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
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
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

Asynchronen Code testen

  • 1. Asynchronen Code testen @ndrssmn Andreas Simon
  • 2. Synchron Übertragungszeit Wartezeit Bearbeitungszeit Wartezeit Antwortzeit
  • 4. Fehlertoleranz Verfügbarkeit Parallelisierung Performance Event-Driven Architecture
  • 6.
  • 8. Listening in JUnit @Test public void should_reply_with_Fibonacci_numbers() throws Exception { // Arrange NotificationTrace<Integer> trace = new NotificationTrace<>(TIMEOUT); String replyQueue = channel.queueDeclare().getQueue(); FibonacciCalculator.create(connection.createChannel()); new IntegerConsumer( connection.createChannel(), trace::append) .consumeQueue(replyQueue); // Act publishNumbers(MIN, MAX, replyQueue); // Assert trace.containsNotification(equalTo(FIB_MIN)); trace.containsNotification(equalTo(FIB_MAX)); }
  • 9. Listening in Mocha describe('AMQP Fibonacci service', function() { it('calculates fib(' + MIN + ')', function(done) { connection.on('ready', function () { connection.queue('my-queue', function(q) { q.subscribe(function (message) { try { // Assert message.data.toString().should.eql(FIB_MIN); done(); } catch(e) { done(e); } }); // Act connection.publish( 'calculate-fibonacci', MIN, { replyTo: 'my-queue'} ); }); }); });
  • 10. Sampling POST localhost/ CREATED Location: localhost/30 GET localhost/30 NOT FOUND GET localhost/30 NOT FOUND GET localhost/30 OK :: 832040 TIMEOUT
  • 11. Sampling in JUnit @Test public void calculates_fib_30() throws Exception { // Act connection = POST("http://localhost:3000/", "30"); fibLocation = connection.getHeaderField("Location"); // Assert Probe probe = responseTo( fibLocation, equalTo(Integer.toString(FIB_30)) ); new Poller(TIMEOUT, POLL_DELAY).check(probe); }
  • 12. public class Poller { […] public void check(Probe probe) { […] while (!probe.isSatisfied()) { […] Thread.sleep(pollDelayMillis); probe.sample(); } } } public interface Probe { void sample(); boolean isSatisfied(); void describeAcceptanceCriteriaTo(Description d); void describeFailureTo(Description d); }
  • 13. Sampling in Mocha describe('Fibonacci server', function() { it('should calculate fib(20)', function(done) { var req = http.request(POST_fib, function(res) { res.setEncoding('utf8'); res.statusCode.should.eql(201); res.headers.location.should.be.ok; pollGET(res.headers.location, done); }).on('error', done); req.setHeader('Content-Type', 'application/x-www-form- urlencoded;charset=UTF-8'); req.write('n=20n'); req.end(); });
  • 14. Sampling in Mocha function pollGET(url, done) { http.get(url, function(res) { if(200 != res.statusCode) { setTimeout(pollGET, POLL_DELAY, url, done); } res.on('data', function (chunk) { chunk.toString().should.eql('6765'); done(); }); }).on('error', done); }
  • 15. Test the test @Test public void is_thread_safe() throws Exception { latch = startStressing(STRESSING_THREADS, () -> { for (int i = 0; i < ITERATIONS; i++) { trace.append("NOT-WANTED"); Thread.sleep(SLEEPTIME); } latch.countDown(); }); scheduler.schedule( () -> trace.append("WANTED"), 100, TimeUnit.MILLISECONDS ); trace.containsNotification(equalTo("WANTED")); latch.await(); assertThat( trace.getAppendCount(), is(equalTo((long) STRESSING_THREADS * ITERATIONS + 1)) ); }
  • 16. Thread-sicher implementieren public class NotificationTrace<T> { public void append(T message) { synchronized (traceLock) { trace.add(message); traceLock.notifyAll(); } } public void containsNotification(Matcher<? super T> criteria) throws AssertionError, InterruptedException { Timeout timeout = new Timeout(timeoutMs); synchronized (traceLock) { stream = new NotificationStream<>(trace, criteria); while (!stream.hasMatched()) { if (timeout.hasTimedOut()) { throw new AssertionError(); } timeout.waitOn(traceLock); } } }
  • 17. Aufräumen @After public void tearDown() throws InterruptedException { executorService.shutdownNow(); scheduler.shutdownNow(); }
  • 18. Fazit Listening vs. Sampling Synchronisierungsmechanismen kapseln (und durch Unit-Tests validieren) Brian Goetz: "Java Concurrency in Practice" Nat Pryce, Steve Freeman: "Growing Object-Oriented Software" https://github.com/andreassimon/talk-asynchronen-code-testen
  • 19. Quagilis Andreas Simon Lazarettstr. 9 48147 Münster Fon +49 (0) 251 - 590 491 55-0 Fax +49 (0) 251 - 590 491 55-9 a.simon@quagilis.de http://www.quagilis.de Quality in Agile.