4

My task is to write stress (load) tests for Service Layer. There are mostly CRUD operations. We use JUnit as test framework, JUnitPerf for building load tests, Spring for injecting service beans and hibernate to access database.

The stress test is something like: read entity - update entity - save - read again and compare. But to build the test I need some test data in the database, so I need to create this data before test and delete it after. The required process flow: create test data - run test in several threads - drop test data after all threads finish execution. There are a lot of test data, so it will be much better to use some test dump sql file to get it. So what I need is to: load data from file into database - perform stress test - delete all loaded data.

I use SchemaExport to load data. I faced the following exception:

org.hibernate.HibernateException: No local DataSource found for configuration - 'dataSource' property must be set on LocalSessionFactoryBean
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.configure(LocalDataSourceConnectionProvider.java:49)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:56)
at org.hibernate.tool.hbm2ddl.ManagedProviderConnectionHelper.prepare(ManagedProviderConnectionHelper.java:27)
at org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:180)
at org.hibernate.tool.hbm2ddl.SchemaExport.create(SchemaExport.java:133)
    .................

Here is the definition of my SessionFactory bean:

  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=${hibernate.dialect}
            hibernate.show.sql=${hibernate.show.sql}
        </value>
    </property>
    <property name="annotatedClasses">
        <list>
            ...
            my classes
            ...
        </list>
    </property>
</bean>

And I init the test in the following way:

 @BeforeClass
public static void createTestData() throws AccessDeniedException, AccountException, SQLException {
    ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext("classpath:/applicationContext_test.xml");
    AnnotationSessionFactoryBean sessionFactoryBean = (AnnotationSessionFactoryBean) appCtx.getBean("sessionFactory");
    org.hibernate.cfg.Configuration configuration = sessionFactoryBean.getConfiguration();
    SchemaExport schemaExport = new SchemaExport(configuration);
    schemaExport.drop(false, true);
    schemaExport.create(false, true);
    if (schemaExport.getExceptions().size() > 0) {
        for (Object exception : schemaExport.getExceptions()) {
            if (exception instanceof Throwable) {
                ((Throwable) exception).printStackTrace();
            }
        }
        throw new IllegalStateException();
    }
}

I mentioned that I need load test to make clear that I can't include data initialization in the test block.

I have two questions: 1) How can I init data before load test and delete it after? 2) Am I on the right way? Or maybe I should switch to another technology for stress testing?

Zalivaka
  • 763
  • 2
  • 13
  • 20

2 Answers2

1

You can use DBUnit to do the data load for you. Or use Unitils that integrates DBUnit with Spring with Hibernate.

Regards,

schrieveslaach
  • 1,689
  • 1
  • 15
  • 32
deluan
  • 1,865
  • 12
  • 14
  • I have setup Unitils, but it executes DataSet insertion on each method call. I need it to be loaded once and then execute test method in several threads without any additional data loading. – Zalivaka Apr 04 '11 at 10:25
0

If you use Spring for testing you should consider to not use Spring Testing Support instead of loading the application context for yourself and lookup the beans.

You can do something like this on your test class and inject beans automatically.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"applicationContext_test.xml"})

Regarding "clean up" after test I always thought about using the Spring transaction management for the test scope. It should be possible to declare the test start as @Transactional and rollback the transaction programmatically after test. There is no need to delete the data explicit this way.

This is just an idea so far. Must give it self a try...

FrVaBe
  • 47,963
  • 16
  • 124
  • 157