当前位置:网站首页>Making single test so simple -- initial experience of Spock framework
Making single test so simple -- initial experience of Spock framework
2022-06-27 19:16:00 【User 3147702】
1. introduction
Testing process is becoming more and more important in the process of software development , Because no matter how experienced developers are , It is hard to avoid mistakes or even logical errors in the coding process , Under such premise , Unit testing is very important . Unit tests cover each part of the program by performing independent tests , And automatically execute after each code update , It ensures that the new changes will not affect the old functions . so to speak , Writing unit tests allows programmers to find problems as early as possible 、 Expose the problem , Thus, the whole coding process is more controllable , meanwhile , Attention to detail in writing unit tests , It also makes programmers think more about the robustness of their own programs . But unit testing also means that we need to maintain business code while , Process and use cases for additional maintenance unit tests , Undoubtedly, it increases the maintenance cost , For the handover of program development , Except for documents 、 Business code , You also need to read and understand the previous unit testing process , Undoubtedly, it also makes it more difficult for newcomers to get started . Since unit testing is so important , So can we find an efficient way to write 、 Easy to maintain 、 Simple and easy to understand unit test framework ?java Medium spock It is with this idea that a testing framework was born .
2. spock
Digression , mention spock, Maybe your first thought is 《 Star Trek 》 Well
before , We introduced java Another testing framework for — JUnit
JUnit Is a set of use through java Language implementation of a set of mature unit testing tools , But because java Its complexity ,JUnit A lot of code needs to be maintained to implement very basic test functions , If you still need mock And other additional test functions , You also need to introduce mokito Etc , Undoubtedly, it increases the learning cost . spock It's through groovy Realized ,groovy It's a kind of jvm Dynamic language running under , And java The main difference is groovy Have stronger semantics , Flexible writing , High readability , Although for writing larger projects , Dynamic languages are often difficult to maintain because of their excessive flexibility , But for the scenario of pursuing convenience and efficiency such as unit testing , Dynamic languages are compared to java Is more comfortable , At the same time ,groovy compatible java grammar , Can be called directly java api, This makes java Programmers have no difficulty getting started . Now let's practice .
3. preparation
3.1. Introduce dependencies
Use spock frame , We first need to introduce the following maven rely on , To pull the required series jar package .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.spockframework/spock-core -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.3-groovy-2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.spockframework/spock-spring -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>1.3-groovy-2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.5</version>
<type>test</type>
</dependency>3.2. Create the tested class
Let's write a very simple calculator class as an example .
package cn.techlog.testspring.testspring.service;
public class Calculate {
public int add(int num1, int num2) {
return num1 + num2;
}
public int sub(int num1, int num2) {
return num1 - num2;
}
public int mul(int num1, int num2) {
return num1 * num2;
}
public int div(int num1, int num2) {
return num1 / num2;
}
}4. Unit test writing
4.1. Create test class
stay test Under the path , Let's create a name CalculateTest Of groovy class:
package service
import spock.lang.Specification
class CalculateTest extends Specification {
Calculate calculate = new Calculate()
}In this class , We created a member variable calculate, For the next test .
4.2. expect — The most basic verification
def "test add"() {
expect:
calculate.add(1, 2) == 3
}def yes groovy Key words of , It can be used to create variables or methods , Here we create a new one called “test add” The test method of . expect Keywords allow us to implement the simplest verification , If you pass parameters 1 and 2, The return value is not 3, The test case will fail to execute .
Perform test methods , We can see the results of the test :
If execution fails , It will show :
4.3. expect where — Test that implements multiple test cases
In the above example, we only use one test case , But often we want to achieve batch testing of multiple test cases . This is the time ,where The key words come in handy .
def "test add"() {
expect:
calculate.add(num1, num2) == result
where:
num1 | num2 | result
1 | 1 | 2
3 | 0 | 3
4 | 2 | 6
}We can also write it another way :
def "test add"() {
expect:
calculate.add(num1, num2) == result
where:
num1 << [1, 3, 4]
num2 << [1, 0 ,2]
result << [2, 3, 6]
}such , When we run , Each use case will be executed in sequence , Make testing easier .
4.4. @Unroll annotation — Let the test results be displayed in strips
Above picture , Although we ran multiple test cases , But the results are shown in a single result , such , When something goes wrong in our use case , It is difficult to locate directly , Since there are multiple use cases , We expect, of course, that each use case will occupy a separate line of results to display . spock The framework also provides a mechanism for batch test splitting , Just add... To the method @Unroll annotation , Multiple test cases will be shown separately in the results .
4.5. when then — Advanced test scenarios
Some test scenarios use expect It's hard to achieve , For example, we expect the function to throw an exception , At this time, you can use the whenthen Block .
def "test div"() {
when:
calculate.div(1, 0)
then:
def ex = thrown(ArithmeticException)
ex.message == "/ by zero"
}4.6. @Timeout — Test timeout
Add... To the method @Timeout annotation , You can specify the timeout of test cases .
@Timeout(value = 900, unit = TimeUnit.MILLISECONDS)
def "test div"() {
when:
calculate.div(1, 0)
then:
def ex = thrown(ArithmeticException)
ex.message == "/ by zero"
}4.7. with — Test object members
The above are the basic types of numbers tested , What if we want to test whether the value of each field of an object meets the expectation ? Through the above methods will appear more cumbersome . with To solve this problem .
def "test findByName by verity"() {
given:
def userDao = Mock(UserDao)
when:
userDao.findByName("kk") >> new User("kk", 12, "33")
then:
def user = userDao.findByName("kk")
with(user) {
name == "kk"
age == 12
passwd == "33"
}
}5. Mock test
In engineering projects , The programs we write often rely on external interface calls , But in the single test , We should ensure the correctness of our program results on the premise that the external interface returns the correct results , However, due to the actual operating environment 、 Permission and other conditions , We can't really call external interfaces in routine automated unit tests , At this point, it reflects Mock The importance of testing . Mock The test simulates the results of an external call , Let our test program continue to run , stay JUnit in , We need to use Mockit To implement the interface Mock, meanwhile ,Mock The compilation of is also complicated , These in spock It is very simple in .
5.1. preparation
Let's go Calculate Class slightly changed , As sub The subtraction of the second parameter of the method is obtained from another service , This service requires a parameter that is our minuend :
package cn.techlog.testspring.testspring.service;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class Calculate {
@Resource
private RemoteGateway remoteGateway;
public int add(int num1, int num2) {
return num1 + num2;
}
public int sub(int num1) {
return num1 - remoteGateway.getSubtraction(num1);
}
public int mul(int num1, int num2) {
return num1 * num2;
}
public int div(int num1, int num2) {
return num1 / num2;
}
}5.2. Mock Test class
Our test class needs to make some corresponding changes , To create an instance of our tested class and the tested class Mock Class instance :
package service
import cn.techlog.testspring.testspring.service.Calculate
import cn.techlog.testspring.testspring.service.RemoteGateway
import spock.lang.Specification
import spock.lang.Unroll
class CalculateTest extends Specification {
RemoteGateway remoteGateway = Mock(RemoteGateway)
Calculate calculate = new Calculate(remoteGateway: remoteGateway)
}5.3. Write test methods
def "test sub"() {
when:
remoteGateway.getSubtraction(*_) >> subtraction
then:
calculate.sub(num1) >> result
where:
num1 << [1, 3, 4]
subtraction << [1, 2, 3]
result << [0, 1, 1]
}6. Public methods
JUnit It has a very convenient function , That is, you can define the methods to be called before and after the start of each test method , In order to do some public automatic processing functions ,spock It also provides the corresponding mechanism :
Method | explain |
|---|---|
setup() | Each method is called before execution. |
cleanup() | After each method is executed, it is called. |
setupSpec() | Each method class is called once before loading. |
cleanupSpec() | Every method class is called once after execution |
7. Reference material
http://spockframework.org/spock/docs/1.3/all\_in\_one.html. https://blog.csdn.net/u011719271/article/details/102888009.
边栏推荐
- How to view the index information of MySQL tables?
- TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
- 芯动联科冲刺科创板:年营收1.7亿 北方电子院与中城创投是股东
- Cloud native database: the outlet of the database, you can also take off
- Explain in detail the differences between opentsdb and tdengine in system functions
- Space calculation of information and innovation industry in 2022
- Teach you how to install Oracle 19C on Windows 10 (detailed picture and text with step on pit Guide)
- Gartner聚焦中国低代码发展 UniPro如何践行“差异化”
- MFS分布式文件系统
- Ansible environment installation and data recovery
猜你喜欢

