Frage

Ich habe eine Hibernate-basierte Anwendung bekommt die DBUnit für Unit-Tests verwendet. Wir haben eine XML-Test-Datenbank, die mit Dummy-Daten in der setUp () jeden Tests und gelöscht während der tearDown geladen wird (). Das Problem ist, dass ich nicht mehr die gesamte Suite in einer IDE (in diesem Fall, IntelliJ) laufen, denn nach etwa 300 Tests, die Heap-Speicher alle aufgebraucht werden. Die Tests gehen aus Mitnahmen ~ 0,3 Sekunden auf mehr als 30 Sekunden ausgeführt werden, bis schließlich die JVM aufgibt und stirbt.

Wenn ich die Testsuite über Ameise JUnit-Task ausführen, dann ist es kein Problem, noch ist die Testsuite für eine einzelne Klasse ausgeführt wird. Allerdings mag ich in der Lage sein, die gesamte Suite lokal zu laufen, bevor ich in großen Refactoring Änderungen an der Code-Basis überprüfen, anstatt den Build auf dem CI-Server zu brechen.

Ich verwende die Testsuite mit -Xmx512m als mein einziges Argument für die JVM, die die gleiche Menge, die ich zu ant passieren, wenn die Aufgabe auf dem CI-Server ausgeführt wird. Mein Hibernate-test.cfg.xml sieht wie folgt aus:

<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>

Wir haben eine Klasse geschrieben, für die alle Testklassen reichen von, die etwa wie folgt aussieht:

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;
  }
}

Es ist klar, dass einige Speicherleck hier los ist, aber ich bin nicht sicher, wo. Wie könnte ich über die Diagnose gehen?

War es hilfreich?

Lösung 2

J-16 SDiZ Antwort hat ich in der richtigen Richtung zu arbeiten, aber ich dachte, dass ich ein bisschen mehr detaillierte Informationen darüber, wie zur Verfügung stellen würde, ich war in der Lage, diese zu lösen. Die Wurzel des Problems war in der Tat, dass die Datenbank im Speicher gehalten gespeichert werden, aber die Lösung war von DBTestCase Klasse DBUnit die erben, nicht versuchen, meine eigene Rolle von der JUnit Testcase vererben. Mein Testfall Basisklasse sieht nun so etwas wie folgt aus:

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());
  }

Diese Klasse funktioniert recht gut, und meine Testsuite Lauf nach unten von einigen Minuten auf nur 30 Sekunden verschwunden.

Andere Tipps

Sie verwenden Memory-Datenbank hier:

<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:mem:mydatabase</property>

Das bedeutet, dass alles, was in der Datenbank im Speicher ist. Entweder mit im Cache gespeicherte Tabelle auf dem Datenträger-Datenbank verwenden, oder stellen Sie sicher, fallen Ihnen alles nach jedem Test.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top