
3.3 使用不同的数据源
数据驱动最好的方式是将数据源外部化,而不是硬编码在代码里。在3.2.6节的@CsvFileSource注解中使用了CSV文件将数据源外部化,这是JUnit自带的使用CSV数据源的方式,但TestNG并没有提供该类方法。本节将从CSV文件开始介绍使用各种数据源的方式,并结合TestNG来做演示。
3.3.1 使用CSV作为数据源
CSV(Comma-Separated Values,逗号分隔值)文件以csv为文件后缀名,在数据驱动测试领域使用非常广泛,比如JUnit的@CsvFileSource注解、JMeter配置元件中的CSV数据文件设置等。
首先引入Commons CSV依赖包:

Commons CSV是Apache Commons旗下的子项目,是一个常用的处理CSV文件的函数库。
创建一个工具类DataSourceUtil,并新增读取CSV文件的方法。


Commons CSV中提供了多种形式的CSVFormat,可在不同场景下使用。另外还可以读取带“表头”的CSV文件。有关Commons CSV的更多用法请读者自行查阅相关资料。
仍然以登录测试用例为例,将登录URL、用户名和密码抽离出来放在CSV文件中,文件内容如下。

使用@DataProvider引入测试数据,代码如下。


登录测试方法做相应的修改,代码如下。

执行登录测试方法,可以观察到CSV文件中的测试数据被成功传递到了测试方法中。
3.3.2 使用Excel作为数据源
Excel是常用的电子表格,以.xlsx或.xls作为文件后缀。本节使用POI OOXML函数库来读取Excel中的测试数据,POI OOXML属于Apache POI的子项目。
首先引入POI OOXML依赖包,代码如下。

然后在DataSourceUtil类中新增读取Excel文件的方法。


由于需要兼容.xlsx和.xls两种后缀的Excel文件,笔者单独抽离一个私有方法用于存放读取Excel文件的公共操作。

读者可能已经注意到,读取CSV文件和Excel文件时都用到了输入流,可以将这部分代码抽离成一个私有方法。

.xlsx后缀的Excel文件内容如图3-2所示。

图3-2 Excel文件的内容
修改数据提供者,将读取CSV文件的操作改为读取Excel文件的操作。

执行登录测试方法,可以观察到Excel文件中的测试数据被成功传递到了测试方法中。
读者可自行使用.xls后缀的Excel文件进行测试,使用效果相同。
3.3.3 使用Properties作为数据源
Properties是常用的配置文件,以properties后缀结尾。读取Properties文件非常简单,直接使用JDK自带的API即可完成。
首先在DataSourceUtil类中新增读取Properties文件的方法。


由于Properties一般用于配置文件,因此很适合存放测试项目的配置。前面的示例都将登录URL作为测试数据进行了参数化,更合理的方式是作为配置数据进行参数化。
接下来对测试类进行以下改造:
1)将建立会话和断开会话分别放在初始化和清理操作中;
2)将登录URL的赋值也放在初始化操作中。
改造后的测试类代码如下。


新增configdata.properties文件,文件内容如下。

最后需要删除Excel文件中的第一列(即登录URL)。
执行登录测试方法,可以观察到Properties文件中的数据被正确传递到了测试方法中。
3.3.4 使用YAML作为数据源
YAML(YAML Ain't Markup Language,YAML不是一种标记语言)文件比Properties文件语法更简洁,它也常被用于配置文件中,其文件后缀以yaml或yml结尾。关于YAML语法,读者请自行查阅相关资料来了解,本节仅演示一个简单的示例。
SnakeYAML是读取YAML文件的常用函数库,TestNG的依赖中已经自带了该函数库,可直接使用,如图3-3所示。
首先在DataSourceUtil类中新增读取YAML文件的方法。


图3-3 TestNG依赖中的SnakeYAML
然后修改初始化方法中获取登录URL的代码。

新增configdata.yaml文件,文件内容如下。

执行登录测试方法,YAML文件中的数据被正确传递到了测试方法中。
读者可自行使用yml后缀的YAML文件进行测试,使用效果保持一致。
3.3.5 使用数据库作为数据源
使用数据库作为数据源是比使用文件更重量级的一种方式。本节以MySQL数据库为例,并使用MySQL Connector/J函数库来提供MySQL数据库的驱动程序。因此需要首先引入MySQL Connector/J依赖包。

然后创建一个客户端类DatabaseClient,代码如下。



DatabaseClient类的作用是作为一个简单的关系型数据库通用客户端操作类,可对数据库进行建立会话、断开会话、查询数据和修改数据等操作。由于对数据库的操作是非常普遍的,因此该类的作用不仅限于数据驱动测试,还可以用于其他需操作数据库的场景。
鉴于DatabaseClient类的通用性,它不可能提供定制化的功能(即返回Object[][]类型的数据),因此需要一个“翻译”将数据库的返回数据类型从List<LinkedHashMap<String,Object>>转换为Object[][]。
在DadaSourceUtil中新增读取数据库数据的方法。

接下来创建一个名为testdata的MySQL数据库,再执行以下SQL语句初始化测试数据。

将登录测试方法中使用Excel读取测试数据的方法改成使用数据库读取测试数据的方法。

请注意以上数据库的IP、端口、用户名和密码为笔者搭建的MySQL数据库,读者需根据实际情况进行替换。
执行登录测试方法,可以观察到数据库中的数据被正确传递到了测试方法中。
以上介绍了5种数据源,那么每种数据源更适合哪种场景呢?
1)测试数据的存放:推荐使用CSV或Excel作为数据源。
2)配置数据的存放:推荐使用Properties或YAML作为数据源。
3)跨项目共享测试数据或配置数据:推荐使用数据库作为数据源。