工作流自动化 低代码是关键

Win10 LTSC 2021 wsappx CPU usage high

破解仓储难题?WMS仓储管理系统解决方案

TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
![[elt.zip] openharmony paper Club - witness file compression system erofs](/img/ad/5c3363b7536d495f153aa0130a10f1.png)
[elt.zip] openharmony paper Club - witness file compression system erofs

Hikvision tools manager Hikvision tools collection (including sadp, video capacity calculation and other tools) a practical tool for millions of security practitioners

SQL update批量更新

Don't worry. This is the truth about wages in all industries in China

Industry university cooperation cooperates to educate people, and Kirin software cooperates with Nankai University to complete the practical course of software testing and maintenance

实施MES管理系统前,要对哪些问题进行评估
随机推荐
CDGA|交通行业做好数字化转型的核心是什么?
在arcgis中以txt格式导出点的坐标
昱琛航空IPO被终止:曾拟募资5亿 郭峥为大股东
SQL update批量更新
如何实现IM即时通讯“消息”列表卡顿优化
Common errors and solutions of MySQL reading binlog logs
[cloud based co creation] the "solution" of Digital Travel construction in Colleges and Universities
ABAP随笔-EXCEL-3-批量导入(突破标准函数的9999行)
If the storage engine of time series database wants to be the best, it has to do its own research
VSCode 建议你启用 gopls,它到底是个什么东东?
Summary of domestic database certification test guide (updated on June 16, 2022)
Market status and development prospect forecast of global 3-Chloro-1,2-Propanediol industry in 2022
What is ICMP? What is the relationship between Ping and ICMP?
The difficulty of realizing time series database "far surpassing" general database in specific scenarios
破解仓储难题?WMS仓储管理系统解决方案
Market status and development prospect forecast of global 4-methyl-2-pentanone industry in 2022
Market status and development prospect forecast of global tetramethylammonium hydroxide developer industry in 2022
Solution to Maxwell error (MySQL 8.x connection)
基于STM32F103ZET6库函数蜂鸣器实验
MFS分布式文件系统