TestContainers:现代数据库的测试方法 -Gundu


TestContainers是一个开源项目,它提供可以在Docker容器中运行的任何东西的轻量级,一次性的实例。它具有Java,Python,Rust,Go,Scala和许多其他语言的绑定。
启动MySQL数据库测试就像添加3行代码一样简单:

class SimpleMySQLTest {
    private MySQLContainer mysql = new MySQLContainer();

    @Before
    void before() {
        mysql.start();
       // You can use mysql.getJdbcUrl(), mysql.getUsername() and
     
// mysql.getPassword() to connect to the container 

    }

    @After
    void after() {
        mysql.stop();
    }

   
// [...]
}

TestContainers提供@ Rule / @ClassRule集成,以允许JUnit 4控制容器的生命周期。它还提供了一个@Container标注为Junit5。这些实用程序将其简化为仅一行代码。
HibernateORM是与Java中的数据库进行交互的最受欢迎的选择。要将您的Hibernate类连接到TestContainers,就这么简单:

class SimpleHibernateTest {
    
    @Rule
    private MySQLContainer mysql = new MySQLContainer().withDatabaseName("local").withUsername("USER").withPassword("PWD");

    @Before
    public void before() {
      final Configuration configuration = new Configuration();
     
// Base configuration
      configuration.configure(
"hibernate.cfg.xml")
      final Properties properties = new Properties();
      properties.setProperty(
"hibernate.hikari.dataSource.url", mysql.getJdbcUrl());
      properties.setProperty(
"hibernate.hikari.datasource.user", "USER");
     properties.setProperty(
"hibernate.hikari.datasource.password", "PWD");
     configuration.addProperties(properties);
     configuration.addAnnotatedClass(ClassToTest.class);
    }

   @Test
   public void test() {
   
// write test case here
   }
}

局限性:
当然,使用TestContainers有缺点。与H2相比,测试用例要慢得多。有减轻这种情况的方法。该@rule注释带来了为让班上所有的测试用例一个新的数据库。建立数据库是一项昂贵的操作,我们可以使用@ClassRule对其进行优化。使用@ClassRule时,将为该类中的所有测试建立一个数据库。在这种情况下,确保在运行测试用例后清理数据库中的数据非常重要,以确保测试隔离。这可以通过使用@After生命周期来完成。
另一个缺点是,如果无法下载docker映像,则测试用例可能会失败。但是,与使用TestContainers的好处相比,这些缺点很小。