在本文中,我们将看到如何使用Junit进行数据驱动的测试。 为此,我将使用一个名为EasyTest的库。
众所周知,对于TestNG,它已内置了数据提供程序。 通过简单的测试,我们可以使用Junit进行数据驱动的测试。
什么是数据驱动测试?
当测试由数据驱动时,则指的是数据驱动的测试。 正式定义可以在Wiki中找到。
总之,将对输入数据,预期输出,配置等进行参数化定义。 因此,最后,您不需要更改测试,但是随着数据的更改,您可以增加测试数量和覆盖范围。 这意味着,您的数据将驱动您的测试能力以及质量。
当您需要处理具有不同排列和组合的大量数据时,这是一种非常好的方法。
我在哪里使用这种方法?
1.当我需要检查大量数据并将其针对数据库查询或Web api方法(REST / SOAP)输出时。
2.当我需要使用不同的数据组合来驱动相同的UI测试时。
3.当我需要将日期更改行为与配置更改隔离开来时。
我们将如何实现?
我们将通过参数化测试解决此问题。 并且此参数将从我们定义的文件中获取值(测试数据)。 这是TestNG与Junit一起缺少的部分。 我们将使用EasyTest库解决。
注意:这不是我们使用Easy test的唯一原因。 简易测试还具有许多令人印象深刻的功能。 我们将一一看到。 这是github中的简单测试项目链接。
让我们学习Example:
为了学习,我正在使用简单的计算器类( Github链接 )。 只需将两个数字相加即可得到Double类型的结果。
public class Calculator {
public Double add(Double a, Double b){
return a+b;
}
}
而且,让我们在没有Easy Test的情况下创建一个测试用例。
public class SimpleTest extends DataDrivenTest{
@Test public void testAddition(){
Assert.assertEquals(25.5,calculator.add(10.5,15.0),0.01);
}
}
我们将使用Easy Test来开发这个简单的测试用例,因此让我们开始制作一个项目。
步骤A:创建Maven项目:
1.使用您最喜欢的组ID和工件ID创建一个Maven项目。 (我使用org.automation和数据驱动)
2.包括以下依赖项。
对于Junit(我们正在使用)
dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
轻松测试
<dependency>
<groupId>org.easetech</groupId>
<artifactId>easytest-core</artifactId>
<version>1.4.0</version>
</dependency>
并且用于日志记录(这是可选的)
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
[这足以使用简单的测试内部日志记录。
]
现在,要提供数据参数,我们需要包括数据文件。 作为最佳实践,我会将所有数据都用作资源 。 因此,我需要在pom中添加资源。 因此,最终项目pom.xml看起来像这样 。
<?xml version="1.0" encoding="UTF-8"?><project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.automation</groupId>
<artifactId>datadriven</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--Only mandatory part : start-->
<dependency>
<groupId>org.easetech</groupId>
<artifactId>easytest-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Only mandatory part: End -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/test/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
</project>
步骤B:创建数据文件:简易测试支持
1. Excel:Office 97/2003格式(xls扩展名)
2. CSV:逗号分隔值
3. XML
4.通过CSV文件的JSON格式。
注意:Easy test还支持自定义数据类型(我们将跳过此部分以使其在Blog中变得简单,您可以在Github中查看示例)
对于CSV和EXCEL,请遵循以下规则
1.第一行,第一列为方法名称(因此,此列的每一行将为空白)
2.第一行从第二列开始,所有将均为参数变量名称。
3.写入方法名称的列的所有行均为空白。
CSV:
Excel(.xls):
XML:
您可以在github中看到我所有的文件。
现在,让我们从其他数据加载器加载数据。
要加载数据,通常我们使用注释
1. @DataLoader定义文件源。
2. @Param定义将哪些列数据视为要获取的项目。
由于此批注特定于Easy Test,因此我们需要使用DataDrivenTestRunner.class来运行此测试类,该类由
因此,首先我们看到CSV数据加载器。
@RunWith(DataDrivenTestRunner.class)
public class CSVLoaderExample extends DataDrivenTest {
@Test @DataLoader(filePaths = "calculator.csv", loaderType = LoaderType.CSV)
public String testAddFromCSV(@Param(name = "a") Double a,
@Param(name = "b") Double b,
@Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
return "success";
}
@Test @DataLoader(filePaths = "calculator2.csv")
public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
Assert.assertEquals(expected, calculator.add(a,b),0.1);
}
}
在这里,您可以看到,我是
=>使用DataDrivenTestRunner.class运行测试
=>正在加载calculator.csv(还有另外一个)
=>获取名称为a,b的参数。
这是CSV文件的内容,看起来像
testAddFromCSV,a,b,expected
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,15.0,25.0,40
,900.0,250.0,1150.0
现在,您可能会问如何处理行。 轻松测试将每一行视为一条记录,它将根据数据文件中存在的行数来迭代我们的测试。 因此,为输入数据定义列已绰绰有余。
最佳实践:我过去一直遵循一个文件来提供输入数据以及预期的输出。 您可以为此使用单独的文件。
同样,如果我们查看excel数据加载器:
@RunWith(DataDrivenTestRunner.class)
public class ExcelLoaderExample extends DataDrivenTest {
@Test @DataLoader(filePaths = "calculator.xls", loaderType = LoaderType.EXCEL)
public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
@Test @DataLoader(filePaths = {"calculator2.xls"})
public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
Assert.assertEquals(expected, calculator.add(a,b),0.1);
}
}
和XML数据加载器
@RunWith(DataDrivenTestRunner.class)
public class XMLLoaderExample extends DataDrivenTest {
@Test @DataLoader(filePaths = "calculator2.xml", loaderType = LoaderType.XML)
public String testAddXMLOutput(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
return "success";
}
}
注意 :
1.文件路径包含物理路径,如果文件在类路径中,则文件名就足够了。 因此,当我定义pom.xml资源时,我们应该包括我们的数据文件以使其像这样工作。 或者我们保持正确的输入路径。
2.如果使用单个文件加载,则可以避免使用LoaderType参数。
3.使用多个相同类型的文件加载时,请确保没有相同的列名。 如果相同,将采用第二个或更高版本文件的列。 (Lifo方式,将保留最后一个文件)
4.在同一方法中不支持不同类型的加载器。 因此,您无法使用单个数据加载器以相同的方法加载Excel&CSV。 只有第一个会工作。
5.单个方法/类不支持多个数据加载器注释。
6.方法级数据加载器将重载类级数据加载器。
7.将单个文件用于多个测试方法的参数时,请使用类级别的数据加载器。
8.在参数中,使用的数据以长,字符串,双精度格式收敛。 但是我们可以将自定义数据类型与我们自己的解析器一起使用。 简易测试对此具有接口。 (使用AbstractConverter <YourDataType>)
9.如果需要自定义显示的参数数据,则可以在加载程序中使用@Display批注。 你可以在这里看到一个例子 。
这是多个数据加载器的一些示例:
@RunWith(DataDrivenTestRunner.class)
public class MultipleDataLoaderExample extends DataDrivenTest {
// only the first loader will be working.. // in here "calculator2.csv" @Test @DataLoader(filePaths = {"calculator2.csv","calculator3.xml"})
public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
@RunWith(DataDrivenTestRunner.class)
public class MultipleDataLoaderExampleSameType extends DataDrivenTest{
@Test @DataLoader(filePaths = {"calculator3.csv","calculator2.csv"})//calculator2 is accepted not 2=> why, it honors the last item, top item of the array list of files public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
Assert.assertEquals(expected, calculator.add(a,b),0.1);
}
}
现在,除了“数据加载”之外,“简易测试”还具有许多其他功能。 我没有详细说明,但每个示例都有示例。 因此,我在逐一解释的基础上加了一点。
报告:简单的测试提供了非常简单的报告……:)。 只需使用注释即可。 这里有一些例子。
默认报告:(输入PDF并存储在用户目录中)
@RunWith(DataDrivenTestRunner.class)
@Reportpublic class DefaultReportExample extends DataDrivenTest{
@Test @DataLoader(filePaths = "calculator2.xls")
public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
在类路径中更改类路径的报告:(报告存储在构建目录中,maven中的目标文件夹中)。 将创建一个文件夹名称TestReports
@RunWith(DataDrivenTestRunner.class)
@Report(outputLocation = "classpath:TestReports")
public class ClassPathExampleReport extends DataDrivenTest{
@Test @DataLoader(filePaths = "calculator.xls")
public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
@Test @DataLoader(filePaths = "calculator2.xls")
public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
在文件夹路径中更改类路径的报告:(我们在文件系统中指定)
@RunWith(DataDrivenTestRunner.class)
@Report(outputLocation = "file:TestReports")// default location = project working directorypublic class CustomPathExampleReport extends DataDrivenTest{
@Test @DataLoader(filePaths = "calculator.xls")
public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
@Test @DataLoader(filePaths = "calculator2.xls")
public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
在github仓库中,我给出了更多易于理解的示例。 这是重要的注意事项。
1.报告功能测试报告和性能测试报告有两种类型(包括运行测试的时间)。 我们可以创建多个报告类型。
2.报告制作速度慢,因此报告制作时间将包含在测试执行时间中
3.报告文件格式有3种类型。 Excel,PDF和HTML,其中pdf是默认选择。 我们可以创建多种报告类型格式。
4. @Report可以在类级别使用,这意味着在生成时,它包括所有测试方法结果。
5.报表位置可以存储特定的文件路径或构建目录中的类路径。 使用mvn clean时将清除类路径报告,因此请谨慎选择。
pdf报告样本:
并行线程:简单测试具有一个简单的批注@Parallel,我们可以在其中定义JVM将分配多少线程来测试一个测试类。
@Parallel(threads = 5)//this is very fragilepublic class ParallelTestExample extends DataDrivenTest_withDefaultAnnotation {
@Test @DataLoader(filePaths = "calculator.xls", loaderType = LoaderType.EXCEL)
public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
Assert.assertEquals(expected, calculator.add(a,b),0.1);
}
}
您可以看到,此测试将使用5个线程运行。
我们可以并行运行测试服,也可以并行运行
@RunWith(Suite.class)
@ParallelSuite(threads = 3)
@Suite.SuiteClasses({RepeatExample.class, TestWithPolicyExample.class})
public class ParallelSuitExample {
}
注意:这非常易碎。 它可能会导致资源分配错误。 而简单的测试并不能确保它们是并发的。
测试重复:在Easy Test中,我们可以使用注解@Repeat重复测试方法。
@RunWith(DataDrivenTestRunner.class)
@TestPolicy(PolicyExample.class)
public class RepeatExample extends DataDrivenTest {
@Test @Repeat(times = 5)
public void testAddFromExcel(@Param(name = "a") Double a,
@Param(name = "b") Double b,
@Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
它是串行运行的,而不是并行运行的。
测试属性:简易测试具有一个不错的注解@TestProperties,可用于直接从类路径中注入测试属性。
public class TestPropertiesExample extends DataDrivenTest_withDefaultAnnotation {
@TestProperties(value = {"test.properties"})
private Properties myProps;
@Test public void testAddition() {
Assert.assertEquals("Easy Test Demos", myProps.getProperty("test.title"));
}
}
[忽略延伸部分,不需要。
为了保持良好的测试,我用过。
您可以看到表格github来源。
]
测试策略:测试策略在Easy测试中非常有用,我们可以在单独的类中定义测试策略并在测试类中使用它。
为此,定义一个策略类。
@Ignore@Parallel(threads = 2)
@Report(reportTypes = {Report.REPORT_TYPE.DEFAULT,
Report.REPORT_TYPE.METHOD_DURATION},
outputFormats = Report.EXPORT_FORMAT.PDF,
outputLocation = "file:TestReports")
@DataLoader(filePaths = "calculator.xls")// i preffer data loder should be with method@Display(fields = "id")
public class PolicyExample {
}
并在测试课程中使用它
@RunWith(DataDrivenTestRunner.class)
@TestPolicy(PolicyExample.class)
public class TestWithPolicyExample extends DataDrivenTest {
@Test public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
Assert.assertEquals(expected, calculator.add(a, b), 0.1);
}
}
因此,我们可以看到,该策略将为线程定义数据文件+报告和并行线程。
在哪里使用?
=>在测试期间,如果我们认为需要单独进行测试配置。
=>当我们具有单独的测试配置以在不同情况下运行时。 例如在开发人员PC或CI中进行测试,或用于测试报告,或进行不同类型的测试等。
缺点:
1.错误消息不是用户友好的。 因此调试并不容易。 您需要了解简单的测试架构才能理解错误。
2.并行执行可能导致与错误相关的资源被锁定或繁忙。
3. Excel或CSV中的空白字符可能会导致错误。 因此,在创建数据文件时要小心。
4.存在一些已知的错误。 流行的错误之一是,仅通过excel数据加载器生成的测试失败报告。 其他数据加载器无法生成失败测试报告(仅生成通过测试报告)。
我希望这篇文章将有助于使用Easy test。 我的Github示例:https://github.com/sarkershantonu/Automation-Getting-Started/tree/master/junit-easytest
Todo:自定义数据类型转换器示例。 我将逐渐添加。
翻译自: https://www.javacodegeeks.com/2016/12/data-driven-testing-junit-easytest.html