干货 | 质量保障新手段,携程回归测试平台实践

基于流量回放的自动化回归测试平台 AREX Agent 技术实现细节分享 在面对多线程和各种异步框架时,对数据的串联带来很大的挑战。很多业务系统的场景是对时间敏感的,不同的时间访问往往会返回不同的结果,如果录制和回放时间不一致就会导致接口回放失败,另外由于回放请求是并发的,修改测试机器的机器时间是不合适的,而且很多服务器也不能修改当前时间,因此我们需要在代码层面上实现当前时间的 Mock。现阶段 AREX Agent 采用的解决方案是每次只录制当前请求链路上用到的缓存数据,通过让应用配置动态类的方式去识别录制,测试环境回放时自动替换,保证录制和回放内存数据的一致性。 阅读详情

作者简介

 

Sedro,携程资深测试工程师,专注于测试技术探索及测试工具研发。

一、系统回归问题

回归测试是软件生命周期一个十分重要的环节,但项目在随着版本的逐步迭代,功能日益增多,系统愈加复杂,在测试过程中测试人员常常需要回归稳定版本的功能以保证不被待发布版本需求所影响。若要对系统进行全方位回归,这个测试的工作量将会非常庞大,而且可能几百上千用例中才会发现一个甚至是0个问题,测试投入产出不成比例。

而CPR则为上述问题提供了较好的解决方案。它通过基于稳定版本的输出,对待发布版本的输出进行比较,同时还将校验两个版本对下游请求的差异。根据比对结果评判待发布版本是否正确,可以大大降低回归的工作量。


二、CPR目标

  • 大量真实流量确保覆盖率

  • 将录制的流量作为用例管理起来进行自动化回归

  • 流量回放支持子调用自动化mock,避免回放产生脏数据

  • 流量回放支持子调用结果的验证

  •  减少人力资源

三、目标实现基本过程

1)首先将部署了稳定代码的服务器作为流量采集源。测试人员在进行功能、接口测试时,实现测试执行过程中主调用以及子调用的入参和返回值的录制。通过功能和接口测试实现对应用功能的全量覆盖,使得应用中请求流量都会被录制到。

2)将录制到的请求流量复制到console平台,由测试人员分析有效的流量归纳为用例。后续即可采用这些有效用例来对待发布版本进行回放和差异比对。

3)回放完成告知到测试人员,由测试人员对回放的差异结果进行确认,快速发现被测系统bug并解决。

 

四、CPR原理及实现


4.1.  CPR录制的数据抓取点

       

如上图所示,CPR采集的数据主要为两方面:待测应用接收到的客户端请求及响应;待测应用接收请求后向外部服务的子调用请求及响应。CPR目前支持的请求类型如上图橙色框中所示;但CPR本身设计时对各类请求采用插件式设计,使其具有较好的扩展性,对于后续其他需要捕获的类型能很好的进行支持。当前CPR系统支持的报文协议为JSON和PB(ProtoBuf)。


4.2.  CPR结构简介

CPR分为两大组件:

1)CPR (CtripPaymentRepeater) 组件,该组件基于开源的jvm-sandbox开发,用于录制和回放流量。此组件核心为两部分:

  • CPRRecord:目标是在稳定代码环境中录制请求调用的入参和返回值,并上送到存储服务。使得CPR Replay具备回放流量的数据。

  • CPRReplay:功能为接收回放服务提供的回放流量,在待测代码环境中进行回放,并将回放结果上送至对比服务,让其实现正常系统和待测系统返回结果比对差异的能力。

2)CPRConsole组件,该组件主要录制/回放的配置管理;数据存储/数据对比等具备多种能力。主要包含三部分:

  • 存储服务:对接收到的录制流量数据,将其持久化保存,待后续用户筛选有效流量。

  • 回放服务:功能为将录制流量进行还原,然后对入口调用做一次流量的发起,使得CPR Replay。

  • 对比服务:对接收到的回放数据与录制数据进行差异比对。

4.3 CPR处理流程

如上图所示,通过这两大组件的协同工作将稳定代码的流量自动捕获并持久化存储,然后由测试人员分析流量收藏为有效用例,对于后续待正式发布的代码,可以用有效用例来进行回放和差异比对,根据差异比对结果发现待测系统存在的问题。

该系统在处理比对时有两个与其他方案较大不同的特性:

1)对子调用MOCK处理:本方案采用的是记录下原始子调用内容及子调用返回内容;在系统内部完成对子调用返回的处理,不再需要实际的子系统或mock系统进行测试支撑。以此减小了环境、数据测试处理的难度和准确性。

