当前位置:网站首页>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.
边栏推荐
- 如何实现IM即时通讯“消息”列表卡顿优化
- Tdengine connector goes online Google Data Studio store
- Market status and development prospect forecast of global epoxy resin active toughener industry in 2022
- Comment encapsuler un appel à une bibliothèque
- Add in address of idea official website
- Market status and development prospect forecast of global 3-Chloro-1,2-Propanediol industry in 2022
- MongoDB和MySQL的区别
- Two methods of MySQL database login and logout
- 技术分享 | kubernetes pod 简介
- How to view the index information of MySQL tables?
猜你喜欢

Two methods of MySQL database login and logout

基于STM32F103ZET6库函数跑马灯实验

SQL update batch update
![[elt.zip] openharmony paper Club - witness file compression system erofs](/img/ad/5c3363b7536d495f153aa0130a10f1.png)
[elt.zip] openharmony paper Club - witness file compression system erofs

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?

一种朴素的消失点计算方法

The first in China! EMQ joined Amazon cloud technology's "startup acceleration - global partner network program"

Redis 原理 - String

Rxjs mergeMap 的使用场合

基于STM32F103ZET6库函数外部中断实验
随机推荐
Ansible environment installation and data recovery
Industry university cooperation cooperates to educate people, and Kirin software cooperates with Nankai University to complete the practical course of software testing and maintenance
别焦虑了,这才是中国各行业的工资真相
The incluxdb cluster function is no longer open source, and the tdengine cluster function is even better
International School of Digital Economics, South China Institute of technology 𞓜 unified Bert for few shot natural language understanding
Current market situation and development prospect forecast of the global ductless heating, ventilation and air conditioning system industry in 2022
Introduction to deep learning and neural networks
图扑数字孪生智慧能源一体化管控平台
Technology sharing | introduction to kubernetes pod
【ELT.ZIP】OpenHarmony啃论文俱乐部—数据密集型应用内存压缩
Market status and development prospect of 4-butyl resorcinol used in skin care industry in the world in 2022
openssl客户端编程:一个不起眼的函数导致的SSL会话失败问题
Application of tdengine in monitoring of CNC machine tools
Informatics Orsay all in one 1335: [example 2-4] connected block
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?
9.OpenFeign服务接口调用
Good news - British software 2022 has obtained 10 invention patents!
产学合作协同育人,麒麟软件携手南开大学合力完成《软件测试与维护》实践课程
Four years of College for an ordinary graduate
如何封装调用一个库