首页> 中国专利> Java单元测试用例生成方法及装置

Java单元测试用例生成方法及装置

摘要

本发明提供了一种Java单元测试用例生成方法及装置,可以应用于金融领域,方法包括:根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库;将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST;对未能匹配成功的业务AST生成测试代码;生成对应的测试AST,并将测试AST填充至测试AST库中;遍历业务AST库和测试AST库以检查是否满足测试覆盖率。本申请能够自动生成符合规范的单元测试用例,且达到代码行覆盖率、变更覆盖率等各项指标要求,而且本申请支持在已有测试代码的基础上进行迭代且不影响原有的测试用例。

著录项

  • 公开/公告号CN113010431A

    专利类型发明专利

  • 公开/公告日2021-06-22

    原文格式PDF

  • 申请/专利权人 中国工商银行股份有限公司;

    申请/专利号CN202110350716.4

  • 发明设计人 王鑫;冯程;嵇海锋;倪志华;

    申请日2021-03-31

  • 分类号G06F11/36(20060101);

  • 代理机构11127 北京三友知识产权代理有限公司;

  • 代理人任默闻;王涛

  • 地址 100140 北京市西城区复兴门内大街55号

  • 入库时间 2023-06-19 11:32:36

说明书

技术领域

本申请属于系统测试技术领域,具体地讲,涉及一种Java单元测试用例生成方法及装置。

背景技术

单元测试是UTDD方法中的重要组成部分。目前单元测试存在编写测试代码繁琐复杂的问题,开发人员往往不得不编写为业务代码量几倍的测试代码。而且,不少复杂项目的架构也很复杂,代码组织盘根交错,常用的mock工具使用困难,写好一个正确、功能完善且覆盖率达标的单元测试用例并不容易。

目前市面上的单元测试用例自动生成框架只支持生成简单的单元测试,无法兼容更多场景,也不支持项目级别复杂的场景。

发明内容

本申请提供了一种Java单元测试用例生成方法及装置,以至少解决目前单元测试中存在编写测试代码繁琐复杂的问题。

根据本申请的一个方面,本申请提供了一种Java单元测试用例生成方法,包括:

根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库;

将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST;

对未能匹配成功的业务AST生成测试代码;

根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中;

遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

在一实施例中,根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库,包括:

根据获取的业务源代码和对应的测试代码建立业务代码文件库和测试代码文件库;

将业务代码文件库和测试代码文件库中的源代码解析成AST结构,获得业务AST和测试AST;

根据业务AST和测试AST分别生成业务AST库及测试AST库。

在一实施例中,对未能匹配成功的业务AST生成测试代码,包括:

获取未能匹配成功的业务AST中的函数变量;

判断函数变量内部代码块的分支类型,并根据代码块的分支类型生成对应的测试代码。

在一实施例中,根据测试代码及测试代码的依赖情况生成对应的测试AST,包括:

如果测试代码没有依赖对象或依赖对象在预设的白名单中,生成基于Junit测试框架的测试AST;

如果测试代码有白名单之外的依赖对象,且使用了设定的方法,则生成基于PowerMock测试框架的测试AST;

如果测试代码有白名单之外的依赖对象,但只使用了非设定的方法,则生成基于Mockito测试框架的测试AST。

在一实施例中,遍历业务AST库和测试AST库以检查是否满足测试覆盖率,包括:

对业务AST库中的每一个业务AST进行遍历,判断是否在测试AST库中有对应的测试AST,获得测试行覆盖率;

判断业务AST中每个具有公共权限的函数变量中的每一个分支是否有对应的单元测试语句,获得分支覆盖率。

在一实施例中,Java单元测试用例生成方法,还包括:

获取测试AST库中新增或发生变更的测试AST;

通过JavaParser为新增或发生变更的测试AST反生成源代码文件;

将源代码文件填充到测试代码文件库中。

根据本申请的另一个方面,还提供了一种Java单元测试用例生成装置,包括:

AST库生成单元,用于根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库;

匹配单元,用于将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST;