2)子调用比对数据的处理:本方案采用的是比对子调用请求。例如一个DB操作,若请求内容是无误的,则认定请求正常;不再去比对具体的数据库存储值。这样的处理方式同样简化了测试环境搭建、测试数据准备,同时还解决了测试环境中数据共享变更可能带来的数据差异问题。


4.4 流量复制实现

在整个录制过程中,CPR进行录制的处理流程主要是在DefaultEventListener类中实现。

1)DefaultEventListener类

DefaultEventListener是用来处理触发事件的类。不同的插件 (soa,mysql,http,redis等) 可以自定义自己的EventListener来进行各自特殊的事件处理。目前插件默认使用DefaultEventListener。

在DefaultEventListener中,承接的是所有事件的处理,也就是说录制/回放操作都是集中在这个类中实现的,只是根据不同的条件来区分是录制流量还是回放流量,从而判断该执行录制还是该执行回放。

当事件第一次过滤时,会进行一次初始化跟踪器。

其中traceId实际上是这个跟踪器的独立标识。所以无论是录制和回放都会有其独立的traceId。

2)Before事件处理

对应的方法是DefaultEventListener.doBefore。

根据traceID判断当前流量是否为回放流量,若为回放流量则调用processor.doMock方法执行Mock,执行完成后直接返回,不再执行后续操作。

若当前流量为录制流量,则基于当前获取到的信息初始化Invocation实例,其中会调用插件中processor#assembleIdentity、processor#assembleRequest、processor#assembleResponse、processor#assembleThrowable四个方法,分别处理调用标识、请求参数、返回结果、抛出异常。最后将当前事件的Invocation信息存放到录制缓存中。

3)Return事件处理/ Throw事件处理

Return/ Throw事件的处理逻辑基本一致。

判断当前流量是否为回放流量,若为回放流量则直接返回,不执行后续操作。

若录制流量则从录制缓存中获取对应的Invocation实例,调用插件调用处理器的assembleResponse/assembleThrowable方法,并将reponst/throwable结果设置到Invocation实例中。

回调调用监听器InvocationListener#onInvocation方法,判断Invocation是入口调用还是子调用,如果是子调用则保存到录制缓存中,如果不是则调用消息投递器的broadcastRecord方法将录制记录序列化后上传给cpr-console。


4.5 流量回放实现

回放流程,是由测试人员选择有效用例,在待测系统中执行回放。

回放服务接受到回放记录,对记录进行反序列化,还原到原来录制的对象,保证classloader与录制时候一致。CPR在执行回放任务的过程中,首先会根据录制记录的信息,构造相同的请求,对被挂载的任务进行请求,并跟踪回放请求的处理流程,以便记录回放结果以及执行mock动作。整个回放过程比较复杂,主要包括以下几个个流程:

1)回放请求的处理

这里以http回放入口为例,RepeaterModule#repeat方法是回放请求最初处理入口。添加@Command注解,使得外部可以使用http协议方式调用入口。

该方法在接收外部的回放请求后,对请求参数进行校验,校验通过后会将参数实例化,形成一个回放事件RepeatEvent,发布到EventBusInner中被RepeatSubscribeSupporter#onSubscribe方法进行处理。

处理过程为首先会将RepeatEvent的参数进行反序列化,获取回放相关的录制记录的信息,然后通过这些信息从prepeater-console拉取对应的录制记录详情(RecordModel),最后用默认流量分发器DefaultFlowDispatcher进行分发。

 

2)回放任务的分发

回放任务的分发由DefaultFlowDispatcher#dispatch方法实现。

主要是针对回放任务的信息进行校验,校验失败会抛出错误到上层。通过校验的回放任务,则会初始化回放上下文信息,并存放到回放缓存中。根据回放任务的入口插件类型,获取对应插件的repeater进行回放处理。

 

3)回放结果执行与记录

回放任务执行、回放结果记录的实现逻辑在AbstractRepeater#repeat中实现。

通过executeRepeat方法交由各个插件的回放器实例来调用。当插件开始执行回放任务时,会根据回放上下文以及当前repeater的应用信息初始化回放结果记录RepeaterModel的实例。

初始化回放结果记录后,初始化回放线程跟踪并触发回放请求并获取回放请求返回的结果。

获取回放请求返回的结果后,停止线程跟踪,将回放结果以及当前的一些状态信息保存到回放结果记录的实例中。

