1. Overview
1.概述
In this article, we will introduce the ZeroCode automated testing framework. We’ll learn the fundamentals through an example of REST API testing.
在这篇文章中,我们将介绍ZeroCode自动化测试框架。我们将通过一个REST API测试的例子来学习基础知识。
2. The Approach
2.办法
The ZeroCode framework takes the following approaches:
ZeroCode框架采取了以下方法。
- Multi-faceted testing support
- The declarative style of testing
Let’s discuss them both.
让我们来讨论一下这两个问题。
2.1. Multi-Faceted Testing Support
2.1.多方面的测试支持
The framework is designed to support automated testing of multiple facets of our applications. Among other things, it gives us the ability to test:
该框架旨在支持对我们应用程序的多个方面进行自动化测试。在其他方面,它使我们有能力测试。
- REST
- SOAP
- Security
- Load/Stress
- Database
- Apache Kafka
- GraphQL
- Open API Specifications
Testing is done via the framework’s DSL that we will discuss shortly.
测试是通过框架的DSL完成的,我们很快就会讨论。
2.2. Declarative Style
2.2.声明性风格
ZeroCode uses a declarative style of testing, which means that we don’t have to write actual testing code. We declare scenarios in JSON/YAML files, and the framework will ‘translate’ them into test code behind-the-scenes. This helps us to concentrate on what we want to test instead of how to test it.
ZeroCode使用声明式的测试方式,这意味着我们不需要编写实际的测试代码。我们在JSON/YAML文件中声明场景,框架会在幕后将它们 “翻译 “成测试代码。这有助于我们专注于我们想要测试的东西,而不是如何测试它。
3. Setup
3.设置
Let’s add the Maven dependency in our pom.xml file:
让我们在pom.xml文件中添加Maven的依赖性。
<dependency>
<groupId>org.jsmart</groupId>
<artifactId>zerocode-tdd</artifactId>
<version>1.3.27</version>
<scope>test</scope>
</dependency>
The latest version is available on Maven Central. We can use Gradle as well. If we’re using IntelliJ, we can download the ZeroCode plugin from Jetbrains Marketplace.
最新的版本可以在Maven中心上找到,。我们也可以使用Gradle。如果我们使用IntelliJ,我们可以从Jetbrains Marketplace下载ZeroCode插件。
4. REST API Testing
4.REST API测试
As we said above, ZeroCode can support testing multiple parts of our applications. In this article, we’ll focus on REST API testing. For that reason, we’ll create a small Spring Boot web app and expose a single endpoint:
正如我们上面所说,ZeroCode可以支持测试我们应用程序的多个部分。在这篇文章中,我们将专注于REST API测试。为此,我们将创建一个小型的Spring Boot网络应用,并暴露一个单一的端点。
@PostMapping
public ResponseEntity create(@RequestBody User user) {
if (!StringUtils.hasText(user.getFirstName())) {
return new ResponseEntity("firstName can't be empty!", HttpStatus.BAD_REQUEST);
}
if (!StringUtils.hasText(user.getLastName())) {
return new ResponseEntity("lastName can't be empty!", HttpStatus.BAD_REQUEST);
}
user.setId(UUID.randomUUID().toString());
users.add(user);
return new ResponseEntity(user, HttpStatus.CREATED);
}
Let’s see the User class that’s referenced in our controller:
让我们看看控制器中引用的User类。
public class User {
private String id;
private String firstName;
private String lastName;
// standard getters and setters
}
When we create a user, we set a unique id and return the whole User object back to the client. The endpoint is reachable at the /api/users path. We’ll be saving users in memory to keep things simple.
当我们创建一个用户时,我们设置一个唯一的ID并将整个User对象返回给客户端。该端点可在/api/users路径上到达。我们将在内存中保存用户,以保持事情的简单。
5. Writing a Scenario
5.写作情景剧
The scenario plays a central role in ZeroCode. It consists of one or more steps, which are the actual things we want to test. Let’s write a scenario with a single step that tests the successful path of user creation:
场景在ZeroCode中起着核心作用。它由一个或多个步骤组成,这些步骤是我们要测试的实际内容。让我们写一个只有一个步骤的场景,测试创建用户的成功路径。
{
"scenarioName": "test user creation endpoint",
"steps": [
{
"name": "test_successful_creation",
"url": "/api/users",
"method": "POST",
"request": {
"body": {
"firstName": "John",
"lastName": "Doe"
}
},
"verify": {
"status": 201,
"body": {
"id": "$NOT.NULL",
"firstName": "John",
"lastName": "Doe"
}
}
}
]
}
Let’s explain what each of the properties represents:
让我们解释一下每个属性代表什么。
- scenarioName – This is the name of the scenario; we can use any name we want
- steps – an array of JSON objects, where we describe what we want to test
- name – the name that we give to the step
- url – relative URL of the endpoint; we can also put an absolute URL, but generally, it’s not a good idea
- method – HTTP method
- request – HTTP request
- body – HTTP request body
- verify – here, we verify/assert the response that the server returned
- status – HTTP response status code
- body (inside verify property) – HTTP response body
In this step, we check if user creation is successful. We check the firstName and lastName values that the server returns. Also, we verify that the id is not null with ZeroCode’s assertion token.
在这一步,我们检查用户创建是否成功。我们检查服务器返回的firstName和lastName值。同时,我们用ZeroCode的断言令牌验证id是否为null。
Generally, we have more than one step in scenarios. Let’s add another step inside our scenario’s steps array:
一般来说,我们在场景中拥有不止一个步骤。让我们在场景的steps数组中增加一个步骤。
{
"name": "test_firstname_validation",
"url": "/api/users",
"method": "POST",
"request": {
"body": {
"firstName": "",
"lastName": "Doe"
}
},
"verify": {
"status": 400,
"rawBody": "firstName can't be empty!"
}
}
In this step, we supply an empty first name that should result in a bad request. Here, the response body will not be in JSON format, so we use the rawbody property to refer to it as a plain string.
在这一步,我们提供一个空的名字,应该会导致一个坏的请求。在这里,响应体不会是JSON格式,所以我们使用rawbody属性来指代它是一个普通字符串。
ZeroCode can’t directly run the scenario — for that, we need a corresponding test case.
ZeroCode不能直接运行该场景–为此,我们需要一个相应的测试案例。
6. Writing a Test Case
6.编写测试案例
To execute our scenario, let’s write a corresponding test case:
为了执行我们的方案,让我们写一个相应的测试案例。
@RunWith(ZeroCodeUnitRunner.class)
@TargetEnv("rest_api.properties")
public class UserEndpointIT {
@Test
@Scenario("rest/user_create_test.json")
public void test_user_creation_endpoint() {
}
}
Here, we declare a method and mark it as a test using the @Test annotation from JUnit 4. We can use JUnit 5 with ZeroCode for load testing only.
在这里,我们声明一个方法并使用JUnit 4的@Test注解将其标记为测试。我们可以将JUnit 5与ZeroCode一起使用,只用于负载测试。
We also specify the location of our scenario with the @Scenario annotation, which comes from the ZeroCode framework. The method body is empty. As we said, we don’t write actual testing code. What we want to test is described in our scenario. We just reference the scenario in a test case method. Our UserEndpointIT class has two annotations:
我们还用@Scenario注解来指定我们的场景的位置,它来自ZeroCode框架。方法主体是空的。正如我们所说,我们不写实际的测试代码。我们想要测试的东西在我们的场景中被描述。我们只是在测试用例方法中引用该场景。我们的UserEndpointIT类有两个注解。
- @RunWith – here, we specify which ZeroCode class is responsible for running our scenarios
- @TargetEnv – this points to the property file that will be used when our scenario runs
When we declared the url property above, we specified the relative path. Obviously, the ZeroCode framework needs an absolute path, so we create a rest_api.properties file with a few properties that define how our test should run:
当我们在上面声明url属性时,我们指定了相对路径。显然,ZeroCode框架需要一个绝对路径,所以我们创建了一个rest_api.properties文件,其中有几个属性,定义了我们的测试应该如何运行。
- web.application.endpoint.host – the host of REST API; In our case, it’s http://localhost
- web.application.endpoint.port – the port of the application server where our REST API is exposed; In our case, it’s 8080
- web.application.endpoint.context – the context of the API; in our case, it’s empty
The properties that we declare in the property file depend on what kind of testing we’re doing. For example, if we want to test a Kafka producer/consumer, we’ll have different properties.
我们在属性文件中声明的属性取决于我们正在进行的测试类型。例如,如果我们想测试一个Kafka生产者/消费者,我们将有不同的属性。
7. Executing a Test
7.执行一个测试
We’ve created a scenario, property file, and test case. Now, we’re ready to run our test. Since ZeroCode is an integration testing tool, we can leverage Maven’s failsafe plugin:
我们已经创建了一个场景、属性文件和测试案例。现在,我们准备运行我们的测试。由于ZeroCode是一个集成测试工具,我们可以利用Maven的failsafe插件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
To run the test, we can use the following command:
要运行该测试,我们可以使用以下命令。
mvn verify -Dskip.it=false
ZeroCode creates multiple types of logs that we can check out in the ${project.basedir}/target folder.
ZeroCode创建了多种类型的日志,我们可以在${project.basedir}/target文件夹中检查出来。
8. Conclusion
8.结语
In this article, we took a look at the ZeroCode automated testing framework. We showed how the framework works with the example of REST API testing. We also learned that ZeroCode DSL eliminates the need for writing actual testing code.
在这篇文章中,我们看了一下ZeroCode自动化测试框架。我们以REST API测试为例,展示了该框架是如何工作的。我们还了解到,ZeroCode DSL消除了编写实际测试代码的需要。
As always, the source code of the article is available over on GitHub.
一如既往,该文章的源代码可在GitHub上获取。