SlideShare une entreprise Scribd logo
1  sur  51
Extreme Testing at kaChing 
From Commit to Production in 5 minutes 
                   
      Pascal‐Louis Perez –               .com 




               Pascal‐Louis Perez, kaChing Group Inc. 
kaChing: the Investing Talent Marketplace 

• Marketplace for qualified managers 
  – Young professionals 
  – RIAs 
  – Hedge Fund managers 
• Customers can mirror “kaChing Geniuses” 
  – Your own brokerage account 
  – Real time reporting; Analytics; Drift alerts 
• Unparalleled Transparency 
  – See everything: holdings, risk metrics, trades, … 
  – Clear fee structure: management fee. No hidden fees, 
    exit fees, … 
                    Pascal‐Louis Perez, kaChing Group Inc. 
 




    Pascal‐Louis Perez, kaChing Group Inc. 
Our System in 30 Seconds 




       Pascal‐Louis Perez, kaChing Group Inc. 
Testing Matters 

                   Architectural Soundness 
Delighting Customers 




               Pascal‐Louis Perez, kaChing Group Inc. 
Testable Code Because… 
• It allows quick iterations 
• It makes it easier to scale the team 
• It is more cost effective than debugging 
• It obsoletes the need for functional QA 
• It facilitates continuous refactoring, allowing 
  the code to get better with age 
• It attracts the right kind of engineers 

                  Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ 

π 



        Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ      • Bad: incorrect  but available system 
       • Bad: correct but unavailable system 


π 



        Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                     Availability 
     • Transformations (λ) 
λ    • Interactions (π): send an e‐mail, 
     store data in a db, RPC call 
     • In π implicit global mutable state 

π 



          Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ 
       • Simplest to test 
       • Input produces an output: just assert 
π      • (Not  to be confused with 
       implementation complexity!) 




        Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ 
                              • Transformations can only be CPU 
π                             bound 
                              • Timing tests, benchmarking, … 




        Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ 

π 
       • Key idea: fake the world 
       • Mocks, stubs, fakes 



        Pascal‐Louis Perez, kaChing Group Inc. 
High Level Classification 

     Correctness                   Availability 

λ 

π 
             • Work in small batches 
             • End‐to‐end tests, regression test, 
             performance lab 
             (Find yourself a great architect!) 


        Pascal‐Louis Perez, kaChing Group Inc. 
Think Outside the Box 
                          C               A 
               λ 
               π 

          A                                                   C    A 
     C 
λ                                                        λ 

π                                                        π 
                           C               A 
               λ 
               π 

               Pascal‐Louis Perez, kaChing Group Inc. 
Repository (or Client) Pattern 

     C    A    @ImplementedBy(DbUserRepo.class)
λ              interface UserRepository {
π                User get(Id<User> id);
               }

               UserRepository repo = ...;
               User pascal = repo.get(Id.<User> of(8));



     C    A    class DbUserRepo
λ                  implements UserRepository {
π                // implementation
               }


                      Pascal‐Louis Perez, kaChing Group Inc. 
Components 
• Software composability is key to test‐driven 
  development 
• Testable software abstracts the control flow; 
  As such is functional by nature 




                 Pascal‐Louis Perez, kaChing Group Inc. 
Examples of Simple Tests 
• Marshalling tests 
• Dealing with time 
• Equivalence tester 




                 Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                               λ 



               Marshalling tests 
                                                               π 




Json.Object o =                     Fail fast 
    TwoLattes.createMarshaller(Trade.class).marshall(...);

assertSameJson(
    object(
         string("id"), number(4),
         string("portfolioId"), NULL,
         string("trade"), string("interest"),
         string("date"), string("2008-07-06"),
         string("toDate"), string("2008-06-06"),
         string("fromDate"), string("2008-07-05"),
         string("longInterest"), number(56.43),
         string("shortInterest"), number(-0.81)),
    o); 



                     Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                               λ 



               Marshalling tests 
                                                               π 




Json.Object o =
    TwoLattes.createMarshaller(Trade.class).marshall(...);

assertSameJson(         Dedicated assertions 
    object(
         string("id"), number(4),
         string("portfolioId"), NULL,
         string("trade"), string("interest"),
         string("date"), string("2008-07-06"),
         string("toDate"), string("2008-06-06"),
         string("fromDate"), string("2008-07-05"),
         string("longInterest"), number(56.43),
         string("shortInterest"), number(-0.81)),
    o); 



                     Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                  λ 



                 Marshalling tests 
                                                                  π 




Json.Object o =
    TwoLattes.createMarshaller(Trade.class).marshall(...);

assertSameJson(                 Descriptive expectation 
    object(
         string("id"), number(4),
         string("portfolioId"), NULL,
         string("trade"), string("interest"),
         string("date"), string("2008-07-06"),
         string("toDate"), string("2008-06-06"),
         string("fromDate"), string("2008-07-05"),
         string("longInterest"), number(56.43),
         string("shortInterest"), number(-0.81)),
    o); 



                        Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                           λ 



            Dealing with time 
                                                           π 




