在自动化 API/Web 或移动应用程序时,您可能会遇到这样的情况:在注册用户时,您可能正在设置用于在测试自动化的端到端用户旅程中签出产品的地址。
那么,你是怎么做到的呢?
通常,我们在 Java 中创建一个 POJO 类,其中包含注册用户或设置签出产品地址所需的字段,然后使用 POJO 类的构造函数在测试中设置值。
让我们看一个注册用户的示例,其中以下字段是填写注册表单所需的必填字段:
名字
姓
地址
城市
州
国家
手机号码
由于我们需要在自动化测试中处理这些字段,因此在执行测试时,我们必须在字段中传递相应的值。
使用构建器模式之前
将使用该 POJO 类中的 Getter 和 Setter 方法创建具有上述必填字段的 POJO 类,并使用构造函数在相应字段中设置值。
查看下面给出的代码示例,了解我们正在讨论的内容。RegisterUser class
1
public class RegisterUser {
2
private String firstName;
3
private String lastName;
4
private String address;
5
private String city;
6
private String state;
7
private String country;
8
private String mobileNumber;
9
10
public RegisterUser (final String firstName, final String lastName, final String address, final String city,
11
final String state, final String country, final String mobileNumber) {
12
this.firstName = firstName;
13
this.lastName = lastName;
14
this.address = address;
15
this.city = city;
16
this.state = state;
17
this.country = country;
18
this.mobileNumber = mobileNumber;
19
}
20
21
public String getFirstName () {
22
return firstName;
23
}
24
25
public void setFirstName (final String firstName) {
26
this.firstName = firstName;
27
}
28
29
public String getLastName () {
30
return lastName;
31
}
32
33
public void setLastName (final String lastName) {
34
this.lastName = lastName;
35
}
36
37
public String getAddress () {
38
return address;
39
}
40
41
public void setAddress (final String address) {
42
this.address = address;
43
}
44
45
public String getCity () {
46
return city;
47
}
48
49
public void setCity (final String city) {
50
this.city = city;
51
}
52
53
public String getState () {
54
return state;
55
}
56
57
public void setState (final String state) {
58
this.state = state;
59
}
60
61
public String getCountry () {
62
return country;
63
}
64
65
public void setCountry (final String country) {
66
this.country = country;
67
}
68
69
public String getMobileNumber () {
70
return mobileNumber;
71
}
72
73
public void setMobileNumber (final String mobileNumber) {
74
this.mobileNumber = mobileNumber;
75
}
76
}
现在,如果我们想使用这个 POJO,我们必须创建一个 class 的实例并传递以下代码示例中给出的值,以在相应的字段中设置数据。RegisterUser
constructor parameters
看看下面的测试示例,了解我们如何做到这一点。Register User
1
public class RegistrationTest {
2
3
@Test
4
public void testRegisterUser () {
5
RegisterUser registerUser = new RegisterUser ("John", "Doe", "302, Adam Street, 1st Lane", "New Orleans",
6
"New Jersey", "US", "52145364");
7
8
assertEquals (registerUser.getFirstName (), "John");
9
assertEquals (registerUser.getCountry (), "US");
10
}
11
}
在我们用于注册用户的示例中,只有七个字段。但是,并非每个应用程序都是如此。还需要一些额外的字段,并且随着字段每次都在不断增加,我们需要使用相应的 Getter 和 Setter 方法更新 POJO 类,并更新 constructor 中的参数。
最后,我们需要将值添加到这些字段中,以便数据可以在所需的实际字段中传递。
长话短说,即使添加了一个新字段,我们也需要更新代码,而且,在测试中添加值作为参数看起来并不干净。
幸运的是,Java 中的 Builder Design Pattern 在这里派上了用场。
什么是 Java 中的构建器设计模式?
构建器设计模式是一种创建性设计模式,可让您逐步构造复杂的对象。该模式允许您使用相同的构造代码生成对象的不同类型和表示形式。
Builder Pattern 通过提供一种返回可在实际测试中使用的最终对象的方法,提供一种逐步构建对象的方法,帮助我们解决设置参数的问题。
什么是Project Lombok?
Project Lombok 是一个 Java 库,它会自动插入您的编辑器并构建工具,为您的 Java 增添趣味。它是一个基于注释的 Java 库,有助于减少样板代码。
它可以帮助我们编写简短明了的代码,而无需编写样板代码。绕过类上的注释,它会自动生成 Getter 方法。同样,您也不必为 Setter 方法编写代码,其注释在类上更新会自动生成 Setter 方法。@Getter
@Setter
它还支持使用 Builder 设计模式,因此我们只需要将注释放在类的上方,其余的将由 Lombok 库处理。@Builder
要在项目中使用 Lombok 注解,我们需要添加以下 Maven 依赖项:
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>
在 Lombok 中使用 Builder 设计模式
在我们开始重构我们编写的代码之前,让我向您介绍一下 DataFaker 库,以及它如何帮助生成可用于测试的虚假数据。理想情况下,在我们的示例中,每个新注册用户的数据都应该是唯一的,否则我们可能会收到重复的数据错误,测试将失败。
在这里,DataFaker库将帮助我们在每次测试执行中提供唯一的数据,从而帮助我们在每次运行注册测试时注册具有唯一数据的新用户。
要使用 DataFaker 库,我们需要将以下 Maven 依赖项添加到我们的项目中。
XML格式
1
<!-- https://mvnrepository.com/artifact/net.datafaker/datafaker -->
2
<dependency>
3
<groupId>net.datafaker</groupId>
4
<artifactId>datafaker</artifactId>
5
<version>2.2.2</version>
6
</dependency>
7
现在,让我们开始重构代码。首先,我们将对类进行更改。我们将删除所有 Getter 和 Setter 方法以及构造函数,并在 .RegisterUser
@Getter
@Builder
RegisterUser class
这是重构后现在的样子RegisterUser class
1
@Getter
2
@Builder
3
public class RegisterUserWithBuilder {
4
private String firstName;
5
private String lastName;
6
private String address;
7
private String city;
8
private String state;
9
private String country;
10
private String mobileNumber;
11
}
完成重构后,它看起来多么干净和清晰。多行代码被删除,但它仍然以与之前相同的方式工作,这要归功于龙目岛。
我们必须添加一个新的 Java 类,以便使用 Builder 设计模式在运行时生成虚假数据。我们将这个新类称为 .DataBuilder class
1
public class DataBuilder {
2
3
private static final Faker FAKER = new Faker();
4
5
public static RegisterUserWithBuilder getUserData () {
6
return RegisterUserWithBuilder.builder ()
7
.firstName (FAKER.name ()
8
.firstName ())
9
.lastName (FAKER.name ()
10
.lastName ())
11
.address (FAKER.address ()
12
.streetAddress ())
13
.state (FAKER.address ()
14
.state ())
15
.city (FAKER.address ()
16
.city ())
17
.country (FAKER.address ()
18
.country ())
19
.mobileNumber (String.valueOf (FAKER.number ()
20
.numberBetween (9990000000L, 9999999999L)))
21
.build ();
22
}
23
}
该方法将返回使用 DataFaker 库注册用户所需的测试数据。请注意类名之后使用的方法。之所以出现它,是因为我们在 RegisterUserWithBuilder 类的顶部使用了批注。getUserData()
builder()
RegisterUserWithBuilder
@Builder
在方法之后,我们必须传递我们在 中声明的变量,并相应地传递我们需要为相应变量生成的假数据。builder()
RegisterUserWithBuilder class
1
RegisterUserWithBuilder.builder ()
2
.firstName (FAKER.name ()
3
.firstName ());
上面的一段代码将生成一个假的名字,并将其设置在名字变量中。同样,我们在所有其他变量中都设置了假数据。
现在,让我们来看看如何在测试中使用这些数据。这很简单,下面的代码片段解释了这一切。
1
@Test
2
public void testRegisterUserWithBuilder () {
3
RegisterUserWithBuilder registerUserWithBuilder = getUserData ();
4
5
System.out.println (registerUserWithBuilder.getFirstName ());
6
System.out.println (registerUserWithBuilder.getLastName ());
7
System.out.println (registerUserWithBuilder.getAddress ());
8
System.out.println (registerUserWithBuilder.getCity ());
9
System.out.println (registerUserWithBuilder.getState ());
10
System.out.println (registerUserWithBuilder.getCountry ());
11
System.out.println (registerUserWithBuilder.getMobileNumber ());
12
}
只需要在实例化 . 接下来,我们将为我们在 . 请记住,我们已经传递了顶部的注释,这实际上有助于在此处调用 Getter 方法。getUserData()
RegisterUserWithBuilder class
RegisterUserWithBuilder class
@Getter
RegisterUserWithBuilder class
此外,我们不需要传递多个数据作为类的构造函数参数,而只需要实例化类并调用该方法即可!RegisterUserWithBuilder
getUserData()
生成唯一数据并在测试中传递是多么容易,而无需编写多行样板代码。
运行测试
运行测试并检查用户详细信息是否打印在控制台中。在以下测试执行的屏幕截图中,我们可以看到假数据是成功生成的。
如何利用 Java 中的构建器设计模式以及 Lombok 和 DataFaker 库在运行时生成虚假测试数据,并将其用于我们的自动化测试。它将通过消除在运行测试之前更新测试数据的需要来简化测试数据生成过程。