Как я могу получить @BeforeClass и эквивалент @AfterClass в Junit3?

Я хочу создать резервную копию базы данных приложений, прежде чем заменять ее тестовым прибором. Я вынужден использовать Junit3 из-за ограничений Android, и я хочу реализовать эквивалентное поведение @BeforeClass @AfterClass.

UPDATE: теперь есть инструмент (Junit4Android), чтобы получить поддержку для Junit4 на Android. Это немного клочья, но он должен работать.

Чтобы достичь эквивалента @BeforeClass, я использовал статическую переменную и инициализировал ее во время первого запуска, как это, но мне нужно иметь возможность восстановить базу данных после запуска всех тестов. Я не могу придумать способ обнаружения, когда последний тест был запущен (так как я считаю, что нет гарантии в порядке выполнения теста.)

public class MyTest extends ActivityInstrumentationTestCase2<MainActivity> {
    private static boolean firstRun = true;

    @Override
    protected void setUp() {
        if(firstRun) {
            firstRun = false;
            setUpDatabaseFixture();
        }
    }
    ...
}

Ответ 1

На веб-сайте junit:

Обернул метод setUp и tearDown в пакете. Это для если вы хотите запустить один тестовый файл TestTestClass.

public static Test suite() {
    return new TestSetup(new TestSuite(YourTestClass.class)) {

        protected void setUp() throws Exception {
            System.out.println(" Global setUp ");
        }
        protected void tearDown() throws Exception {
            System.out.println(" Global tearDown ");
        }
    };
}

Если вы хотите запустить только один setUp и tearDown для всех testcase, создать пакет и добавить к нему testClass и передать пакет объект в конструкторе TestSetup. Но я думаю, что не так много использования для этого и в какой-то мере нарушает философию Юнита.

Ответ 2

Недавно я искал аналогичное решение. К счастью, в моем случае после выхода JVM после запуска последнего теста. Поэтому я смог достичь этого, добавив JVM-заглушку.

// Restore database after running all tests
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        restoreDatabase();
    }
});

надеюсь, что это поможет.

Ответ 3

Разве это не так (элегантно с данными, поэтому вам не нужно беспокоиться о его восстановлении), что тестирование с макетными объектами для? Android поддерживает насмешку.

Я задаю вопрос, потому что я никогда не издевался над Android.


В моем опыте и от это сообщение в блоге, когда тесты на Android превращаются в набор и запускаются a href= "http://developer.android.com/reference/android/test/InstrumentationTestRunner.html" rel= "nofollow noreferrer" > InstrumentationTestRunner - ActivityInstrumentationTestCase2 является расширением ActivityTestCase, который является расширением InstrumentationTestCase - они упорядочены по алфавиту с помощью android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME, поэтому вы можете просто восстановить DB с помощью метода, который является минимумом в алфавите из ваших тестовых имен, например:

// underscore is low in the alphabet
public void test___________Restore() { 
    ... 
}

Примечание:

Вы должны обратить внимание на унаследованные тесты, так как они не будут работать в этом порядке. Решение состоит в том, чтобы переопределить все унаследованные тесты и просто вызвать super() из переопределения. Это снова приведет к тому, что все будет выполнено в алфавитном порядке.

Пример:

// Reusable class w only one time setup and finish. 
// Abstract so it is not run by itself.
public abstract class Parent extends InstrumentationTestCase {
    @LargeTest
    public void test_001_Setup() { ... }

    @LargeTest
    public void test_____Finish() { ... }
}

/*-----------------------------------------------------------------------------*/

// These will run in order shown due to naming.
// Inherited tests would not run in order shown w/o the use of overrides & supers
public class Child extends Parent {
    @LargeTest
    public void test_001_Setup() { super.test_001_Setup(); }

    @SmallTest
    public void test_002_MainViewIsVisible() { ... }

    ...

    @LargeTest
    public void test_____Finish() { super.test_____Finish(); }
}

Ответ 4

Я бы предложил избегать таких зависимостей, где вам нужно знать порядок выполнения тестов. Если вам нужно только восстановить реальную базу данных, которая была заменена на setUpDatabaseFixture(), вероятно, решение будет получено из RenamingDelegatingContext. В любом случае, если вы не можете не знать, когда был запущен последний тест, вы можете использовать что-то вроде этого:

...

private static final int NUMBER_OF_TESTS = 5; // count your tests here
private static int sTestsRun = 0;

...

protected void tearDown() throws Exception {
    super.tearDown();
    sTestsRun += countTestCases();

    if ( sTestsRun >= NUMBER_OF_TESTS ) {
        android.util.Log.d("tearDow", "*** Last test run ***");
    }
}