文章自动采集插件(如何保证代码质量?测试验流程是怎样的?(一))
优采云 发布时间: 2022-04-07 06:23文章自动采集插件(如何保证代码质量?测试验流程是怎样的?(一))
博客:
沉淀、分享、成长,让自己和他人有所收获!
一、前言
如何保证代码质量?
业务需求、产品计划、研发实施、测试流程。四个角色的交互是确保需求生效的必要条件。研发和测试是整个需求交付质量等级划分中非常重要的一环。如果研发测试的代码质量不高,就会存在bug修复、返工甚至不同层次重做的风险。
那么,如何提高代码质量呢?一般我们会要求研发在开发代码的过程中编写单元测试来验证自己的代码逻辑。如果最终的单元测试覆盖率不足,研发测试可以被测试拒绝。
但是整个需求的实现代码是在全部开发完成之后进行测试的,也就是在launch附近的最后一个环节,大家都知道一个研发的某个功能域的实现是否具备测试条件. 如果此时代码质量不高,那么接下来就是项目风险的时候了。压力测试时间,上线时间的调整,总之,病拖,最后变成了大病!
当然,你可以在项目开发的过程中定期检查代码,或者每天反馈进度等。但是,开发和调查的方法,需要大量的时间,很难满足开发的需要。大型项目复杂,流程复杂,项目风险控制也难以预测。
因此,我们希望采集研究开发开发过程中的执行动作,以推进风险判断。实际操作的一个例子是,当你开发一个接口并开始测试时,我们的插件可以采集访问该接口的所有信息,包括:接口名称、输入参数类型和内容、输出参数类型和内容、异常信息、调用关系链等,然后将这些信息汇总提交给服务器,生成需要的代码分支下的所有接口动作,以及各个系统之间的关系链接,具有生成最新接口文档,随时一键测试验证。当测试人员在后期介入时,它们可以参考编码过程中开发的所有测试用例,还可以检查整个功能的覆盖率。此外,测试人员在测试过程中的数据也会被保留。现在有了这些数据信息,就可以生成一套完整的研发测试质量交付概览图,使整个工程开发交付质量评估透明化。
接下来,我们将根据上述描述性内容开发一个案例体验。我们走吧!
二、技术实现准备字节码插装,因为我们需要采集接口执行信息,那么我们需要使用字节码插装组件来增强接口方法。这种实现有点类似于 Google 的 Dapper,一种对*敏*感*词*分布式架构的非侵入式监控。只是我们需要来自 采集 的更多描述性信息。对于字节码检测,了解 ASM、Javassist、Byte-Buddy,所有这些都可以完成这项工作。IDEA插件开发,因为我们需要在研发人员的开发过程中进行采集,不要破坏研发的操作习惯。那么最好的办法就是嵌入到启动操作中,只要在开发过程中有运行代码的动作,对应的接口信息为采集。最后是数据的传输和处理。传输可以使用MQ,也可以直接使用Netty。处理数据的过程相对复杂。在这个过程中,需要对有价值的数据、相似的数据进行分析,合并某个执行环节的数据,生成相关的接口文档和工程服务图。三、检测字节码
我们在这里使用的字节码检测组件是 Byte-buddy,它是一个代码生成和操作库,用于在 Java 应用程序运行时创建和修改 Java 类,而无需编译器的帮助。除了 Java 类库中收录的代码生成实用程序之外,Byte Buddy 还允许创建任意类,并且不限于实现用于创建运行时代理的接口。此外,Byte Buddy 提供了一个方便的 API,可以使用 Java 代理或在构建过程中手动更改类。
1. 方法入口
public static void premain(String agentArgs, Instrumentation inst) {
AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {
return builder
.method(ElementMatchers.any()) // 拦截任意方法
.intercept(MethodDelegation.to(MonitorMethod.class));
};
new AgentBuilder
.Default()
.type(ElementMatchers.nameStartsWith(agentArgs))
.transform(transformer)
.installOn(inst);
}
如果您接触过 Javaagent 开发,您就会熟悉 premain。如果不清楚,可以理解为程序启动时的方法入口,可以从这个入口中截取自己需要的方法,然后对其进行字节码增强。其实就是动态写代码,把你的代码加到方法中,采集方法信息。
2. 采集信息
<p>@RuntimeType
public static Object intercept(@Origin Method method, @SuperCall Callable callable, @AllArguments Object[] args) throws Exception {
long start = System.currentTimeMillis();
Object resObj = null;
try {
resObj = callable.call();
return resObj;
} finally {
System.out.println("方法名称:" + method.getName());
System.out.println("入参个数:" + method.getParameterCount());
for (int i = 0; i