测试代码生成单元,用于对未能匹配成功的业务AST生成测试代码;

测试AST生成单元,用于根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中;

覆盖率检查单元,用于遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

在一实施例中,AST库生成单元包括:

代码文件库建立模块,用于根据获取的业务源代码和对应的测试代码建立业务代码文件库和测试代码文件库;

AST结构解析模块,用于将业务代码文件库和测试代码文件库中的源代码解析成AST结构,获得业务AST和测试AST;

AST库生成模块,用于根据业务AST和测试AST分别生成业务AST库及测试AST库。

在一实施例中,测试代码生成单元包括:

获取模块,用于获取未能匹配成功的业务AST中的函数变量;

代码生成模块,用于判断函数变量内部代码块的分支类型,并根据代码块的分支类型生成对应的测试代码。

在一实施例中,测试AST生成单元包括:

第一生成模块,用于如果测试代码没有依赖对象或依赖对象在预设的白名单中,生成基于Junit测试框架的测试AST;

第二生成模块,用于如果测试代码有白名单之外的依赖对象,且使用了设定的方法,则生成基于PowerMock测试框架的测试AST;

第三生成模块,用于如果测试代码有白名单之外的依赖对象,但只使用了非设定的方法,则生成基于Mockito测试框架的测试AST。

在一实施例中,覆盖率检查单元包括:

测试行覆盖率获取模块,用于对业务AST库中的每一个业务AST进行遍历,判断是否在测试AST库中有对应的测试AST,获得测试行覆盖率;

分支覆盖率获取模块,用于判断业务AST中每个具有公共权限的函数变量中的每一个分支是否有对应的单元测试语句,获得分支覆盖率。

在一实施例中,Java单元测试用例生成装置,还包括:

变更获取单元,用于获取测试AST库中新增或发生变更的测试AST;

反生单元,用于通过JavaParser为新增或发生变更的测试AST反生成源代码文件;

填充单元,用于将源代码文件填充到测试代码文件库中。

本申请能够自动生成符合规范的单元测试用例,且达到代码行覆盖率,分支覆盖率,变更覆盖率等各项指标要求。而且框架支持在已有测试代码的基础上迭代更新而不影响原有测试用例,这样在业务代码更新时能自动完成对应测试代码的迭代更新,大大释放了开发人员的开发压力,提升工作效率。

附图说明

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本申请提供的一种Java单元测试用例生成方法流程图。

图2为本申请实施例中生成业务AST库及测试AST库的方法流程图。

图3为本申请实施例中对未能匹配成功的业务AST生成测试代码的方法流程图。

图4为本申请实施例中生成对应的测试AST的方法流程图。

图5为本申请实施例中检查是否满足测试覆盖率的方法流程图。

图6为本申请实施例中另一种Java单元测试用例生成方法的流程图。

图7为本申请提供的一种Java单元测试用例生成装置的结构框图。

图8为本申请实施例中AST库生成单元的结构框图。

图9为本申请实施例中测试代码生成单元的结构框图。

图10为本申请实施例中测试AST生成单元的结构框图。

图11为本申请实施例中覆盖率检查单元的结构框图。

图12为本申请实施例中另一Java单元测试用例生成装置的结构框图。

图13为本申请实施例中一种电子设备的具体实施方式。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

目前市面上的单元测试用例自动生成框架只支持生成简单的单元测试,无法兼容更多场景,不少复杂项目的架构也很复杂,代码组织盘根交错,也不支持例如mock项目等项目级别复杂的场景。

为了解决上述问题,本申请提供了一种Java单元测试用例生成方法,如图1所示,包括:

S101:根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库。AST(Abstract Syntax Tree,抽象语法树)

S102:将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST。

S103:对未能匹配成功的业务AST生成测试代码。

S104:根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中。

S105:遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

