KEMBAR78
Testing Your Application On Google App Engine | PDF
Testing Your Application on / for
       Google App Engine
                          Narinder Kumar
                       Inphina Technologies




                                       1
Agenda
   Problem Context
   App Engine Testing Framework
       Local DataStore Testing
       Authentication API Testing
       Memcache Testing
   Google Cloud Cover – An Overview



                                       2
Easy to build, Easy to Maintain,
         Easy to Scale




                                   3
Why Testing
   To verify correctness
    of the code
   To be assured of
    continued
    correctness of old
    code
   To avoid surprises
   To safely make large
    refactorings
I feel sad and naked without Good Test Coverage
                              Max Ross (Member of Google App Engine Team)   4
Do we need App Engine Specific
     Testing Strategies ?




                                 5
Our Goal
To be able to test in our local environment using
   Spring
   Maven
   JPA/JDO
   JUnit
   Continuous Integration



                                                6
Google Infrastructure Services
   DataStore
   Memcache
   TaskQueue
   Authentication
   ...




                                       7
App Engine Testing Framework
   LocalServiceTestHelper
       LocalDataStoreServiceTestConfig
       LocalMemCacheServiceTestConfig
       LocalTaskQueueTestConfig
       LocalUserServiceTestConfig
       ...




                                          8
Local Data Store Testing




                           9
Step 1 : Make RunTime Libraries
        Available Locally
 <dependency>
     <groupid>com.google.appengine</groupid>
     <artifactid>appengine-testing</artifactid>
     <version>1.3.4</version>
     <scope>test</scope>
 </dependency>
 <dependency>
     <groupid>com.google.appengine</groupid>
     <artifactid>appengine-api-labs</artifactid>
     <version>1.3.4</version>
     <scope>test</scope>
 </dependency>
 <dependency>
     <groupid>com.google.appengine</groupid>
     <artifactid>appengine-api-stubs</artifactid>
     <version>1.3.4</version>
     <scope>test</scope>
 </dependency>


 Some of these libraries are not available in Central Maven
                        Repositories                          10
