2012-03-10 3 views
1

Я запускаю JUnit 4.10 на Eclipse 3.7. Я делаю тестирование базы данных: в базе данных используется SQLite3 с sqlitejdbc. Я попытался выполнить тесты как на окнах, так и на linux, и вот мои наблюдения:Блокировка базы данных SQLite в тестах JUnit

  • В Windows 7 x64 тесты выполняются быстрее (~ 0,6 с на тест). Я получаю ошибки о «Не могу открыть файл базы данных». Они кажутся прерывистыми (иногда один и тот же тест может проходить один раз во время следующего прогона)
  • На Ubuntu 11.10 x64 тесты проходят медленно (~ 3 с на тест). Я получаю ошибки о «заблокированной базе данных». В отличие от ошибок Windows, которые прерывисты, здесь возникают ошибки в одном и том же тесте/файле, и после возникновения ошибки блокировки все последующие тесты терпят неудачу.

UPDATE

Вы можете найти код для испытаний на GitHub. Я думаю, что проблема может быть что-то делать с тем, как мои @BeforeClass, @Before и наборы тестов могут быть сконфигурированы

У меня есть Test Suite, как

@RunWith(Suite.class) 
@SuiteClasses({ DataAccessTests.class, SimpleQueryTests.class, ... }) 
public class DataAccessTestSuite { 
    @BeforeClass 
    public static void setUpDatabase() throws SQLException, ClassNotFoundException {  
     DataAccess.setEnvironment(DataAccess.DATABASE_TESTING); 
     Connection conn = DataAccess.getConn(); 

     // truncate tables: simply DELETE statements 
     truncateTables(conn); 

     // insert test data, INSERT statements 
     insertTestData(conn); 
    } 

Тогда в моих классах испытаний я был @Before, который вызывает установку также ,

public class EventsDataAccessTests { 

    @Before 
public void setup() throws SQLException, ClassNotFoundException { 
    DataAccessTestSuite.setUpDatabase(); 
} 

Я думал, что все еще хочу настроить свою базу данных на случай, если я не хочу называть весь пакет. Я думаю, что проблема связана с этим, но я не уверен, как именно это создает проблему. Похоже, что даже если я вызываю отдельный тестовый класс, моя настройка для пакета выполняется? Или, если нет, как я могу застраховать его, запускается один раз, если тест не вызывается из Suite?

- Old Post Удалены -

+0

Выполняете ли вы единичный тест одновременно? – kan

+0

Я запускаю свои тесты с использованием Eclipse, не много экземпляров eclipse или чего-то подобного, поэтому тесты не должны запускаться одновременно? –

+0

Если у меня есть что-то вроде '@SuiteClasses ({DataAccessTests.class, SimpleQueryTests.class, SimpleInsertTests.class, SimpleUpdateTests.class, ...})' являются ли отдельные тестовые классы запускаемыми одновременно? –

ответ

2

Вы должны убедиться, что не более чем один поток одновременно не пытается иметь запись блокировку на SQLite базы данных. Для получения дополнительной информации о том, что я имею в виду, что прочитал

(5) Can multiple applications or multiple instances of the same application access a single database file at the same time?

Так что, когда вы говорите:

Если я запускаю тест сам по себе, она проходит. При попытке запустить весь пакет он не

Я думаю, что это справедливо предположить, что записи блокировка не снимается, возможно, на объект подключения, а другой один пытается приобрести его. Итак, даже если вы не используете потоки, возможно, GC не попадает на объект соединения предыдущего теста, прежде чем другой тест создает другой объект соединения.

Возможно, вы можете опубликовать некоторые из этих тестов, чтобы лучше понять, что может произойти неправильно.

UPDATE:

вы не должны закрывать соединение здесь?:

public static void tearDownDatabase() throws SQLException, ClassNotFoundException { 
    Connection conn = DataAccess.getConn(); 
    truncateTables(conn); 
} 
+0

+1 для острого диагноза. Иногда мы все непреднамеренно вызывают проблемы с параллелизмом. :) – MrGomez

Смежные вопросы