最后通过调用消息投递器的AbstractBroadcaster#broadcastRepeat方法将回放结果记录序列化后上传到crp-console保存。

4)回放过程中的Mock处理

在回放过程中,直接在DefaultEventListner#Before事件处理中执行。

processor#doMock方法,交给插件调用处理器执行mock,并且只对子调用事件执行mock。

public void doMock(BeforeEvent event, Boolean entrance, InvokeType type) throws ProcessControlException {
    /*
     * 获取回放上下文
     */
    RepeatContext context = RepeatCache.getRepeatContext(Tracer.getTraceId());
    /*
     * mock执行条件
     */
    if (!skipMock(event, entrance, context) && context != null && context.getMeta().isMock()) {
        try {
            /*
             * 构建mock请求
             */
            final MockRequest request = MockRequest.builder()
                    .argumentArray(this.assembleRequest(event))
                    .event(event)
                    .identity(this.assembleIdentity(event))
                    .meta(context.getMeta())
                    .recordModel(context.getRecordModel())
                    .traceId(context.getTraceId())
                    .repeatId(context.getMeta().getRepeatId())
                    .index(SequenceGenerator.generate(context.getTraceId()))
                    .type(type)
                    .build();
            /*
             * 执行mock动作
             */


                final MockResponse mr = StrategyProvider.instance().provide(context.getMeta().getStrategyType()).execute(request);
                 /*
                 * 处理策略推荐结果
                 */
                switch (mr.action) {
                    case SKIP_IMMEDIATELY:
                        break;
                    case THROWS_IMMEDIATELY:
                        ProcessControlException.throwThrowsImmediately(mr.throwable);
                        break;
                    case RETURN_IMMEDIATELY:
                     //   if(!type.equals(InvokeType.MYSQL) &&! type.equals(InvokeType.MYBATIS)){
                            ProcessControlException.throwReturnImmediately(assembleMockResponse(event, mr.invocation));
                    //    }
                        break;
                    default:
                        ProcessControlException.throwThrowsImmediately(new RepeatException("invalid action"));
                        break;
                }


        } catch (ProcessControlException pce) {
            throw pce;
        } catch (Throwable throwable) {
            ProcessControlException.throwThrowsImmediately(new RepeatException("unexpected code snippet here.", throwable));
        }
    }
}

AbstractInvocationProcessor#doMock方法的实现,与AbstractRepeater#repeat相似,实际调用时是通过插件中各自的Processor的实例进行调用的。

当开始执行回放mock时,会先获取回放上下文的信息。根据回放上下文的信息,判断是否跳过mock的执行。当需要执行mock时,会根据回放上下文中的信息初始化MockRequest实例,通过mock策略计算获取MockResponse。

根据MockResponse返回状态进行不同的操作:

1)    当MockResponse执行结果是返回正常内容时,就会抛出一个终止当前调用操作并返回当前的返回结果,用ProcessControlException异常来阻挡需要mock的方法的实际调用。

2)    当MockResponse执行结果是返回一个异常时,就会抛出一个终止当前调用操作并抛出ProcessControlException异常,此时需要mock的方法不会被真实调用。

3)   只有当MockResponse返回状态是skip时,则不对这个调用事件做任何处理,调用会真实发生,其他任何状态都会通过抛出ProcessControlException异常来阻挡这个事件的实际调用。


4.6.  缺陷判定简析

1)对于读操作,我们主要关注在相同请求下正常系统和待测系统的返回结果的差异,读接口也提倡对所有对外请求进行mock,这样回放时能保持当时的一个现场环境,保证验证的准确性。

2)对于写操作,只验证接口返回结果是不够的,需要验证它具体写入的数据是否正确。例如创建支付订单会调用PPI的写订单PPI.Bill.CreatePaymentBill接口,那么我们需要验证回放时调用PPI的参数和录制时调用PPI的参数是否一致。

3)对比默认是全对象字段逐一对比。由于录制环境和回放环境所处环境不同,有一些必然不一致的信息,例如随机数、时间,以及系统ip等等,这些内容系统做了默认不比对处理。系统对于子调用是默认对比所有子调用,也可以通过平台配置排除一些不关心的子调用的对比。

4.7 数据安全保护

系统录制与回放过程中基于对通讯、数据的安全保护要求,系统实现了对公司神盾安全系统的接入,使得传输过程、落地数据及日志等涉及安全要求的数据内容都符合了信息安全要求。也确保了使用者不会接触到敏感数据等限制性内容。


五、小结