Step 2 : Enhance Domain Classes
 <plugin>
            <groupid>org.datanucleus</groupid>
            <artifactid>maven-datanucleus-plugin</artifactid>
            <version>1.1.4</version>
            <configuration>
            <mappingincludes>**/domain/*.class</mappingincludes>
                 <verbose>true</verbose>
                 <enhancername>ASM</enhancername>
                 <api>JPA</api>
            </configuration>
            <executions>
                 <execution>
                      <phase>compile</phase>
                      <goals>
                          <goal>enhance</goal>
                      </goals>
                 </execution>
            </executions>
 ......
 <plugin>
                                                                   11
Prepare Run-Time Environment
        and Dependencies
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class })
@ContextConfiguration(locations = { "classpath:test-applicationContext.xml",
"classpath:test-applicationContext-dao.xml"})
public class LocalDatastoreSpringTestCase extends TestCase {

  private final LocalServiceTestHelper helper =
     new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

  @Before
  public void setUp() {
    helper.setUp();
  }

  @After
  public void tearDown() {
    helper.tearDown();
  }


                                                                               12
Write Specific Tests
public class EmployeeDaoSpringTest extends LocalDatastoreSpringTestCase {

    @Autowired
    private EmployeeDao employeeDao;

    @Test
    public void testShouldPersistEmployee() {
         Employee employee = new Employee();
         employee.setFirstName("Scott");
         employee.setLastName("Adams");
         employee.setHireDate(new Date());

        employeeDao.createEmployee(employee);

        Collection<employee> list = employeeDao.list();

        Assert.assertEquals(1, list.size());
    }


                                                                            13
Authentication API Testing
public class AuthenticationTest {

    private final LocalServiceTestHelper helper =
       new LocalServiceTestHelper(new LocalUserServiceTestConfig())
         .setEnvIsAdmin(true).setEnvIsLoggedIn(true);

    @Test
    public void testIsAdmin() {
      UserService userService = UserServiceFactory.getUserService();
      assertTrue(userService.isUserAdmin());
    }

    @Before
    public void setUp() {
      helper.setUp();
    }

    @After
    public void tearDown() {
      helper.tearDown();
    }
}
                                                                       14
Memcache Testing
public class LocalMemcacheTest {

       private final LocalServiceTestHelper helper =
          new LocalServiceTestHelper(new LocalMemcacheServiceTestConfig());

       @Test
       private void testInsert() {
          MemcacheService ms = MemcacheServiceFactory.getMemcacheService();
          assertFalse(ms.contains("yar"));
          ms.put("yar", "foo");
          assertTrue(ms.contains("yar"));
       }}

....
       // SetUp and Tear Down




                                                                              15
Google Cloud Cover – An Overview




                                   16
Key Features
   Provides ability to run your tests in Cloud
   Designed to run Existing Test Suites
   Tests Execute in Parallel
       Creates one Task Queue per Test
       Number of workers determined by Queue Config
   Allows to Run Large Test Suites faster : Acts as
    a Test Grid


                                                       17
How to Set it up
   Create a Standard GAE/J web application with
    all Production Code & Test Code and
    dependencies
   Add Cloud Cover Dependencies to WAR
   Create a TestRunner Config around your Test
    Suite
   Add Cloud Cover Servlet
      http://<your_app_id>/cloudcover.html

                                                  18
Google Cloud Cover in Action




                               19
Different from Normal Testing
   Each Test must complete in 30 seconds

   Application Code and Test Code must obey

    Sandbox restrictions

   Need to invoke Tests via HTTP



                                               20
Conclusions
   Local RunTime Environment very helpful

    during Development Phase

   Google Cloud Cover can be a good aid in

    certain areas but need more refinement



                                              21
nkumar@inphina.com

      www.inphina.com
http://thoughts.inphina.com


                              22
References
   http://code.google.com/appengine/docs/java/tools/localunittesting.html

   http://code.google.com/p/cloudcover/

   http://thoughts.inphina.com/2010/06/28/unit-testing-maven-based-jpa-application-on-gae/

   http://objectuser.wordpress.com/category/software-development/google-app-engine/

   http://code.google.com/events/io/2010/sessions.html#App%20Engine




                                                                                        23

Testing Your Application On Google App Engine

  • 1.
    Testing Your Applicationon / for Google App Engine Narinder Kumar Inphina Technologies 1
  • 2.
    Agenda  Problem Context  App Engine Testing Framework  Local DataStore Testing  Authentication API Testing  Memcache Testing  Google Cloud Cover – An Overview 2
  • 3.
    Easy to build,Easy to Maintain, Easy to Scale 3
  • 4.
    Why Testing  To verify correctness of the code  To be assured of continued correctness of old code  To avoid surprises  To safely make large refactorings I feel sad and naked without Good Test Coverage Max Ross (Member of Google App Engine Team) 4
  • 5.
    Do we needApp Engine Specific Testing Strategies ? 5
  • 6.
    Our Goal To beable to test in our local environment using  Spring  Maven  JPA/JDO  JUnit  Continuous Integration 6
  • 7.
    Google Infrastructure Services  DataStore  Memcache  TaskQueue  Authentication  ... 7
  • 8.
    App Engine TestingFramework  LocalServiceTestHelper  LocalDataStoreServiceTestConfig  LocalMemCacheServiceTestConfig  LocalTaskQueueTestConfig  LocalUserServiceTestConfig  ... 8
  • 9.
  • 10.
    Step 1 :Make RunTime Libraries Available Locally <dependency> <groupid>com.google.appengine</groupid> <artifactid>appengine-testing</artifactid> <version>1.3.4</version> <scope>test</scope> </dependency> <dependency> <groupid>com.google.appengine</groupid> <artifactid>appengine-api-labs</artifactid> <version>1.3.4</version> <scope>test</scope> </dependency> <dependency> <groupid>com.google.appengine</groupid> <artifactid>appengine-api-stubs</artifactid> <version>1.3.4</version> <scope>test</scope> </dependency> Some of these libraries are not available in Central Maven Repositories 10
  • 11.
    Step 2 :Enhance Domain Classes <plugin> <groupid>org.datanucleus</groupid> <artifactid>maven-datanucleus-plugin</artifactid> <version>1.1.4</version> <configuration> <mappingincludes>**/domain/*.class</mappingincludes> <verbose>true</verbose> <enhancername>ASM</enhancername> <api>JPA</api> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>enhance</goal> </goals> </execution> </executions> ...... <plugin> 11
  • 12.
    Prepare Run-Time Environment and Dependencies @RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class }) @ContextConfiguration(locations = { "classpath:test-applicationContext.xml", "classpath:test-applicationContext-dao.xml"}) public class LocalDatastoreSpringTestCase extends TestCase { private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); @Before public void setUp() { helper.setUp(); } @After public void tearDown() { helper.tearDown(); } 12
  • 13.
    Write Specific Tests publicclass EmployeeDaoSpringTest extends LocalDatastoreSpringTestCase { @Autowired private EmployeeDao employeeDao; @Test public void testShouldPersistEmployee() { Employee employee = new Employee(); employee.setFirstName("Scott"); employee.setLastName("Adams"); employee.setHireDate(new Date()); employeeDao.createEmployee(employee); Collection<employee> list = employeeDao.list(); Assert.assertEquals(1, list.size()); } 13
  • 14.
    Authentication API Testing publicclass AuthenticationTest { private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalUserServiceTestConfig()) .setEnvIsAdmin(true).setEnvIsLoggedIn(true); @Test public void testIsAdmin() { UserService userService = UserServiceFactory.getUserService(); assertTrue(userService.isUserAdmin()); } @Before public void setUp() { helper.setUp(); } @After public void tearDown() { helper.tearDown(); } } 14
  • 15.
    Memcache Testing public classLocalMemcacheTest { private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalMemcacheServiceTestConfig()); @Test private void testInsert() { MemcacheService ms = MemcacheServiceFactory.getMemcacheService(); assertFalse(ms.contains("yar")); ms.put("yar", "foo"); assertTrue(ms.contains("yar")); }} .... // SetUp and Tear Down 15
  • 16.
    Google Cloud Cover– An Overview 16
  • 17.
    Key Features  Provides ability to run your tests in Cloud  Designed to run Existing Test Suites  Tests Execute in Parallel  Creates one Task Queue per Test  Number of workers determined by Queue Config  Allows to Run Large Test Suites faster : Acts as a Test Grid 17
  • 18.
    How to Setit up  Create a Standard GAE/J web application with all Production Code & Test Code and dependencies  Add Cloud Cover Dependencies to WAR  Create a TestRunner Config around your Test Suite  Add Cloud Cover Servlet http://<your_app_id>/cloudcover.html 18
  • 19.
    Google Cloud Coverin Action 19
  • 20.
    Different from NormalTesting  Each Test must complete in 30 seconds  Application Code and Test Code must obey Sandbox restrictions  Need to invoke Tests via HTTP 20
  • 21.
    Conclusions  Local RunTime Environment very helpful during Development Phase  Google Cloud Cover can be a good aid in certain areas but need more refinement 21
  • 22.
    nkumar@inphina.com www.inphina.com http://thoughts.inphina.com 22
  • 23.
    References  http://code.google.com/appengine/docs/java/tools/localunittesting.html  http://code.google.com/p/cloudcover/  http://thoughts.inphina.com/2010/06/28/unit-testing-maven-based-jpa-application-on-gae/  http://objectuser.wordpress.com/category/software-development/google-app-engine/  http://code.google.com/events/io/2010/sessions.html#App%20Engine 23