前言
最近公司开始有后端的项目,必不可免的需要针对这些后端 API 进行测试。随着测试技术的突飞猛进,越来越多的人喜欢造轮子。面对如此多的框架该如何选型呢。
框架选型
在众多的框架里面,耳熟能详的,postman,RF, JMeter,rest-assured,HTTPrunner....
对于框架的选型,个人的观点,怎么简单怎么来吧。
框架是否能较好的支持
框架维护成本
团队成员学习成本
我的方案 Junit + Rest-Assured, 原因如下:
*后端项目采用 Gradle,Rest-Assured 可以快速度集成,在后续的 CI 中较友好,统一的仓库,编译执行命令。
*团队采用 Juint 做 UT/IT,学习成本较低。
*现有的 mock server client,可以使用 Gradle 集成
*Rest-Assured 对 restful 的支持友好,提供良好的断言,given-when-then 与现有的 AC 方式相似,可接受度高
开始框架集成
build.gradle 添加依赖, 在这里需要注意的是版本间的兼容
dependencies {
testImplementation('junit:junit:4.13')
//rest-assured
testCompile group: 'io.rest-assured', name: 'rest-assured', version: '4.1.2'
testCompile group: 'io.rest-assured', name: 'rest-assured-all', version: '4.1.2'
testCompile group: 'io.rest-assured', name: 'spring-mock-mvc', version: '4.1.2'
testImplementation 'io.rest-assured:json-path:4.1.2'
testImplementation 'io.rest-assured:json-schema-validator:4.1.2'
testImplementation 'io.rest-assured:xml-path:4.1.2'
//Log4J:
testImplementation group: 'log4j', name: 'log4j', version: '1.2.17'
//Gson:
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
//Inject
compile group: 'com.google.inject', name: 'guice', version: '4.2.3'
//mockingbird-client
compile group: 'mockingbird', name: 'mockingbird-client', version: '3.1-SNAPSHOT'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
api group: 'com.ringcentral', name: 'ringcentral', version: '0.6.4'
}
复制代码
使用 Guice 作为依赖注入在 junit 中使用
GuiceJUnit4Runner.java
package com.ringcentral.ltibackend;
import com.google.inject.Guice;
import com.google.inject.Module;
import com.google.inject.internal.ProviderMethodsModule;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public class GuiceJUnit4Runner extends BlockJUnit4ClassRunner {
public GuiceJUnit4Runner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
public Object createTest() throws Exception {
Object object = super.createTest();
Module module = ProviderMethodsModule.forObject(object);
Guice.createInjector(module).injectMembers(object);
return object;
}
}
复制代码
在测试中声明
*Test.java
@RunWith(GuiceJUnit4Runner.class)
public class VideoConfigTest {
//todo
}
复制代码
整体的框架结果如下:
image.png
上手写 case
1.使用 mock 让内部的第三方 api 返回期望的结果,通过 before,after 在测试前 mock,结束后清理掉 mock 的 api。
package com.*.*.core.api;
import com.google.inject.Inject;
import com.*.*.GuiceJUnit4Runner;
import com.*.*.util.config.ApiConfig;
import com.*.*.util.config.EnvConfig;
import com.*.*.util.mock.services.MockRCServer;
import io.restassured.RestAssured;
import org.apache.http.HttpStatus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.lessThan;
@RunWith(GuiceJUnit4Runner.class)
public class VideoConfigTest {
private static final Long TIME_OUT = 5000L;
@Inject
private MockRCServer mockRCServer;
@Before
public void setUp() {
mockRCServer.mockSucessRCToken();
mockRCServer.mockVideoConfigurationReturnRCVideo();
}
@After
public void teardown() {
mockRCServer.getMockServer().deleteMockFor();
}
@Test
public void videoConfigTestShouldBeCorrect() {
RestAssured.useRelaxedHTTPSValidation();
RestAssured.given().header("x-api-key", ApiConfig.API_HEADER).
when().
get(EnvConfig.LTI_SERVER_URL + ApiConfig.API_VIDEO_CONFIG).
then().
assertThat().
statusCode(HttpStatus.SC_OK).
and().assertThat().body(containsString("RCVideo")).
and().time(lessThan(TIME_OUT));
}
}
复制代码
2.更好的断言 jsonschema,可以通过https://extendsclass.com/json-schema-validator.html生成 json 文件。将 json 文件放置在 resource 文件中。更多方法查看官网
https://rest-assured.io/
public class UserInfoTest {
private static final Long TIME_OUT = 5000L;
@Test
public void userInfoTestShouldBeCorrect() {
RestAssured.useRelaxedHTTPSValidation();
RestAssured.given().header("x-api-key", ApiConfig.API_HEADER).
when().
get(EnvConfig.LTI_SERVER_URL + ApiConfig.API_USER_INFO).
then().
assertThat().
statusCode(HttpStatus.SC_OK).
and().time(lessThan(TIME_OUT)).
and().assertThat().body(matchesJsonSchemaInClasspath("userInfo.json")).
and().assertThat().body(containsString("\"brand\":\"rc\",\"extensionId\":\"2172406004\",\"meetingProvider\":\"RCVideo\""));
}
}
复制代码
更多问题欢迎探讨~
评论