此博客用于个人学习,来源于网上,对知识点进行一个整理。
1. 前期准备:
在进行测试前,需要对 SpringCloud 的核心组件之一——Hystrix Dashboard 有个了解。
1.1 Hystrix Dashboard 是什么:
Hystrix 提供了对于微服务调用状态的监控信息,但是需要结合 spring-boot-actuator 模块一起使用。
Hystrix Dashboard 主要用来实时监控 Hystrix 的各项指标信息。通过 Hystrix Dashboard 反馈的实时信息,可以帮助我们快速发现系统中存在的问题,正是由于该组件的这些优点,我们可以利用其进行本系统的可用性测试。
更多有关于 Hystrix 的内容可以参考我之前的一篇关于介绍 SpringCloud 核心组件的博客,里面有更多更详细的内容:SpringCloud 核心组件(二)
1.2 改造系统:
在 imooc-ad-service 下,创建 module:ad-dashborad。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>imooc-ad-service</artifactId>
<groupId>com.imooc.ad</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ad-dashboard</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!-- 引入服务容错 Hystrix 的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- Hystrix 监控 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- 监控端点, 采集应用指标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--
Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!--
SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类:
@EnableEurekaClient
@SpringBootApplication
@EnableHystrixDashboard
public class DashboardApplication {
public static void main(String[] args) {
SpringApplication.run(DashboardApplication.class,args);
}
}
application.yml:
server:
port: 7002
spring:
application:
name: ad-dashboard
eureka:
client:
service-url:
defaultZone: http://server1:8000/eureka/
management:
endpoints:
web:
exposure:
include: "*"
1.3 数据库准备:
目前我们的数据库中还没有数据,无法进行测试,于是我们先往其中插入一些数据:
--
-- init data for table `ad_user`
--
INSERT INTO `ad_user` VALUES (15,'qinyi','B2E56F2420D73FEC125D2D51641C5713',1,'2018-11-19 20:29:01','2018-11-19 20:29:01');
--
-- init data for table `ad_creative`
--
INSERT INTO `ad_creative` VALUES (10,'第一个创意',1,1,720,1080,1024,0,1,15,'https://www.imooc.com','2018-11-19 21:31:31','2018-11-19 21:31:31');
--
-- init data for table `ad_plan`
--
INSERT INTO `ad_plan` VALUES (10,15,'推广计划名称',1,'2018-11-28 00:00:00','2019-11-20 00:00:00','2018-11-19 20:42:27','2018-11-19 20:57:12');
--
-- init data for table `ad_unit`
--
INSERT INTO `ad_unit` VALUES (10,10,'第一个推广单元',1,1,10000000,'2018-11-20 11:43:26','2018-11-20 11:43:26'),(12,10,'第二个推广单元',1,1,15000000,'2018-01-01 00:00:00','2018-01-01 00:00:00');
--
-- init data for table `ad_unit_district`
--
INSERT INTO `ad_unit_district` VALUES (10,10,'安徽省','淮北市'),(11,10,'安徽省','宿州市'),(12,10,'安徽省','合肥市'),(14,10,'辽宁省','大连市');
--
-- init data for table `ad_unit_it`
--
INSERT INTO `ad_unit_it` VALUES (10,10,'台球'),(11,10,'游泳'),(12,10,'乒乓球');
--
-- init data for table `ad_unit_keyword`
--
INSERT INTO `ad_unit_keyword` VALUES (10,10,'宝马'),(11,10,'奥迪'),(12,10,'大众');
--
-- init data for table `creative_unit`
--
INSERT INTO `creative_unit` VALUES (10,10,10);
2. 测试:
准备工作完成后,可以进行各系统的测试。
2.1 广告投放系统的测试:
测试主要是测试项目的 Service 层,因为 Service 层就是我们的功能逻辑,而 Controller 层也是调用 Service 的方法。
在 ad-sponsor 的 test 中编写方法进行测试,由于我们只是作为测试使用,于是在配置文件中取消 eureka 的扫描。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class},webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class AdPlanServiceTest {
@Autowired
private IAdPlanService planService;
public void testGetAdPlan() throws AdException{
System.out.println(
planService.getAdPlanByIds(
new AdPlanGetRequest(15L, Collections.singletonList(10L))
)
);
}
}
2.2 广告检索系统的测试:
在 ad-search 的 test 中,同样需要定义启动类和配置文件。
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
application.yml:注意配置将注册 eureka 设为 false,防止出错
server:
port: 7001
servlet:
context-path: /ad-search
spring:
application:
name: eureka-client-ad-search
jpa:
show-sql: true
hibernate:
ddl-auto: none
properties:
hibernate.format_sql: true
open-in-view: false
datasource:
url: jdbc:mysql://127.0.0.1:3306/imooc_ad_data?autoReconnect=true
username: root
password: root
tomcat:
max-active: 4
min-idle: 2
initial-size: 2
eureka:
client:
service-url:
defaultZone: http://server1:8000/eureka/
enabled: false
feign:
hystrix:
enabled: true
management:
endpoints:
web:
exposure:
include: "*"
adconf:
mysql:
host: 127.0.0.1
port: 3306
username: root
password: root
binlogName: ""
position: -1
kafka:
topic: ad-search-mysql-data
由于我们的匹配信息存在多种,我们在测试的时候也需要注意这一点。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SearchTest {
@Autowired
private ISearch search;
@Test
public void testFetchAds() {
SearchRequest request = new SearchRequest();
request.setMediaId("imooc-ad");
// 第一个测试条件
request.setRequestInfo(new SearchRequest.RequestInfo("aaa", Collections.singletonList(new AdSlot(
"ad-x", 1,
1080, 720, Arrays.asList(1, 2),
1000
)),
buildExampleApp(),
buildExampleGeo(),
buildExampleDevice()
));
request.setFeatureInfo(buildExampleFeatureInfo(
Arrays.asList("宝马", "大众"),
Collections.singletonList(
new DistrictFeature.ProvinceAndCity(
"安徽省", "合肥市")),
Arrays.asList("台球", "游泳"),
FeatureRelation.OR
));
System.out.println(JSON.toJSONString(request));
System.out.println(JSON.toJSONString(search.fetchAds(request)));
// 第二个测试条件
request.setRequestInfo(new SearchRequest.RequestInfo(
"aaa",
Collections.singletonList(new AdSlot(
"ad-y", 1,
1080, 720, Arrays.asList(1, 2),
1000
)),
buildExampleApp(),
buildExampleGeo(),
buildExampleDevice()
));
request.setFeatureInfo(buildExampleFeatureInfo(
Arrays.asList("宝马", "大众", "标志"),
Collections.singletonList(
new DistrictFeature.ProvinceAndCity(
"安徽省", "合肥市")),
Arrays.asList("台球", "游泳"),
FeatureRelation.AND
));
System.out.println(JSON.toJSONString(request));
System.out.println(JSON.toJSONString(search.fetchAds(request)));
}
private App buildExampleApp() {
return new App("imooc", "imooc",
"com.imooc", "video");
}
private Geo buildExampleGeo() {
return new Geo((float) 100.28, (float) 88.61,
"北京市", "北京市");
}
private Device buildExampleDevice() {
return new Device(
"iphone",
"0xxxxx",
"127.0.0.1",
"x",
"1080 720",
"1080 720",
"123456789"
);
}
private SearchRequest.FeatureInfo buildExampleFeatureInfo(
List<String> keywords,
List<DistrictFeature.ProvinceAndCity> provinceAndCities,
List<String> its,
FeatureRelation relation
) {
return new SearchRequest.FeatureInfo(
new KeywordFeature(keywords),
new DistrictFeature(provinceAndCities),
new ItFeature(its),
relation
);
}
}