本文系统的介绍了CtripPaymentRepeater的目标以及实现原理以及流量复制、流量回放的技术方案,希望给因频繁进行回归测试而困扰的朋友一些帮助和借鉴。

在系统成熟的前提下,可以扩展本平台进行生产数据的采集比对。当这一步实现后,可以想见回归将真正不再是一件难事,尤其是生产回归需要面对的数据污染等问题都将不再是问题。同时该平台还可演化为MOCK平台,这样的MOCK将不再依赖任何系统,只需在待测应用的服务器上增加一个Agent即可完成。

 

 【推荐阅读】

 “携程技术”公众号

  分享,交流,成长

测试开发进阶:用Python重构质量保障体系 测试开发不是编写自动化脚本的技能叠加,而是以工程化思维重构软件质量保障体系的核心能力。其本质在于将零散测试活动升维为可度量、可治理、可持续演进的质量基础设施——依托Python强大的胶水能力与丰富生态(如pytest、playwright、locust),实现契约驱动的接口治理、分层解耦的自动化架构、以及CI/CD深度集成的质量门禁。该路径显著提升ROI,降低80%以上用例维护成本,并支撑测试左移、混沌工程、可观测性等高阶实践。本文聚焦测试工程师从执行者到质量架构师的关键跃迁,详解如何用Python构建具备 阅读详情

相关推荐

Web自动化实战:从Gulp到Selenium与云端测试的完整指南

Web自动化是现代软件开发中提升效率与保障质量的关键技术,其核心原理是通过脚本或工具模拟用户操作,自动执行浏览器任务。这项技术的价值在于实现测试与构建流程的一致性和可重复性,显著提升持续集成与部署(CI/CD)的可靠性。在实际应用场景中,Web自动化主要分为构建流程自动化(如使用Gulp进行代码检查与转换)和浏览器操作自动化(如利用Selenium进行端到端测试)。通过结合本地任务运行器与云端测试服务,开发者可以构建覆盖多浏览器、多设备的健壮测试体系。本文聚焦于Selenium、Gulp等热词工具,深入探讨

Liusuzhi19610221的博客 1275

干货 | 应用SQL性能风险识别与预警,携程金融支付AppTrace落地实践

作者简介Sedro,携程资深测试工程师,专注于测试技术探索及测试工具研发。一、应用性能问题在我们过往的测试及生产问题的分析中,常常可以发现应用执行数据库操作导致出现性能问题的情况。而这...

携程技术 902

【审计专栏】【法律领域】【社会科学】 第五十六篇 企业管理层互动形态分析01 AI分析

战略官试图塑造公司“战略现实”S_s(如“未来在于AI”),业务总裁固守“运营现实”S_o(如“现金为王”)。

weixin_49199313的博客 502

接口测试系列——AutoDiff流量回放在集成测试中的实践应用

1.1 迭代形态及组织变化迭代加快在当今的互联网行业的形态背景下,产品需求迭代都愈加地追求快速交付流动,大部分公司都采用精益产品研发流程。那么在汽车之家经销商bu内部,我们近2年的平均需求交付时间≈4天。而潜在的问题是,由于原自动化接口测试的开发/维护成本较高已追不上迭代,我们大部分的回归测试是被跳过的,更多要依赖开发人员水平+测试人员经验,所以一旦常规的节奏被打破(紧急需求插入、人员状态、人员变化等),回归缺失的问题就会暴露出来,而这种外来变化其实也越来越频繁。项目/人员变更随着公司内部布局的各种变化,也

2468

贝壳埋点质量全流程保障方案.pptx

性能apm监控方案设计,可借鉴,资料仅供学习参考~~~ 方案水平很高

sharingan:Sharingan(写轮眼)是一个基于golang的流量录制的跟踪工具,适合项目重构,回归测试等

Sharingan Sharingan,中文名称:写轮眼,是漫画《火影忍者》中的一种瞳术,具有复制,幻术等能力,在幻术世界里,一切因素包括时间,地点,质量等,都由施术者掌控。 一,简介 Sharingan是一个基于golang的流量录制的录制工具,录制的在线真实请求流量进行重新测试,适合项目分解,回归测试等。 1.1,背景 随着微服务架构的兴起,服务之间的依赖关系变的越来越复杂,软件测试也面临新的挑战:系统升级重复,服务依赖众多等等。 常见的测试方案。(如:单元测试,系统测试等)构造和维护测试用例成本高,特别是业务复杂的场景「构造测试数据难」 依赖第三方服务众多,线下测试环境不太稳定,经常出现下游服务不可用导致测试失败的情况发生。「维护测试环境成本高」 因此,我们需要开发一套工具来缓解上述问题。 1.2,方案 录制线上服务真实请求流量(包括下游调用流量),在线下进行追溯,解决构造测试

