Можно ли выполнить тесты TestNG для нескольких реализаций интерфейса (источников данных)? - PullRequest
0 голосов
/ 11 марта 2012

Я ищу способ запустить несколько тестов TestNG для нескольких DataSource с.Я видел DataProvider опции для TestNG, но они не совсем то, что я хочу.Я хочу провести несколько очень простых тестов с моими сопоставителями MyBatis, главным образом, чтобы убедиться, что у меня нет простых синтаксических ошибок, опечаток и т. Д. Сейчас у меня есть базовый класс тестирования, подобный этому:1005 * Затем я создаю тест для каждого маппера:

public class SequenceMapperTest extends MapperTestBaseH2 {
    private SequenceMapper sequenceMapper;

    @BeforeClass
    @Override
    public void beforeClass() throws SQLException, LiquibaseUpdateException {
        super.beforeClass();
        sequenceMapper = super.sessionManager.getMapper(SequenceMapper.class);
    }

    @Test
    public void selectBidSequenceTest() {
        sequenceMapper.selectSequence(Sequences.BID_SEQ);
    }

    @Test
    public void updateBidSequenceTest() {
        sequenceMapper.updateSequence(sequenceMapper.selectSequence(Sequences.BID_SEQ));
    }
}

Что я хотел бы сделать, это запустить каждый тестовый класс дважды (или более), используя каждый раз разный SqlSessionManager.Я могу использовать TestNG DataProvider для запуска каждого теста с несколькими SqlSessionManager s, но тогда мне придется запускать и откатывать сеанс внутри каждого теста, а не в @BeforeMethod.

Есть ли простой способвыполнить то, что я хочу?

1 Ответ

1 голос
/ 12 марта 2012

Мне кажется, я понял это после того, как наткнулся на этот пост. Хитрость в том, чтобы использовать комбинацию @Factory и @DataProvider.Сначала я создал абстрактный базовый класс, который управляет провайдером и транзакциями.

public abstract class MyBatisTestBase {
    public abstract SqlSessionManager getSessionManager();

    @BeforeMethod
    public void beforeMethod() {
        getSessionManager().startManagedSession();
    }

    @AfterMethod
    public void afterMethod() {
        getSessionManager().rollback();
    }

    @DataProvider(name = "sql-session-manager-provider")
    public static Object[][] sqlSessionManagerProvider() throws SQLException, LiquibaseUpdateException {
        return new Object[][] {
                {createDerbySessionManager()},
                {createH2SessionManager()}
        };
    }

    private static SqlSessionManager createDerbySessionManager() throws SQLException, LiquibaseUpdateException {
        EmbeddedDataSource40 dataSource = new EmbeddedDataSource40();
        dataSource.setDatabaseName("memory:test-db");
        dataSource.setCreateDatabase("create");

        LiquibaseUtils.update(dataSource.getConnection(), LiquibaseUtils.DEFAULT_CONTEXTS);
        return MyBatisUtils.createSqlSessionManager(dataSource);
    }

    private static SqlSessionManager createH2SessionManager() throws SQLException, LiquibaseUpdateException {
        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL("jdbc:h2:mem:test-db;DB_CLOSE_DELAY=-1");

        LiquibaseUtils.update(dataSource.getConnection(), LiquibaseUtils.DEFAULT_CONTEXTS);
        return MyBatisUtils.createSqlSessionManager(dataSource);
    }
}

Затем я использую аннотацию @Factory в конструкторе расширяющихся классов.Это приводит к созданию одного экземпляра класса теста на SqlSessionManager из моего @DataProvider.

public class SequenceMapperTest extends MyBatisTestBase {
    private final SqlSessionManager sessionManager;
    private final SequenceMapper sequenceMapper;

    @Factory(dataProvider = "sql-session-manager-provider")
    public SequenceMapperTest(SqlSessionManager sessionManager) {
        this.sessionManager = sessionManager;
        this.sequenceMapper = sessionManager.getMapper(SequenceMapper.class);
    }

    @Test
    public void selectBidSequenceTest() {
        sequenceMapper.selectSequence(Sequences.BID_SEQ);
    }

    @Test
    public void updateBidSequenceTest() {
        sequenceMapper.updateSequence(sequenceMapper.selectSequence(Sequences.BID_SEQ));
    }

    @Override
    public SqlSessionManager getSessionManager() {
        return this.sessionManager;
    }
}

Когда я запускаю свои тесты, создается два экземпляра SequenceMapperTest, по одному для каждогоSqlSessionManager, который я настроил в @DataProvider.Пока, похоже, это работает, но у моей IDE (IntelliJ IDEA) есть небольшие проблемы с разделением результатов регистрации каждого отдельного теста.

...