集成测试是软件测试中的一个阶段。在该阶段中,各个软件模块被组合起来作为一个整体进行测试。进行集成测试是为了评估某系统或某组件是否符合指定的功能需求。
Apache IoTDB 集成测试的环境一共有3种,分别为本地单机测试环境、本地集群测试环境和远程测试环境。 Apache IOTDB 的集群测试需要在其中的1种或多种环境下完成。对于这三类环境的说明如下:
黑盒测试 是一种软件测试方法,它检验程序的功能,而不考虑其内部结构或工作方式。开发者不需要了解待测程序的内部逻辑即可完成测试。Apache IoTDB 的集成测试以黑盒测试的方式进行。通过 JDBC 或 Session API 的接口实现测试输入的用例即为黑盒测试用例。 因此,测试用例的输出验证也应该通过 JDBC 或 Session API 的返回结果实现。
集成测试的步骤主要分为三步,即 (1) 构建测试类和标注测试环境、(2) 设置测试前的准备工作以及测试后的清理工作以及 (3) 实现集成测试逻辑。如果需要测试非默认环境下的 IoTDB,还需要修改 IoTDB 的配置,修改方法对应小结的第4部分。
构建的集成测试类时,开发者需要在 Apache IoTDB 的 integration-test 模块中创建测试类。类名应当能够精简准确地表述该集成测试的目的。除用于服务其他测试用例的类外,含集成测试用例用于测试 Apache IoTDB 功能的类,应当命名为“功能+IT”。例如,用于测试IoTDB自动注册元数据功能的集成测试命名为“IoTDBAutoCreateSchemaIT”。
@Category注明测试环境 ,测试环境用LocalStandaloneIT.class、ClusterIT.class 和 RemoteIT.class来表示,分别与“Apache IoTDB 集成测试的环境”中的本地单机测试环境、本地集群测试环境和远程测试环境对应。标签内是测试环境的集合,可以包含多个元素,表示在多种环境下分别测试。一般情况下,标签LocalStandaloneIT.class 和 ClusterIT.class 是必须添加的。 当某些功能仅支持单机版 IoTDB 时可以只保留LocalStandaloneIT.class。@RunWith(IoTDBTestRunner.class) 标签。// 给 IoTDBAliasIT 测试类加标签,分别在本地单机测试环境、 // 本地集群测试环境和远程测试环境完成测试。 @RunWith(IoTDBTestRunner.class) @Category({LocalStandaloneIT.class, ClusterIT.class, RemoteIT.class}) public class IoTDBAliasIT { ... } // 给 IoTDBAlignByDeviceIT 测试类加标签,分别在本地单机 // 测试环境和本地集群测试环境完成测试。 @RunWith(IoTDBTestRunner.class) @Category({LocalStandaloneIT.class, ClusterIT.class}) public class IoTDBAlignByDeviceIT { ... }
测试前的准备工作包括启动 IoTDB(单机或集群)实例和测试用的数据准备。这些逻辑在setUp方法内实现。其中setUp方法前需要添加@BeforeClass 或 @Before 标签,前者表示该方法为当前集成测试执行的第 1 个方法,并且在集成测试运行时只执行 1 次,后者表示在运行当前集成测试的每 1 个测试方法前,该方法都会被执行 1 次。
EnvFactory.getEnv().initBeforeClass()。@BeforeClass public static void setUp() throws Exception { // 启动 IoTDB 实例 EnvFactory.getEnv().initBeforeClass(); ... // 准备数据 }
测试后需要清理相关的环境,其中需要断开还没有关闭的连接。这些逻辑在 tearDown 方法内实现。其中 tearDown 方法前需要添加@AfterClass 或 @After 标签,前者表示该方法为当前集成测试执行的最后一个方法,并且在集成测试运行时只执行 1 次,后者表示在运行当前集成测试的每一个测试方法后,该方法都会被执行 1 次。
EnvFactory.getEnv().cleanAfterClass()。@AfterClass public static void tearDown() throws Exception { ... // 断开连接等 // 清理 IoTDB 实例的环境 EnvFactory.getEnv().cleanAfterClass(); }
Apache IoTDB 的集成测试以黑盒测试的方式进行,测试方法的名称为“测试的功能点+Test”,例如“selectWithAliasTest”。测试通过 JDBC 或 Session API 的接口来完成。
1、使用JDBC接口
使用JDBC接口时,建议将连接建立在 try 语句内,以这种方式建立的连接无需在 tearDown 方法内关闭。连接需要通过工厂类来建立,即EnvFactory.getEnv().getConnection(),不要指定具体的 ip 地址或端口号。示例代码如下所示。
@Test public void someFunctionTest(){ try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { ... // 执行相应语句并做测试 } catch (Exception e) { e.printStackTrace(); Assert.fail(); } }
注意:
executeQuery()方法,返回ResultSet; 对于更新数据库等无返回值的操作,必须使用execute()方法。 示例代码如下。@Test public void exampleTest() throws Exception { try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { // 使用 execute() 方法设置存储组 statement.execute("CREATE DATABASE root.sg"); // 使用 executeQuery() 方法查询存储组 try (ResultSet resultSet = statement.executeQuery("show databases")) { if (resultSet.next()) { String storageGroupPath = resultSet.getString("database"); Assert.assertEquals("root.sg", storageGroupPath); } else { Assert.fail("This ResultSet is empty."); } } } }
2、使用 Session API
目前暂不支持使用 Session API 来做集成测试。
3、测试方法的环境标签 对于测试方法,开发者也可以指定特定的测试环境,只需要在对应的测试方法前注明环境即可。值得注意的是,有额外测试环境标注的用例,不但会在所指定的环境中进行测试,还会在该用例隶属的测试类所对应的环境中进行测试。示例代码如下。
@RunWith(IoTDBTestRunner.class) @Category({LocalStandaloneIT.class}) public class IoTDBExampleIT { // 该用例只会在本地单机测试环境中进行测试 @Test public void theStandaloneCaseTest() { ... } // 该用例会在本地单机测试环境、本地集群测试环境和远程测试环境中进行测试 @Test @Category({ClusterIT.class, RemoteIT.class}) public void theAllEnvCaseTest() { ... } }
有时,为了测试 IoTDB 在特定配置条件下的功能需要更改其配置。由于远程的机器配置无法修改,因此,需要更改配置的测试不支持远程测试环境,只支持本地单机测试环境和本地集群测试环境。配置文件的修改需要在setUp方法中实现,在EnvFactory.getEnv().initBeforeClass()之前执行,应当使用 ConfigFactory 提供的方法来实现。在 tearDown 方法内,需要将 IoTDB 的配置恢复到原默认设置,这一步在环境清理(EnvFactory.getEnv().cleanAfterTest())后通过调用ConfigFactory提供的方法来执行。实例代码如下。
@RunWith(IoTDBTestRunner.class) @Category({LocalStandaloneIT.class, ClusterIT.class}) public class IoTDBAlignedSeriesQueryIT { protected static boolean enableSeqSpaceCompaction; protected static boolean enableUnseqSpaceCompaction; protected static boolean enableCrossSpaceCompaction; @BeforeClass public static void setUp() throws Exception { // 获取默认配置 enableSeqSpaceCompaction = ConfigFactory.getConfig().isEnableSeqSpaceCompaction(); enableUnseqSpaceCompaction = ConfigFactory.getConfig().isEnableUnseqSpaceCompaction(); enableCrossSpaceCompaction = ConfigFactory.getConfig().isEnableCrossSpaceCompaction(); // 更新配置 ConfigFactory.getConfig().setEnableSeqSpaceCompaction(false); ConfigFactory.getConfig().setEnableUnseqSpaceCompaction(false); ConfigFactory.getConfig().setEnableCrossSpaceCompaction(false); EnvFactory.getEnv().initBeforeClass(); AlignedWriteUtil.insertData(); } @AfterClass public static void tearDown() throws Exception { EnvFactory.getEnv().cleanAfterClass(); // 恢复为默认配置 ConfigFactory.getConfig().setEnableSeqSpaceCompaction(enableSeqSpaceCompaction); ConfigFactory.getConfig().setEnableUnseqSpaceCompaction(enableUnseqSpaceCompaction); ConfigFactory.getConfig().setEnableCrossSpaceCompaction(enableCrossSpaceCompaction); } }
1、点击出错的测试对应的 Details
2、查看和下载日志
也可以点击左上角的 summary 然后查看和下载其他错误日志。