回归测试详解(定义&目的、策略以及什么叫做回归等)

1. 概述

catch_dreamer的博客 3万+

质量保障新手段,携程回归测试平台实践

本文系统的介绍了CtripPaymentRepeater的目标以及实现原理以及流量复制、流量回放的技术方案,希望给因频繁进行回归测试而困扰的朋友一些帮助和借鉴。回归测试是软件生命周期一个十分重要的环节,但项目在随着版本的逐步迭代,功能日益增多,系统愈加复杂,在测试过程中测试人员常常需要回归稳定版本的功能以保证不被待发布版本需求所影响。若要对系统进行全方位回归,这个测试的工作量将会非常庞大,而且可能几百上千用例中才会发现一个甚至是0个问题,测试投入产出不成比例。而CPR则为上述问题提供了较好的解决方案。它通过基于稳定版本的输出,对待发布版本的输出进行比较,同时还将校验两个版本对下游请求的差异。根

工作经验 | 产品回归测试的流程及注意事项

作为一名软件测试工程师,测试版本的N次构建必然少不了回归测试这一步骤,但根据最近的几场面试来看,很多初级工程师还停留在回归测试即是对已修复Bug的重复验证的认识上。今天我们就来分享下产品回归测试的流程及注意事项。

公众号【伤心的辣条】资料领取~ 1062

Avellaneda & Stoikov’s market-making strategy 工程化处理

前2篇文章详细介绍了AS存货模型的做市策略,这次对于这些公式里面一些希腊字母的取值是如何计算的,如何做工程化并应用到生产环境中做一些说明。这个里面有一些重要参数:很直观,可以直接取值的有:s = current market mid price (中间价,也就是【最佳卖价+最佳买价】/2)q = quantity of assets in inventory of base asset (也就是买入多少价值的股票数量)

weixin_42480337的博客 7068

SWIFT报文实战指南:从MT700到MT799的信用证操作全解析

本文深入解析了国际贸易中信用证操作的核心SWIFT报文流程,从开证的MT700到各类通知、修改及结算报文(如MT707、MT730、MT754、MT732/734等)。通过实战案例与关键字段拆解,指导外贸与银行从业者精准处理报文,规避风险,并探讨了利用自动化工具提升处理效率的方法,助力保障跨境交易顺畅。

weixin_29015801的博客 878

SaaS 业务自动化测试体系实践分享

本文将重点介绍保利威如何基于 “双螺旋模式” 构建高效的自动化测试体系,以及如何通过技术手段提升测试效率和覆盖率,最终取得了在回归提速、覆盖率提升和拦截 Bug 等方面的显著成果。本文将为业界提供可参考的 SaaS 自动化测试体系建设经验。

伤心的辣条 940

STM32 FATFS文件系统按行读取SD卡数据

STM32 SD数据实现按行读取

qq_32216815的博客 7824

走出回归测试困境,爱奇艺精准测试体系建设

8月7日下午,爱奇艺技术产品团队举办了第17期“i技术会”,本次技术会的主题是“智能化、精准化测试前沿探索”,本次沙龙与TesterHome社区联合举办。其中,来自爱奇艺的技术专家苏慧为大...

爱奇艺技术产品团队 876

VASP吸附计算1:CO在Pt(111)面的吸附|Materials Studio建模

介绍用VASP计算CO-Pt体系电荷密度的流程。

weixin_50519490的博客 5944

S32DS IDE调试技巧:如何用Attach功能高效定位汽车电子MCU的Bootloader问题

本文详细介绍了在汽车电子MCU开发中,如何利用S32DS IDE的Attach调试模式高效定位Bootloader与应用程序的协同问题。通过对比常规调试与Attach模式的本质差异,并深入讲解工程配置、镜像合并及实战调试流程,帮助开发者在不复位、不重新下载程序的前提下,实时分析系统状态,快速解决内存映射冲突、中断向量表重定向等疑难杂症。

weixin_29168393的博客 266

业务场景抽离,助力测试提效

本篇文章主要介绍在日常业务测试过程中,面对不同的业务场景时如何进行测试场景抽离和测试手段选择,从而达到保证项目质量、提高测试效率的目的。

zhuanzhuantech的博客 262