在一具体实施例中,扫描java项目下所有源代码文件(.java文件),根据项目结构推断出需要生成测试的业务源代码和对应的测试代码,然后根据业务源代码和对应的测试代码业务生成AST库和测试AST库,将业务AST库中的内容和测试AST库中的内容进行匹配,理论上每一个业务AST都至少有一个对应的测试AST,业界默认的方式“业务文件名+Test.java”=“测试文件名.java”来对应。如果有业务AST在测试AST库中没有被发现有对应的测试AST,则为其初始化一个对应的AST,为每个业务AST生成测试代码,然后验证测试指标如覆盖率等。

在一实施例中,根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库,如图2所示,包括:

S201:根据获取的业务源代码和对应的测试代码建立业务代码文件库和测试代码文件库。

S202:将业务代码文件库和测试代码文件库中的源代码解析成AST结构,获得业务AST和测试AST。

S203:根据业务AST和测试AST分别生成业务AST库及测试AST库。

在一具体实施例中,扫描java项目下所有源代码文件(.java文件),根据项目结构推断出需要生成测试的业务源代码和对应的测试代码,分别建立业务代码文件库(SourceFileRepo)和对应的测试代码文件仓库(TestFileRepo)。然后通过JAVA源代码解析工具JavasParser将SourceFileRepo和TestFileRepo里面的源代码解析成对应的AST,将源代码解析后的AST结构按业务代码和测试代码区分,分别建立业务AST库(SourceASTRepo)和测试AST库(TestASTRepo),作为下一步“生成测试代码”的数据来源。

在一实施例中,对未能匹配成功的业务AST生成测试代码,如图3所示,包括:

S301:获取未能匹配成功的业务AST中的函数变量。

S302:判断函数变量内部代码块的分支类型,并根据代码块的分支类型生成对应的测试代码。

在一具体实施例中,对SourceASTRepo中和TestASTRepo里面的进行匹配,理论上每一个业务AST都至少有一个对应的TestAST,业界默认的方式“业务文件名+Test.java”=“测试文件名.java”来对应。如果有SourceAST在TestASTRepo中没有发现对应的TestAST,则初始化一个对应的TestAST。

每一个正确的java源代码文件对应的AST包含至少一个类,接口或枚举类,其内部包含成员变量和函数变量,每个类中的具有公共权限(public)的函数变量就是需要生成测试代码的目标。每个函数变量内部有若干内部代码块,如果代码块具有分支类型(IF...ELSE),则需要针对不同的分支生成测试代码。

在一实施例中,根据测试代码及测试代码的依赖情况生成对应的测试AST,如图4所示,包括:

S401:如果测试代码没有依赖对象或依赖对象在预设的白名单中,生成基于Junit测试框架的测试AST。所述白名单为符合mock化条件但是无需mock化的依赖对象所述类或方法名单。

S402:如果测试代码有白名单之外的依赖对象,且使用了设定的方法,则生成基于PowerMock测试框架的测试AST。

S403:如果测试代码有白名单之外的依赖对象,但只使用了非设定的方法,则生成基于Mockito测试框架的测试AST。

在一具体实施例中,在测试代码中,被测试类往往需要涉及jdk自带类库,一方库(工程中其他模块的依赖),二方库(公司内部的依赖),第三方库(其他公司或开源软件的依赖)以及本模块内其他类的调用,则需要在测试代码中对根据不同依赖情况生成不同的TestAST。判断条件如下:

①如果没有依赖对象或依赖对象和方法都在白名单,则生成基于Junit测试框架的TestAST;

②如果有白名单外之外的依赖对象和方法,但只使用了依赖对象的普通方法,则生成基于Mockito测试框架的TestAST;

③如果有白名单之外的依赖对象和方法,且使用了private/static/final方法,则生成基于PowerMock测试框架的TestAST;

上面提到的白名单是指不需要mock,可以直接使用而不会影响单元测试正确性的依赖对象和方法集合,减少冗余代码量。例如jdk类库的自带日志输出,获得系统时间等方法。白名单通过框架的配置文件获得,开发人员可以根据项目业务的场景修改白名单列表。

