为什么我的DBUnit的测试,耗费这么多的内存?
-
12-09-2019 - |
题
我有其使用DBUnit的单元测试基于休眠应用程序。我们有一个XML测试数据库,这将会拆卸过程中每个测试的设置()加载了虚拟数据和删除()。问题是,我不能再运行在IDE整个套件(在这种情况下,的IntelliJ),因为后约300测试,堆内存得到全部用完。测试去从取-0.3秒至30秒以上来执行,直到最终JVM放弃和死亡。
当我通过蚂蚁的junit任务运行测试套件,那么它的没有问题的,也不是在运行测试套件为单个类。不过,我喜欢能够在本地运行整个套件之前,我在大重构更改检查代码库,而不是CI服务器上破坏构建。
我运行测试套件以-Xmx512m作为我的唯一参数的JVM中,这是相同的量运行CI服务器上的任务时,我传递给蚂蚁。我的休眠,test.cfg.xml看起来是这样的:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:mem:mydatabase</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- Other configuration properties -->
<property name="connection.pool_size">1</property>
<property name="jdbc.batch_size">20</property>
<property name="connection.autocommit">true</property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="bytecode.use_reflection_optimizer">false</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<!-- Mappings (omitted for brevity) -->
<mapping resource="hbm/blah.hbm.xml"/>
</session-factory>
</hibernate-configuration>
我们写了一个类,所有的测试类的扩展从,这看起来是这样的:
package com.mycompany.test;
// imports omitted for brevity
public abstract class DBTestCase extends TestCase {
private final String XML_DATA_SET = "test/resources/mytestdata.xml";
private Session _session;
private Configuration _config;
public DBTestCase(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
_config = new Configuration().configure();
SessionFactory sf = _config.buildSessionFactory();
// This is a singleton which is used the DAO's to acquire a session.
// The session must be manually set from the test's setup so that any
// calls to the singleton return this session factory, otherwise NPE
// will result, since the session factory is normally built during
// webapp initialization.
HibernateUtil.setSessionFactory(sf);
_session = sf.openSession();
_session.beginTransaction();
IDataSet dataSet = new FlatXmlDataSet(new File(XML_DATA_SET));
DatabaseOperation.CLEAN_INSERT.execute(getConnection(), dataSet);
}
protected void tearDown() throws Exception {
super.tearDown();
_session.close();
}
protected IDatabaseConnection getConnection() throws Exception {
ConnectionProvider connProvider = ConnectionProviderFactory
.newConnectionProvider(_config.getProperties());
Connection jdbcConnection = connProvider.getConnection();
DatabaseConnection dbConnection = new DatabaseConnection(jdbcConnection);
DatabaseConfig dbConfig = dbConnection.getConfig();
dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());
return dbConnection;
}
}
显然,一些内存泄漏会在这里,但我不知道在哪里。我怎么可能去诊断呢?
解决方案 2
J-16 SDiZ的回答让我在正确的方向努力,但我想我会提供更多的详细信息,我怎么能解决这个问题。问题的根源确实数据库保持被存储在内存中,但解决的办法是从DbUnit的DBTestCase类继承,不要试图从JUnit的TestCase的继承推出自己的。我的测试情况下,基类现在看起来是这样的:
public class MyTestCase extends DBTestCase {
private static Configuration _config = null;
public MyTestCase(String name) {
super(name);
if(_config == null) {
_config = new Configuration().configure();
SessionFactory sf = _config.buildSessionFactory();
HibernateUtil.setSessionFactory(sf);
}
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:mem:mydbname");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa");
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "");
}
@Override
protected IDataSet getDataSet() throws Exception {
return new FlatXmlDataSet(new FileReader(MY_XML_DATA_FILE_NAME), false, true, false);
}
@Override
protected void setUpDatabaseConfig(DatabaseConfig config) {
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());
}
本类工作得很好,我的测试套件运行已经从几分钟了,最后变成了30秒。
其他提示
您在此处使用的内存数据库:
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:mem:mydatabase</property>
这意味着一切在数据库是在存储器中。无论是使用缓存的表在磁盘上的数据库中使用,或者确保您每次测试后放下一切。
不隶属于 StackOverflow