从‘最长白列’到‘八邻域’:智能车图像巡线算法怎么选?我的踩坑经验分享

本文深入探讨了全国大学生智能汽车竞赛中图像巡线算法的选型与优化,对比了最长白列法、八邻域算法等五种主流方法的性能与适用场景。通过实战数据和代码示例,分析了各算法在直道、弯道及特殊赛道元素中的表现,并提供了内存优化、参数调整等实用技巧,帮助参赛团队提升智能车的巡线精度与效率。

weixin_30374009的博客 632

测试Leader亲授:团队管理中最容易犯的5个错误

测试团队管理五大误区及改进方案:1.过度专注技术忽略沟通,建议建立定期会议与实时信息同步机制;2.忽视人员技能提升,应制定个性化发展计划并提供培训资源;3.流程责任不清晰,需文档化测试流程并明确分工;4.自动化与手动测试失衡,应根据需求合理分配资源;5.团队文化缺失,要培养开放包容氛围并关注成员心理健康。通过针对性改进可显著提升测试效率与质量。

2501_94261392的博客 887

最优控制 (Optimal Control) 算法详解及案例分析

最优控制是一种通过优化控制输入,使系统在满足约束条件的情况下达到最优性能的控制方法。其目标是最小化或最大化一个性能指标。

闲人编程的博客 2090

30、航空公司调度问题的数学模型解析

本文详细解析了航空公司调度问题中的核心数学模型,包括航班时刻表生成、机组人员排班和飞机调度的建模方法与求解技术。通过定义变量、约束条件及目标函数,结合线性规划、整数规划等方法,帮助航空公司实现高效调度。文章还探讨了模型的优化策略、简化方法以及实际应用案例,为提升航空运营效率提供了理论支持和实践指导。

beer8的博客 258

【杭州六小龙招聘】月薪最高50K*14薪,速来加入AI浪潮!

本科及以上学历,计算机相关教育背景。 三年以上的C++开发经验,熟悉实时操作系统。 熟悉常见设计模式、常见数据结构算法,了解设计原则和以太网、RS232/485、GPIO开发。

software_test010的博客 792

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

蘑菇街测试笔试题深度解析:测试思维与自动化实战指南

软件测试是保障产品质量的关键环节,其核心在于通过系统化的用例设计和分层策略,尽早发现缺陷以降低修复成本。随着自动化测试技术(如pytest、Appium)的普及,企业越来越看重测试人员的工程实践能力,接口测试、移动端专项测试等也逐渐成为岗位必备技能。在电商业务中,链路长、并发高、规则复杂的特点,使得测试思维和全链路排查能力尤为重要。本文基于蘑菇街2019年测试笔试真题,从测试金字塔、黑盒用例设计、冒烟与回归测试等基础考点出发,结合自动化框架选型、接口测试实战、App专项测试等热门方向,深度解析每道题背后的面

weixin_34344403的博客 385

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

五大开源移动端自动化测试工具深度横评与选型指南

移动端自动化测试是软件工程中保障应用质量、提升测试效率的关键技术。其核心原理是通过脚本模拟用户操作,对Android和iOS应用进行功能验证与回归测试,从而替代重复性手动劳动。在技术价值层面,它能实现快速反馈、提升测试覆盖率,并成为持续集成与交付(CI/CD)流程中的重要环节。应用场景广泛,从初创团队的快速验证到大型互联网企业的全机型覆盖夜间回归,都离不开合适的自动化工具。本文聚焦于跨平台(Android/iOS)这一核心挑战,深入剖析了Appium、Espresso/XCUITest、Detox、Maes

weixin_34226706的博客 468

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

回归测试怎么做

读者提问:回归测试怎么做 ?阿常回答:这个问题我分两点回答1、什么是回归测试2、怎么做回归测试一、什么是回归测试有些同学对于冒烟测试和回归测试拎不清,冒烟测试与回归测试是有区别的,下面阿常分别和大家说说两者的区别。冒烟测试,是新编译的版本在进行正式测试之前,进行预测试来确保软件的基本功能是正常的。回归测试,是正式测试过程中,对已修复的问题或软件环境发生改变后进行的测试,一般是验证已修复的问题及测试问题相关联模块。二、怎么做回归测试回归测试策略如下:1、全面回归测试--每一个大版本的发布,或者一次较大规模的调

weixin_44079378的博客 5793
上一篇: 沙龙回看 | 携程技术沙龙——前端测试技术创新与实践
下一篇: 《携程技术2020年度合辑》,送给爱学习的你
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值