一个完整的单元测试语句包括Given(如果涉及mock则包括mock打桩操作),When(调用被测试类的被测试方法),Then(验证执行结果是否和预期相同)。对TestASTRepo中每一个对应的SourceAST和TestAST进行对比,SourceAST类中的每个具有公共权限(public)的函数变量的每一个分支都需要有对应的单元测试语句,即满足测试行覆盖率,分支覆盖率指标。

针对以上条件,对初始化或现有的TestAST进行解析优化,例如根据依赖情况使用对应的测试框架,修改原有错误的单元测试语句,补充不满足行覆盖率和分支覆盖率要求的单元测试语句等。

在一实施例中,遍历业务AST库和测试AST库以检查是否满足测试覆盖率,如图5所示,包括:

S501:对业务AST库中的每一个业务AST进行遍历,判断是否在测试AST库中有对应的测试AST,获得测试行覆盖率。

S502:判断业务AST中每个具有公共权限的函数变量中的每一个分支是否有对应的单元测试语句,获得分支覆盖率。

在一具体实施例中,调用单元测试覆盖检查工具jacoco,对修改后的工程进行UTDD覆盖率检测,给出检测报告,验证测试指标(包括测试先行率,行覆盖率,分支覆盖率等)是否达标。

在一实施例中,Java单元测试用例生成方法,如图6所示,如图6所示,还包括:

S601:获取测试AST库中新增或发生变更的测试AST。

S602:通过JavaParser为新增或发生变更的测试AST反生成源代码文件。

S603:将源代码文件填充到测试代码文件库中。

在一具体实施例中,扫描生成完TestAST后的TestASTRepo,对新增或修改了的TestAST通过JavasParser反生成为源代码文件,填充到TestFileRepo中。

基于同一发明构思,本申请实施例还提供了一种Java单元测试用例生成装置,可以用于实现上述实施例中所描述的方法,如下面实施例所述。由于该Java单元测试用例生成装置解决问题的原理与Java单元测试用例生成方法相似,因此Java单元测试用例生成装置的实施可以参见Java单元测试用例生成方法的实施,重复之处不再赘述。以下所使用的,术语“单元”或者“模块”可以实现预定功能的软件和/或硬件的组合。尽管以下实施例所描述的系统较佳地以软件来实现,但是硬件,或者软件和硬件的组合的实现也是可能并被构想的。

根据本申请的另一个方面,还提供了一种Java单元测试用例生成装置,如图7所示,包括:

AST库生成单元701,用于根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库;

匹配单元702,用于将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST;

测试代码生成单元703,用于对未能匹配成功的业务AST生成测试代码;

测试AST生成单元704,用于根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中;

覆盖率检查单元705,用于遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

在一实施例中,如图8所示,AST库生成单元701包括:

代码文件库建立模块801,用于根据获取的业务源代码和对应的测试代码建立业务代码文件库和测试代码文件库;

AST结构解析模块802,用于将业务代码文件库和测试代码文件库中的源代码解析成AST结构,获得业务AST和测试AST;

AST库生成模块803,用于根据业务AST和测试AST分别生成业务AST库及测试AST库。

在一实施例中,如图9所示,测试代码生成单元703包括:

获取模块901,用于获取未能匹配成功的业务AST中的函数变量;

代码生成模块902,用于判断函数变量内部代码块的分支类型,并根据代码块的分支类型生成对应的测试代码。

在一实施例中,如图10所示,测试AST生成单元704包括:

第一生成模块1001,用于如果测试代码没有依赖对象或依赖对象在预设的白名单中,生成基于Junit测试框架的测试AST;

第二生成模块1002,用于如果测试代码有白名单之外的依赖对象,且使用了设定的方法,则生成基于PowerMock测试框架的测试AST;

第三生成模块1003,用于如果测试代码有白名单之外的依赖对象,但只使用了非设定的方法,则生成基于Mockito测试框架的测试AST。

在一实施例中,如图11所示,覆盖率检查单元705包括:

测试行覆盖率获取模块1101,用于对业务AST库中的每一个业务AST进行遍历,判断是否在测试AST库中有对应的测试AST,获得测试行覆盖率;

