目前正在着手开发一款功能全面的接口自动化测试平台,该平台将涵盖登录、用户管理、权限控制、项目管理、用例管理、测试数据管理、测试报告生成、任务调度、缺陷跟踪以及系统配置等多个核心模块。为了高效执行测试任务或脚本,我们引入了RabbitMQ作为消息队列,实现测试任务的持久化与调度。
接口调用工具详解
技术选型
- 后端:采用Java作为主要开发语言。
- 前端:使用VUE框架进行界面展示。
任务执行功能设计
在执行测试任务或脚本时,利用RabbitMQ消息队列,实现了任务的异步处理与高效调度。具体实现流程如下:
任务发布:将待执行的测试任务ID或脚本ID封装为消息,发送至RabbitMQ消息队列。
持久化策略:设置RabbitMQ的数据持久化策略,确保任务消息在队列中的安全可靠存储。
任务消费:多个测试执行队列并行工作,作为RabbitMQ的消费端实时接收并处理任务消息。
rabbitMQ配置类
/**
* @author zhangkx
* rabbitmq配置类
*/
@Configuration
public class RabbitConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
/**
* Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输,
* Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
* Queue:消息的载体,每个消息都会被投到一个或多个队列。
* Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来.
* Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
* vhost:虚拟主机,一个broker里可以有多个vhost,用作不同用户的权限分离。
* Producer:消息生产者,就是投递消息的程序.
* Consumer:消息消费者,就是接受消息的程序.
* Channel:消息通道,在客户端的每个连接里,可建立多个channel.
*/
public static final String EXCHANGE_TESTTASK = "my-mq-exchange_TESTTASK";
public static final String QUEUE_TESTTASK = "QUEUE_TESTTASK";
public static final String ROUTINGKEY_TESTTASK = "spring-boot-routingKey_TESTTASK";
public static final String FANOUT_EXCHANGE = "api-test-fanout_exchange";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost("/");
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
@Bean
public DirectExchange defaultExchange() {
return new DirectExchange(EXCHANGE_TESTTASK);
}
@Bean
public Queue queueQUEUE_TESTTASK() {
// 队列持久
return new Queue(QUEUE_TESTTASK, true);
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queueQUEUE_TESTTASK()).to(defaultExchange()).with(RabbitConfig.ROUTINGKEY_TESTTASK);
}
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange(RabbitConfig.FANOUT_EXCHANGE);
}
}
生产者
/**
* @author zhangkx
* 消息生产者
*/
@Component
public class MsgProducer implements RabbitTemplate.ConfirmCallback {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final RabbitTemplate rabbitTemplate;
@Autowired
public MsgProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setConfirmCallback(this);
}
public void sendMsgTestTask(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_TESTTASK, RabbitConfig.ROUTINGKEY_TESTTASK, content, correlationId);
}
public void sendAll(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend(RabbitConfig.FANOUT_EXCHANGE,"", content,correlationId);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
logger.info(" 回调id:" + correlationData);
if (ack) {
logger.info("消息成功被发送到rabbitmq");
} else {
logger.info("消息发送到rabbitmq失败:" + cause);
}
}
}
消费者
/**
* @author zhangkx
* 消费者
*/
@Component
@RabbitListener(queues = RabbitConfig.QUEUE_TESTTASK)
public class MsgReceiverTestTask {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RabbitHandler
public void process(String content,Channel channel, Message message) {
logger.info("接收处理队列QUEUE_TESTTASK当中的消息: {}" , content);
TODO; // 任务处理逻辑代码......
try {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException e) {
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
e.printStackTrace();
}
}
}
通过上面的方法,实现了测试任务的持久化队列。可以帮助我们高效的处理测试任务。同时,针对大批量的任务,我们可以增加消费端来提高测试平台执行任务的能力。