当前位置:网站首页>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.
边栏推荐
- Vscode suggests that you enable gopls. What exactly is it?
- TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
- 通过 G1 GC Log 重新认识 G1 垃圾回收器
- 一位平凡毕业生的大学四年
- Don't worry. This is the truth about wages in all industries in China
- Cloud native database: the outlet of the database, you can also take off
- 云原生数据库:数据库的风口,你也可以起飞
- 可靠的分布式锁 RedLock 与 redisson 的实现
- Characteristics of time series data
- 工作流自动化 低代码是关键
猜你喜欢

DFS and BFS simple principle
![[webinar] mongodb and Google cloud accelerate enterprise digital innovation](/img/ea/4680381ce78fd5d956ed009692b424.png)
[webinar] mongodb and Google cloud accelerate enterprise digital innovation

新中大冲刺科创板:年营收2.84亿 拟募资5.57亿

PCB线路板蛇形布线要注意哪些问题?

binder hwbinder vndbinder

一种朴素的消失点计算方法
![[elt.zip] openharmony paper Club - memory compression for data intensive applications](/img/b3/ab915f0338174cba1a003edc262a5d.png)
[elt.zip] openharmony paper Club - memory compression for data intensive applications

国产数据库认证考试指南汇总(2022年6月16日更新)

Summary of domestic database certification test guide (updated on June 16, 2022)

Vscode suggests that you enable gopls. What exactly is it?
随机推荐
基于STM32F103ZET6库函数跑马灯实验
国信证券是国企吗?在国信证券开户资金安全吗?
工作流自动化 低代码是关键
Cucumber自动化测试框架使用
How to arrange digital collections on online platforms such as reading and Chinese online? Will "read/write-to-earn" products be launched in the future?
Campus book resource sharing platform
NVIDIA Clara-AGX-Developer-Kit installation
Summary of domestic database certification test guide (updated on June 16, 2022)
Hikvision tools manager Hikvision tools collection (including sadp, video capacity calculation and other tools) a practical tool for millions of security practitioners
TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
Comment encapsuler un appel à une bibliothèque
Jinyuan's high-end IPO was terminated: it was planned to raise 750million Rushan assets and Liyang industrial investment were shareholders
Don't worry. This is the truth about wages in all industries in China
Current market situation and development prospect forecast of global concrete shrinkage reducing agent industry in 2022
Recommend several open source IOT platforms
The difficulty of realizing time series database "far surpassing" general database in specific scenarios
Win10 LTSC 2021 wsappx CPU 占用高
使用logrotate对宝塔的网站日志进行自动切割
信息学奥赛一本通 1335:【例2-4】连通块
Row to column and column to row in MySQL