分支覆盖率获取模块1102,用于判断业务AST中每个具有公共权限的函数变量中的每一个分支是否有对应的单元测试语句,获得分支覆盖率。

在一实施例中,Java单元测试用例生成装置,如图12所示,还包括:

变更获取单元1201,用于获取测试AST库中新增或发生变更的测试AST;

反生单元1202,用于通过JavaParser为新增或发生变更的测试AST反生成源代码文件;

填充单元1203,用于将源代码文件填充到测试代码文件库中。

本申请提供的方法及装置能够自动生成符合规范的单元测试用例,且达到代码行覆盖率、变更覆盖率等各项指标要求,而且本申请提供的方法支持在已有测试代码的基础上进行迭代且不影响原有的测试用例。

本申请的实施例还提供能够实现上述实施例中的方法中全部步骤的一种电子设备的具体实施方式,参见图13,所述电子设备具体包括如下内容:

处理器(processor)1301、内存1302、通信接口(Communications Interface)1303、总线1304和非易失性存储器1305;

其中,所述处理器1301、内存1302、通信接口1303通过所述总线1304完成相互间的通信;

所述处理器1301用于调用所述内存1302和非易失性存储器1305中的计算机程序,所述处理器执行所述计算机程序时实现上述实施例中的方法中的全部步骤,例如,所述处理器执行所述计算机程序时实现下述步骤:

S101:根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库。

S102:将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST。

S103:对未能匹配成功的业务AST生成测试代码。

S104:根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中。

S105:遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

本申请的实施例还提供能够实现上述实施例中的方法中全部步骤的一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,该计算机程序被处理器执行时实现上述实施例中的方法的全部步骤,例如,所述处理器执行所述计算机程序时实现下述步骤:

S101:根据获取的业务源代码和对应的测试代码生成业务AST库及测试AST库。

S102:将业务AST库中的业务AST与测试AST库中的测试AST进行匹配,并筛选未能匹配成功的业务AST。

S103:对未能匹配成功的业务AST生成测试代码。

S104:根据测试代码及测试代码的依赖情况生成对应的测试AST,并将测试AST填充至测试AST库中。

S105:遍历业务AST库和测试AST库以检查是否满足测试覆盖率,测试覆盖率包括:测试行覆盖率和分支覆盖率。

本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于硬件+程序类实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。虽然本说明书实施例提供了如实施例或流程图所述的方法操作步骤,但基于常规或者无创造性的手段可以包括更多或者更少的操作步骤。实施例中列举的步骤顺序仅仅为众多步骤执行顺序中的一种方式,不代表唯一的执行顺序。在实际中的装置或终端产品执行时,可以按照实施例或者附图所示的方法顺序执行或者并行执行(例如并行处理器或者多线程处理的环境,甚至为分布式数据处理环境)。术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、产品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、产品或者设备所固有的要素。在没有更多限制的情况下,并不排除在包括所述要素的过程、方法、产品或者设备中还存在另外的相同或等同要素。为了描述的方便,描述以上装置时以功能分为各种模块分别描述。当然,在实施本说明书实施例时可以把各模块的功能在同一个或多个软件和/或硬件中实现,也可以将实现同一功能的模块由多个子模块或子单元的组合实现等。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。本领域技术人员应明白,本说明书的实施例可提供为方法、系统或计算机程序产品。因此,本说明书实施例可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本说明书实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于系统实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。在本说明书的描述中,参考术语“一个实施例”、“一些实施例”、“示例”、“具体示例”、或“一些示例”等的描述意指结合该实施例或示例描述的具体特征、结构、材料或者特点包含于本说明书实施例的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不必须针对的是相同的实施例或示例。此外,在不相互矛盾的情况下,本领域的技术人员可以将本说明书中描述的不同实施例或示例以及不同实施例或示例的特征进行结合和组合。以上所述仅为本说明书实施例的实施例而已,并不用于限制本说明书实施例。对于本领域技术人员来说,本说明书实施例可以有各种更改和变化。凡在本说明书实施例的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本说明书实施例的权利要求范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号