• Use clocks 
  – Provider<DateTime> 
  – Provider<LocalDate> 
• Pass in now or today in business logic 




                 Pascal‐Louis Perez, kaChing Group Inc. 
Time Logic 

@VisibleForTesting
<T> T provideCurrentOrHistorical(
     DateTime date, Provider<T> current, Provider<T> historical) {
   DateTime lastTradeDate = getLastTradeDate();  Time logic is easy 
   boolean isCurrent = date == null                  to test 
       || lastTradeDate == null
       || date.compareTo(lastTradeDate) > 0;
   return isCurrent ? current.get() : historical.get();
} 




                         Pascal‐Louis Perez, kaChing Group Inc. 
Time Logic 

@VisibleForTesting
<T> T provideCurrentOrHistorical(              Higher‐order functions 
     DateTime date, Provider<T> current, Provider<T> historical) {
   DateTime lastTradeDate = getLastTradeDate();
   boolean isCurrent = date == null
       || lastTradeDate == null
       || date.compareTo(lastTradeDate) > 0;
   return isCurrent ? current.get() : historical.get();
} 




                          Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                                 λ 



           Equivalence Tester 
                                                                                 π 




EquivalenceTester.check(                                    Tests 
    asList(                                                  Reflexivity 
        new Isin("abCdEFgHiJK3“),                            Symmetry 
        new Isin("ABCDEFGHIJK3“),                            Transitivity 
        new Isin(“abCDefGHIJK3")),                            hashCode consistency 
    asList(
        new Isin("AU0000XVGZA3"),
        new Isin("AU0000XVGZA3"))); 




                  Pascal‐Louis Perez, kaChing Group Inc. 
Rationale for Database Testing 
•   Accessing the database correctly 
•   O/R properly configured and used 
•   Hand written queries 
•   Optimistic concurrency 




                  Pascal‐Louis Perez, kaChing Group Inc. 
JDBC 
                                                                Global static state 
DriverManager.registerDriver(new org.gjt.mm.mysql.Driver());
Connection conn = DriverManager.getConnection("jdbc:...");
PreparedStatement st = conn.prepareStatement("select ...");
st.setString(1, "...");
ResultSet rs = st.executeQuery();
while (rs.next()) {
  // work
}
rs.close();
st.close();
conn.close(); 




                     Pascal‐Louis Perez, kaChing Group Inc. 
JDBC 

DriverManager.registerDriver(new org.gjt.mm.mysql.Driver());
Connection conn = DriverManager.getConnection("jdbc:...");
PreparedStatement st = conn.prepareStatement("select ...");
st.setString(1, "...");
ResultSet rs = st.executeQuery();
while (rs.next()) {
  // work
}
rs.close();
                                 Low level, stateful API, wide scoping 
st.close();
conn.close(); 




                         Pascal‐Louis Perez, kaChing Group Inc. 
JDBC 

DriverManager.registerDriver(new org.gjt.mm.mysql.Driver());
Connection conn = DriverManager.getConnection("jdbc:...");
PreparedStatement st = conn.prepareStatement("select ...");
st.setString(1, "...");
ResultSet rs = st.executeQuery();
while (rs.next()) {
  // work
}                                                Resources hell 
rs.close();
st.close();
conn.close(); 




                      Pascal‐Louis Perez, kaChing Group Inc. 
Hibernate 
                                                               Global state 
SessionFactory factory = ...;
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
List<User> users = session
    .createQuery("from User where ...")
    .list();
 for (User user : users) {
   // work
 }
 tx.commit();
 session.close(); 




                    Pascal‐Louis Perez, kaChing Group Inc. 
Hibernate 

SessionFactory factory = ...;                                  High‐level API 
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
List<User> users = session
    .createQuery("from User where ...")
    .list();
 for (User user : users) {
   // work
 }
 tx.commit();
 session.close(); 




                    Pascal‐Louis Perez, kaChing Group Inc. 
Hibernate 

SessionFactory factory = ...;
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
List<User> users = session
    .createQuery("from User where ...")
    .list();
 for (User user : users) {
   // work
 }                                                             Resources hell 
 tx.commit();
 session.close(); 




                    Pascal‐Louis Perez, kaChing Group Inc. 
Transacter 
                                                              Global state 
Transacter transacter = ...;
transacter.execute(new WithSession() {
  public void run(Session session) {
     List<User> users = ...;
     for (User user : users) {
       // work
     }
  }
}); 




                   Pascal‐Louis Perez, kaChing Group Inc. 
Transacter 

Transacter transacter = ...;          High‐level API, no resources 
transacter.execute(new WithSession() {
  public void run(Session session) {
     List<User> users = ...;
     for (User user : users) {
       // work
     }
  }
}); 




                      Pascal‐Louis Perez, kaChing Group Inc. 
Transacter 

Transacter transacter = ...;
transacter.execute(new WithSession() {
  public void run(Session session) {  Lexical scoping 
     List<User> users = ...;
     for (User user : users) {
       // work
     }
  }
}); 




                     Pascal‐Louis Perez, kaChing Group Inc. 
Database Testing is Hard 
•   Complex to set up : PersistenceTestRunner 
•   Schema installation : O/R Mapping 
•   Requires data to be loaded : Fixtures, DbUnit 
•   Developer must have proper environment 
    : in‐memory DBs (HSQLDB, Connector/MXJ) 




                  Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                             λ 



         PersistenceTestRunner 
                                                             π 




@RunWith(PersistenceTestRunner.class)     Declarative setup 
@PersistentEntities({Item.class, Note.class})
public class ExamplePersistentTest {

    @Test
    public void example1(Transacter transacter) {
      // work
    }

    @Test
    public void example2() {
      // work
    }

}


                   Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                             λ 



         PersistenceTestRunner 
                                                             π 




@RunWith(PersistenceTestRunner.class)
@PersistentEntities({Item.class, Note.class})
public class ExamplePersistentTest {
                                           Lexical scoping 
  @Test
  public void example1(Transacter transacter) {
    // work
  }

    @Test
    public void example2() {
      // work
    }

}


                   Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                               λ 



         PersistenceTestRunner 
                                                               π 




@RunWith(PersistenceTestRunner.class)
@PersistentEntities({Item.class, Note.class})
public class ExamplePersistentTest {

    @Test                           RuntimeException 
    public void example1(Transacter transacter) {
      // work
    }

    @Test
    public void example2() {
      // work
    }

}


                     Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                 λ 



          PersistenceTestRunner 
                                                                 π 




@RunWith(PersistenceTestRunner.class)
@PersistentEntities({Item.class, Note.class})
public class ExamplePersistentTest {

    @Test
    public void example1(Transacter transacter) {
      // work
    }
                                 Non‐persistent tests run as usual 
    @Test
    public void example2() {
      // work
    }

}


                      Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                            λ 



     Testing Interactions (I/O, …) 
                                                            π 




• Implicit global state 
• Many cases 
  – HTTP GET: succeed, fail to connect, connection 
    closed before headers are read, … 
  – Sending e‐mail: succeed, connection lost after 
    HELO, … 
• Sequencing is crucial 


                  Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                      λ 



   Testing the Transacter (success) 
                                                                      π 




                                                                 Mocking 
final WithSession withSession = mockery.mock(WithSession.class);
mockery.checking(new Expectations() {{
  one(sessionFactory).openSession();
      will(returnValue(session));
      inSequence(execution);
  one(session).connection(); will(...); inSequence(...);
  one(connection).setReadOnly(with(equal(false))); ...
  one(connection).setAutoCommit(with(equal(false))); ...
  one(session).beginTransaction(); inSequence(...);
  ...
}});

transacter.execute(withSession);

mockery.assertIsSatisfied();

                      Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                 λ 



   Testing the Transacter (success) 
                                                                 π 




final WithSession withSession = mockery.mock(WithSession.class);
mockery.checking(new Expectations() {{
  one(sessionFactory).openSession();
                                       Interactions are scripted 
      will(returnValue(session));
      inSequence(execution);
  one(session).connection(); will(...); inSequence(...);
  one(connection).setReadOnly(with(equal(false))); ...
  one(connection).setAutoCommit(with(equal(false))); ...
  one(session).beginTransaction(); inSequence(...);
  ...
}});

transacter.execute(withSession);

mockery.assertIsSatisfied();

                       Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                   λ 



      Testing the Transacter (failure) 
                                                                   π 




mockery.checking(new Expectations() {{
  one(sessionFactory).openSession();
                                        Failure is controlled 
  ...

  one(connection).setReadOnly(with(equal(false)));
      will(throwException(exception));
      inSequence(execution);

  one(session).close(); inSequence(execution);
}});

try {
  transacter.execute(withSession); fail();
} catch (RuntimeException e) {
  assertTrue(e == exception);
}
 mockery.assertIsSatisfied();
                         Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                      λ 



       Testing the Transacter (failure) 
                                                                      π 




mockery.checking(new Expectations() {{
  one(sessionFactory).openSession();
  ...

  one(connection).setReadOnly(with(equal(false)));
      will(throwException(exception));
      inSequence(execution);

  one(session).close(); inSequence(execution);
}});

try {
  transacter.execute(withSession); fail();
} catch (RuntimeException e) {
  assertTrue(e == exception);    Exact  same object (correct bubbling) 
}
 mockery.assertIsSatisfied();
                           Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                                   λ 



      Testing the Transacter (failure) 
                                                                   π 




mockery.checking(new Expectations() {{
  one(sessionFactory).openSession();
  ...

  one(connection).setReadOnly(with(equal(false)));
      will(throwException(exception));
      inSequence(execution);

  one(session).close(); inSequence(execution);
}});
                                     Unreachable program point 
try {
  transacter.execute(withSession); fail();
} catch (RuntimeException e) {
  assertTrue(e == exception);
}
 mockery.assertIsSatisfied();
                         Pascal‐Louis Perez, kaChing Group Inc. 
Meta Tests 
• Cross domain tests to sweep the codebase, 
  exactly like static analysis 
• Catch common mistakes 
      – Distracted developers 
      – Bad APIs 
      – New hires learning conventions 
   


                      Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                           λ 



            Dependency Test 
                                                           π 




• Declare software dependencies 
• Controls layering of application 
• Simpler and more flexible than different 
  compilation units 
• Can guarantee that certain APIs are not used 
  directly 
• Patched Jdepend to parse annotations 


                 Pascal‐Louis Perez, kaChing Group Inc. 
Dependency Test 
dependencies.forPackages(
        "com.kaching.*"
        ).

check("com.kaching.supermap").mayDependOn(
        "com.kaching.platform.guice",
        "org.apache.commons.lang",
        "voldemort.*",
        "org.kohsuke.args4j"
        ).

assertIsVerified(jDepend.getPackages());




                Pascal‐Louis Perez, kaChing Group Inc. 
C    A 
                                                             λ 



                Bad Code Test 
                                                             π 




• Enforce conventions 
• Gotchas, bad APIs 
  – E.g. System.out.println 
  – E.g. java.net.URL 
• Code reviews 
  – Design patterns, custom APIs, etc. 
  – Enforce conventions: automate this! 


                   Pascal‐Louis Perez, kaChing Group Inc. 
Bad Code Test 
@RunWith(BadCodeSnippetsRunner.class)
@CodeSnippets({
@Check(paths = "src/com/kaching", snippets = {

    // no uses of java.net.URL
    @Snippet(value = "bjava.net.URLb", exceptions = {
        "src/com/kaching/...",
        "src/com/kaching/..."
    }),

    // never call default super constructor
    @Snippet("super()")
})})
class MyBadCodeSnippetsTest {




                     Pascal‐Louis Perez, kaChing Group Inc. 
Key Takeaways 
•   Invest in your tests, and testing frameworks 
•   Design patterns to separate concerns 
•   Components 
•   TDD pushes towards functional techniques 
 
•   We’re recruiting jobs@kaching.com 
•   More http://eng.kaching.com 

                   Pascal‐Louis Perez, kaChing Group Inc. 

Contenu connexe

Similaire à Extreme Testing at kaChing

ScalaCheck
ScalaCheckScalaCheck
ScalaCheck
BeScala
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
shinolajla
 
Alexei shilov 2010 rit-rakudo
Alexei shilov 2010 rit-rakudoAlexei shilov 2010 rit-rakudo
Alexei shilov 2010 rit-rakudo
rit2010
 
Jonathan Worthington – Perl 2010 Rit Rakudo
Jonathan Worthington – Perl 2010 Rit RakudoJonathan Worthington – Perl 2010 Rit Rakudo
Jonathan Worthington – Perl 2010 Rit Rakudo
rit2010
 

Similaire à Extreme Testing at kaChing (20)

Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Aaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security TeamsAaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security Teams
 
Kpi driven-java-development-fn conf
Kpi driven-java-development-fn confKpi driven-java-development-fn conf
Kpi driven-java-development-fn conf
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An Analysis
 
ScalaCheck
ScalaCheckScalaCheck
ScalaCheck
 
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
 
Boost.Python - domesticating the snake
Boost.Python - domesticating the snakeBoost.Python - domesticating the snake
Boost.Python - domesticating the snake
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
Pattern Matching in Java 14
Pattern Matching in Java 14Pattern Matching in Java 14
Pattern Matching in Java 14
 
JavaParser - A tool to generate, analyze and refactor Java code
JavaParser - A tool to generate, analyze and refactor Java codeJavaParser - A tool to generate, analyze and refactor Java code
JavaParser - A tool to generate, analyze and refactor Java code
 
Alexei shilov 2010 rit-rakudo
Alexei shilov 2010 rit-rakudoAlexei shilov 2010 rit-rakudo
Alexei shilov 2010 rit-rakudo
 
Jonathan Worthington – Perl 2010 Rit Rakudo
Jonathan Worthington – Perl 2010 Rit RakudoJonathan Worthington – Perl 2010 Rit Rakudo
Jonathan Worthington – Perl 2010 Rit Rakudo
 
Introducing Kogito
Introducing KogitoIntroducing Kogito
Introducing Kogito
 
Scaling Scala to the database - Stefan Zeiger (Typesafe)
Scaling Scala to the database - Stefan Zeiger (Typesafe)Scaling Scala to the database - Stefan Zeiger (Typesafe)
Scaling Scala to the database - Stefan Zeiger (Typesafe)
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring tests
 
An Introduction to Property Based Testing
An Introduction to Property Based TestingAn Introduction to Property Based Testing
An Introduction to Property Based Testing
 
Cascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUGCascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUG
 
3 Dundee-Spark Overview for C* developers
3 Dundee-Spark Overview for C* developers3 Dundee-Spark Overview for C* developers
3 Dundee-Spark Overview for C* developers
 
Cassandra Summit EU 2014 - Testing Cassandra Applications
Cassandra Summit EU 2014 - Testing Cassandra ApplicationsCassandra Summit EU 2014 - Testing Cassandra Applications
Cassandra Summit EU 2014 - Testing Cassandra Applications
 

Plus de Pascal-Louis Perez

SLL Conf - Continuous Deployment
SLL Conf - Continuous DeploymentSLL Conf - Continuous Deployment
SLL Conf - Continuous Deployment
Pascal-Louis Perez
 
Alchemist Startup Primer - Lean Development Practices
Alchemist Startup Primer - Lean Development PracticesAlchemist Startup Primer - Lean Development Practices
Alchemist Startup Primer - Lean Development Practices
Pascal-Louis Perez
 
Xignite's Dedicate kaChing Api
Xignite's Dedicate kaChing ApiXignite's Dedicate kaChing Api
Xignite's Dedicate kaChing Api
Pascal-Louis Perez
 

Plus de Pascal-Louis Perez (12)

Fuchsia RFCs
Fuchsia RFCsFuchsia RFCs
Fuchsia RFCs
 
Products’ Love Story with Biz
Products’ Love Story with BizProducts’ Love Story with Biz
Products’ Love Story with Biz
 
How to Send a Receipt, Topics in Concurrency and Distributed Systems
How to Send a Receipt, Topics in Concurrency and Distributed SystemsHow to Send a Receipt, Topics in Concurrency and Distributed Systems
How to Send a Receipt, Topics in Concurrency and Distributed Systems
 
Corporate Finance Primer
Corporate Finance PrimerCorporate Finance Primer
Corporate Finance Primer
 
Developing an Immune System — The Hard and Soft Skills required to avoid Outages
Developing an Immune System — The Hard and Soft Skills required to avoid OutagesDeveloping an Immune System — The Hard and Soft Skills required to avoid Outages
Developing an Immune System — The Hard and Soft Skills required to avoid Outages
 
SLL Conf - Continuous Deployment
SLL Conf - Continuous DeploymentSLL Conf - Continuous Deployment
SLL Conf - Continuous Deployment
 
Alchemist Startup Primer - Lean Development Practices
Alchemist Startup Primer - Lean Development PracticesAlchemist Startup Primer - Lean Development Practices
Alchemist Startup Primer - Lean Development Practices
 
Database compatibility
Database compatibilityDatabase compatibility
Database compatibility
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
Type Checking JavaScript
Type Checking JavaScriptType Checking JavaScript
Type Checking JavaScript
 
Xignite's Dedicate kaChing Api
Xignite's Dedicate kaChing ApiXignite's Dedicate kaChing Api
Xignite's Dedicate kaChing Api
 
kaChing's API garage event
kaChing's API garage eventkaChing's API garage event
kaChing's API garage event
 

Dernier

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Dernier (20)

Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
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...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
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
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 

Extreme Testing at kaChing

  • 1. Extreme Testing at kaChing  From Commit to Production in 5 minutes    Pascal‐Louis Perez –               .com  Pascal‐Louis Perez, kaChing Group Inc. 
  • 2. kaChing: the Investing Talent Marketplace  • Marketplace for qualified managers  – Young professionals  – RIAs  – Hedge Fund managers  • Customers can mirror “kaChing Geniuses”  – Your own brokerage account  – Real time reporting; Analytics; Drift alerts  • Unparalleled Transparency  – See everything: holdings, risk metrics, trades, …  – Clear fee structure: management fee. No hidden fees,  exit fees, …  Pascal‐Louis Perez, kaChing Group Inc. 
  • 3.   Pascal‐Louis Perez, kaChing Group Inc. 
  • 4. Our System in 30 Seconds  Pascal‐Louis Perez, kaChing Group Inc. 
  • 5. Testing Matters  Architectural Soundness  Delighting Customers  Pascal‐Louis Perez, kaChing Group Inc. 
  • 6. Testable Code Because…  • It allows quick iterations  • It makes it easier to scale the team  • It is more cost effective than debugging  • It obsoletes the need for functional QA  • It facilitates continuous refactoring, allowing  the code to get better with age  • It attracts the right kind of engineers  Pascal‐Louis Perez, kaChing Group Inc. 
  • 7. High Level Classification  Correctness  Availability  λ  π  Pascal‐Louis Perez, kaChing Group Inc. 
  • 8. High Level Classification  Correctness  Availability  λ  • Bad: incorrect  but available system  • Bad: correct but unavailable system  π  Pascal‐Louis Perez, kaChing Group Inc. 
  • 9. High Level Classification  Correctness  Availability  • Transformations (λ)  λ  • Interactions (π): send an e‐mail,  store data in a db, RPC call  • In π implicit global mutable state  π  Pascal‐Louis Perez, kaChing Group Inc. 
  • 10. High Level Classification  Correctness  Availability  λ  • Simplest to test  • Input produces an output: just assert  π  • (Not  to be confused with  implementation complexity!)  Pascal‐Louis Perez, kaChing Group Inc. 
  • 11. High Level Classification  Correctness  Availability  λ  • Transformations can only be CPU  π  bound  • Timing tests, benchmarking, …  Pascal‐Louis Perez, kaChing Group Inc. 
  • 12. High Level Classification  Correctness  Availability  λ  π  • Key idea: fake the world  • Mocks, stubs, fakes  Pascal‐Louis Perez, kaChing Group Inc. 
  • 13. High Level Classification  Correctness  Availability  λ  π  • Work in small batches  • End‐to‐end tests, regression test,  performance lab  (Find yourself a great architect!)  Pascal‐Louis Perez, kaChing Group Inc. 
  • 14. Think Outside the Box  C  A  λ  π  A  C  A  C  λ  λ  π  π  C  A  λ  π  Pascal‐Louis Perez, kaChing Group Inc. 
  • 15. Repository (or Client) Pattern  C  A  @ImplementedBy(DbUserRepo.class) λ  interface UserRepository { π  User get(Id<User> id); } UserRepository repo = ...; User pascal = repo.get(Id.<User> of(8)); C  A  class DbUserRepo λ  implements UserRepository { π  // implementation } Pascal‐Louis Perez, kaChing Group Inc. 
  • 16. Components  • Software composability is key to test‐driven  development  • Testable software abstracts the control flow;  As such is functional by nature  Pascal‐Louis Perez, kaChing Group Inc. 
  • 17. Examples of Simple Tests  • Marshalling tests  • Dealing with time  • Equivalence tester  Pascal‐Louis Perez, kaChing Group Inc. 
  • 18. A  λ  Marshalling tests  π  Json.Object o =  Fail fast  TwoLattes.createMarshaller(Trade.class).marshall(...); assertSameJson( object( string("id"), number(4), string("portfolioId"), NULL, string("trade"), string("interest"), string("date"), string("2008-07-06"), string("toDate"), string("2008-06-06"), string("fromDate"), string("2008-07-05"), string("longInterest"), number(56.43), string("shortInterest"), number(-0.81)), o);  Pascal‐Louis Perez, kaChing Group Inc. 
  • 19. A  λ  Marshalling tests  π  Json.Object o = TwoLattes.createMarshaller(Trade.class).marshall(...); assertSameJson(  Dedicated assertions  object( string("id"), number(4), string("portfolioId"), NULL, string("trade"), string("interest"), string("date"), string("2008-07-06"), string("toDate"), string("2008-06-06"), string("fromDate"), string("2008-07-05"), string("longInterest"), number(56.43), string("shortInterest"), number(-0.81)), o);  Pascal‐Louis Perez, kaChing Group Inc. 
  • 20. A  λ  Marshalling tests  π  Json.Object o = TwoLattes.createMarshaller(Trade.class).marshall(...); assertSameJson(  Descriptive expectation  object( string("id"), number(4), string("portfolioId"), NULL, string("trade"), string("interest"), string("date"), string("2008-07-06"), string("toDate"), string("2008-06-06"), string("fromDate"), string("2008-07-05"), string("longInterest"), number(56.43), string("shortInterest"), number(-0.81)), o);  Pascal‐Louis Perez, kaChing Group Inc. 
  • 21. A  λ  Dealing with time  π  • Use clocks  – Provider<DateTime>  – Provider<LocalDate>  • Pass in now or today in business logic  Pascal‐Louis Perez, kaChing Group Inc. 
  • 22. Time Logic  @VisibleForTesting <T> T provideCurrentOrHistorical( DateTime date, Provider<T> current, Provider<T> historical) { DateTime lastTradeDate = getLastTradeDate();  Time logic is easy  boolean isCurrent = date == null      to test  || lastTradeDate == null || date.compareTo(lastTradeDate) > 0; return isCurrent ? current.get() : historical.get(); }  Pascal‐Louis Perez, kaChing Group Inc. 
  • 23. Time Logic  @VisibleForTesting <T> T provideCurrentOrHistorical(  Higher‐order functions  DateTime date, Provider<T> current, Provider<T> historical) { DateTime lastTradeDate = getLastTradeDate(); boolean isCurrent = date == null || lastTradeDate == null || date.compareTo(lastTradeDate) > 0; return isCurrent ? current.get() : historical.get(); }  Pascal‐Louis Perez, kaChing Group Inc. 
  • 24. A  λ  Equivalence Tester  π  EquivalenceTester.check( Tests  asList(  Reflexivity  new Isin("abCdEFgHiJK3“),  Symmetry  new Isin("ABCDEFGHIJK3“),  Transitivity  new Isin(“abCDefGHIJK3")),   hashCode consistency  asList( new Isin("AU0000XVGZA3"), new Isin("AU0000XVGZA3")));  Pascal‐Louis Perez, kaChing Group Inc. 
  • 25. Rationale for Database Testing  • Accessing the database correctly  • O/R properly configured and used  • Hand written queries  • Optimistic concurrency  Pascal‐Louis Perez, kaChing Group Inc. 
  • 26. JDBC   Global static state  DriverManager.registerDriver(new org.gjt.mm.mysql.Driver()); Connection conn = DriverManager.getConnection("jdbc:..."); PreparedStatement st = conn.prepareStatement("select ..."); st.setString(1, "..."); ResultSet rs = st.executeQuery(); while (rs.next()) { // work } rs.close(); st.close(); conn.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 27. JDBC  DriverManager.registerDriver(new org.gjt.mm.mysql.Driver()); Connection conn = DriverManager.getConnection("jdbc:..."); PreparedStatement st = conn.prepareStatement("select ..."); st.setString(1, "..."); ResultSet rs = st.executeQuery(); while (rs.next()) { // work } rs.close();  Low level, stateful API, wide scoping  st.close(); conn.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 28. JDBC  DriverManager.registerDriver(new org.gjt.mm.mysql.Driver()); Connection conn = DriverManager.getConnection("jdbc:..."); PreparedStatement st = conn.prepareStatement("select ..."); st.setString(1, "..."); ResultSet rs = st.executeQuery(); while (rs.next()) { // work }  Resources hell  rs.close(); st.close(); conn.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 29. Hibernate   Global state  SessionFactory factory = ...; Session session = factory.openSession(); Transaction tx = session.beginTransaction(); List<User> users = session .createQuery("from User where ...") .list(); for (User user : users) { // work } tx.commit(); session.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 30. Hibernate  SessionFactory factory = ...;  High‐level API  Session session = factory.openSession(); Transaction tx = session.beginTransaction(); List<User> users = session .createQuery("from User where ...") .list(); for (User user : users) { // work } tx.commit(); session.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 31. Hibernate  SessionFactory factory = ...; Session session = factory.openSession(); Transaction tx = session.beginTransaction(); List<User> users = session .createQuery("from User where ...") .list(); for (User user : users) { // work }  Resources hell  tx.commit(); session.close();  Pascal‐Louis Perez, kaChing Group Inc. 
  • 32. Transacter   Global state  Transacter transacter = ...; transacter.execute(new WithSession() { public void run(Session session) { List<User> users = ...; for (User user : users) { // work } } });  Pascal‐Louis Perez, kaChing Group Inc. 
  • 33. Transacter  Transacter transacter = ...;  High‐level API, no resources  transacter.execute(new WithSession() { public void run(Session session) { List<User> users = ...; for (User user : users) { // work } } });  Pascal‐Louis Perez, kaChing Group Inc. 
  • 34. Transacter  Transacter transacter = ...; transacter.execute(new WithSession() { public void run(Session session) {  Lexical scoping  List<User> users = ...; for (User user : users) { // work } } });  Pascal‐Louis Perez, kaChing Group Inc. 
  • 35. Database Testing is Hard  • Complex to set up : PersistenceTestRunner  • Schema installation : O/R Mapping  • Requires data to be loaded : Fixtures, DbUnit  • Developer must have proper environment  : in‐memory DBs (HSQLDB, Connector/MXJ)  Pascal‐Louis Perez, kaChing Group Inc. 
  • 36. A  λ  PersistenceTestRunner  π  @RunWith(PersistenceTestRunner.class)  Declarative setup  @PersistentEntities({Item.class, Note.class}) public class ExamplePersistentTest { @Test public void example1(Transacter transacter) { // work } @Test public void example2() { // work } } Pascal‐Louis Perez, kaChing Group Inc. 
  • 37. A  λ  PersistenceTestRunner  π  @RunWith(PersistenceTestRunner.class) @PersistentEntities({Item.class, Note.class}) public class ExamplePersistentTest {  Lexical scoping  @Test public void example1(Transacter transacter) { // work } @Test public void example2() { // work } } Pascal‐Louis Perez, kaChing Group Inc. 
  • 38. A  λ  PersistenceTestRunner  π  @RunWith(PersistenceTestRunner.class) @PersistentEntities({Item.class, Note.class}) public class ExamplePersistentTest { @Test  RuntimeException  public void example1(Transacter transacter) { // work } @Test public void example2() { // work } } Pascal‐Louis Perez, kaChing Group Inc. 
  • 39. A  λ  PersistenceTestRunner  π  @RunWith(PersistenceTestRunner.class) @PersistentEntities({Item.class, Note.class}) public class ExamplePersistentTest { @Test public void example1(Transacter transacter) { // work }  Non‐persistent tests run as usual  @Test public void example2() { // work } } Pascal‐Louis Perez, kaChing Group Inc. 
  • 40. A  λ  Testing Interactions (I/O, …)  π  • Implicit global state  • Many cases  – HTTP GET: succeed, fail to connect, connection  closed before headers are read, …  – Sending e‐mail: succeed, connection lost after  HELO, …  • Sequencing is crucial  Pascal‐Louis Perez, kaChing Group Inc. 
  • 41. A  λ  Testing the Transacter (success)  π   Mocking  final WithSession withSession = mockery.mock(WithSession.class); mockery.checking(new Expectations() {{ one(sessionFactory).openSession(); will(returnValue(session)); inSequence(execution); one(session).connection(); will(...); inSequence(...); one(connection).setReadOnly(with(equal(false))); ... one(connection).setAutoCommit(with(equal(false))); ... one(session).beginTransaction(); inSequence(...); ... }}); transacter.execute(withSession); mockery.assertIsSatisfied(); Pascal‐Louis Perez, kaChing Group Inc. 
  • 42. A  λ  Testing the Transacter (success)  π  final WithSession withSession = mockery.mock(WithSession.class); mockery.checking(new Expectations() {{ one(sessionFactory).openSession();  Interactions are scripted  will(returnValue(session)); inSequence(execution); one(session).connection(); will(...); inSequence(...); one(connection).setReadOnly(with(equal(false))); ... one(connection).setAutoCommit(with(equal(false))); ... one(session).beginTransaction(); inSequence(...); ... }}); transacter.execute(withSession); mockery.assertIsSatisfied(); Pascal‐Louis Perez, kaChing Group Inc. 
  • 43. A  λ  Testing the Transacter (failure)  π  mockery.checking(new Expectations() {{ one(sessionFactory).openSession();  Failure is controlled  ... one(connection).setReadOnly(with(equal(false))); will(throwException(exception)); inSequence(execution); one(session).close(); inSequence(execution); }}); try { transacter.execute(withSession); fail(); } catch (RuntimeException e) { assertTrue(e == exception); } mockery.assertIsSatisfied(); Pascal‐Louis Perez, kaChing Group Inc. 
  • 44. A  λ  Testing the Transacter (failure)  π  mockery.checking(new Expectations() {{ one(sessionFactory).openSession(); ... one(connection).setReadOnly(with(equal(false))); will(throwException(exception)); inSequence(execution); one(session).close(); inSequence(execution); }}); try { transacter.execute(withSession); fail(); } catch (RuntimeException e) { assertTrue(e == exception);  Exact  same object (correct bubbling)  } mockery.assertIsSatisfied(); Pascal‐Louis Perez, kaChing Group Inc. 
  • 45. A  λ  Testing the Transacter (failure)  π  mockery.checking(new Expectations() {{ one(sessionFactory).openSession(); ... one(connection).setReadOnly(with(equal(false))); will(throwException(exception)); inSequence(execution); one(session).close(); inSequence(execution); }});  Unreachable program point  try { transacter.execute(withSession); fail(); } catch (RuntimeException e) { assertTrue(e == exception); } mockery.assertIsSatisfied(); Pascal‐Louis Perez, kaChing Group Inc. 
  • 46. Meta Tests  • Cross domain tests to sweep the codebase,  exactly like static analysis  • Catch common mistakes  – Distracted developers  – Bad APIs  – New hires learning conventions    Pascal‐Louis Perez, kaChing Group Inc. 
  • 47. A  λ  Dependency Test  π  • Declare software dependencies  • Controls layering of application  • Simpler and more flexible than different  compilation units  • Can guarantee that certain APIs are not used  directly  • Patched Jdepend to parse annotations  Pascal‐Louis Perez, kaChing Group Inc. 
  • 48. Dependency Test  dependencies.forPackages( "com.kaching.*" ). check("com.kaching.supermap").mayDependOn( "com.kaching.platform.guice", "org.apache.commons.lang", "voldemort.*", "org.kohsuke.args4j" ). assertIsVerified(jDepend.getPackages()); Pascal‐Louis Perez, kaChing Group Inc. 
  • 49. A  λ  Bad Code Test  π  • Enforce conventions  • Gotchas, bad APIs  – E.g. System.out.println  – E.g. java.net.URL  • Code reviews  – Design patterns, custom APIs, etc.  – Enforce conventions: automate this!  Pascal‐Louis Perez, kaChing Group Inc. 
  • 50. Bad Code Test  @RunWith(BadCodeSnippetsRunner.class) @CodeSnippets({ @Check(paths = "src/com/kaching", snippets = { // no uses of java.net.URL @Snippet(value = "bjava.net.URLb", exceptions = { "src/com/kaching/...", "src/com/kaching/..." }), // never call default super constructor @Snippet("super()") })}) class MyBadCodeSnippetsTest { Pascal‐Louis Perez, kaChing Group Inc. 
  • 51. Key Takeaways  • Invest in your tests, and testing frameworks  • Design patterns to separate concerns  • Components  • TDD pushes towards functional techniques    • We’re recruiting jobs@kaching.com  • More http://eng.kaching.com  Pascal‐Louis Perez, kaChing Group Inc.