让你的自动化代码更健壮

在做自动化测试时,尤其是UI级自动化,如何让你的代码更健壮可能是你经常要考虑的问题,这里分享几个小Tips。

多用WaitForXXXX

严格意义上讲,任何长时间的“硬等待”都是可取的!!到处随意的Sleep()只能显示你技能的匮乏,写出的Case也会效率低下。所以当此之时, 我们都应该多用WaitFor方法,而且任何的自动化框架都是有类似方法的,像Robotium的:

solo.waitForDialogToClose() //waits for the dialog to close
solo.waitForActivity() // if there is a activity change
solo.waitForText() //if a certain text appears after the loading is done
solo.waitForView() //if a certain view is shown after the load screen is done.

Ranorex也有很多这样的的功能来帮你等待特定元素出现.

但是如果从框架里找不到类似的方法来满足实际测试的场景,怎么办? OK, 那我们就只能自己来实现了.

实现自己的WaitFor方法

其实仔细想想,这样的方法归根到底还是需要sleep动作的,毕竟是要等待,只不过我们要做的是让它要更聪明的去等待. 比如下面:

/**
     * Wait for the view with id to be shown in the timeout
     *
     * @param id the id of the view
     * @param timeout the amount of time in milliseconds to wait
     * @return true that the view is shown, false otherwise
     */
    public <T extends View> boolean waitForViewShown(final int id, final int timeout){
        final long endTime = SystemClock.uptimeMillis() + timeout;
        boolean foundMatchingView = false;
        View view;

        while (SystemClock.uptimeMillis() < endTime) {
            solo.sleep(Global.SLEEP_FLASH_TIME);

            view = solo.getView(id);
            if (view != null)
                foundMatchingView = view.isShown();

            if (foundMatchingView)
                return true;
        }
        return false;
    }

我们可以设置个Timeout时间,这样在时间范围内,只要找到目标,就立马返回,如果没找到,那么再进行下一轮循环. 这样当要操作的对象确实出来之后,在进行下一步操作, 出错的可能就会少很多.

另外,出错少可不代表不出错,也许就会有一些莫名其妙的情况让你的代码执行失败. 虽然努力分析错误,找出最终导致Case失败的Root Cause, 毋庸置疑是非常重要的。但也许考虑到付出与得到的性价比,也许一个简单的失败再重试,会对你更有用。

若失败再重试机制,让你的代码更健壮

这里提到的失败重试机制不是指让整条Case的重新去执行一遍,而是当你发现某个一或几个动作,有可能因为一些特殊的场景导致失败的话,而这种特殊场景又不可控的话,那么我们就可以使用简单的几行代码,让风险更可控。比如下面这些方法:

        /// <summary>
        /// Open the bottom app bar
        /// </summary>
        public static void OpenBottomAppBar()
        {
            Report.Info("Running in OpenBottomAppBar method.");

            System.DateTime endtime = System.DateTime.Now.AddSeconds(30);
            while(System.DateTime.Compare(System.DateTime.Now, endtime) <= 0)
            {
                //Move cursor to center of HP Connected Drive view and right click to open filter menu
                Size point = repo.HPConnectedDriveView.Self.Element.Size;
                Mouse.MoveTo(point.Width/2 < 400?400:point.Width/2, 10);
                Delay.Seconds(1);
                Mouse.Click(System.Windows.Forms.MouseButtons.Right);

                if(Utility.FindElement(repo.HPConnectedDriveView.BottomAppBar.BottomAppBarInfo, 1000 * 2))
                {
                    return;
                }
            }
            Report.Screenshot();
        }
        

同样是利用前面提到的WaitFor机制,使用场景却更广泛,这里会循环判断,到底这个BottomAppBar出来没,要是没有的话,我就再点以下,并且在30秒之内,直至它打开为止。

要注意的是,这里是用时间也就是Timeout来控制重试范围,不过它适用单步或者有限几步操作的容错控制,如果是大的模块(Module),或者整条Case的,也许直接用重试次数会更好,毕竟当上升到大的模块,我们的首要目标还是让Case能执行过去而不是考虑时间范围。

用重试次数来控制大的模块或整条Case的执行

比如下面:

        /// <summary>
        /// Create a snapfish account via snapfish website
        /// http://www.snapfish.com/snapfish/home
        /// http://us1.sfint1.qa.snapfish.com/snapfish/home
        /// </summary>
        /// <param name="stack"></param>
        /// <returns></returns>
        public static string CreateSFAccount(string stack)
        {
            int i =0;
            string result = null;
            while(i<2)
            {
                i++;
                OpenSnapfishSignUpPage(stack);
                Delay.Seconds(4);
                ClickSignUPLink();
                Delay.Seconds(1);
                string emailPrefix = "asgqa.hpcd.SF";
                string emailPassword = "asg111111";
                string suffix = Utility.GetUniqueNumber();
                string email = emailPrefix + suffix + Utility.MapStack(stack) +"@hp.com";

                email = InputSFRegisteredAccountInformation(email, emailPassword, emailPassword);
                ClickSFSubmitButton();
                result =  email + "|" + emailPassword;
                if(Utility.FindElement(repo.Snapfish.SignOutInfo, 1000*60))
                {
                    Validate.IsTrue(true, "Register Snapfish account successfully email=" + email + " password=" + emailPassword);
                    return result;
                }
                else
                {
                    Report.Warn("Failed to get the successful infor after registering the SF account, take screenshot for reference");
                    Report.Screenshot();

                    Report.Info("Click F5 to refresh the page");
                    repo.Snapfish.Self.PressKeys("{F5}");
                    if(Utility.FindElement(repo.Snapfish.SignOutInfo, 1000*30))
                    {
                        Validate.IsTrue(true, "Register Snapfish account successfully email=" + email + " password=" + emailPassword);
                        return result;
                    }
                }
            }

            Report.Warn("still Unable to create snapfish account after try twice, take screenshot for reference");
            Report.Screenshot();

            Report.Warn("Sometimes i found even we registerd successfully, Snapfish website page still didn‘t refreshed, so i will use the registered account to login HPCD to try it again");
            return result;
        }

这是例子目的就是要去一个网站,创建帐号,我的目的就是只要能创建好帐号就行,并不是测这个网站,所以这里的操作如果失败了,我就会重试,直至三次机会用完,那我相信即使在重试多次,效果也是一样的,所以还是直接返回吧。

总结

构建健壮的测试代码,是我们测试人员的目标,就像开发需要不断的重构代码,以让代码更简洁优雅,其性质是完全一样的。这里只是我常使用的几个小Tips,抛砖引玉, 若各位看官有啥意见和建议,望不吝赐教。

如果您看了本篇博客,觉得对您有所收获,请点击下面的 [推荐]

如果您想转载本博客,请注明出处

如果您对本文有意见或者建议,欢迎留言

时间: 2024-10-24 13:09:50

让你的自动化代码更健壮的相关文章

基于AOP的MVC拦截异常让代码更优美

与asp.net 打交道很多年,如今天微软的优秀框架越来越多,其中微软在基于mvc的思想架构,也推出了自己的一套asp.net mvc 框架,如果你亲身体验过它,会情不自禁的说‘漂亮’.回过头来,‘漂亮’终归有个好的思想,其中类似于AOP的思想,就在其中体现的淋漓尽致,今天本文主要讨论的是基于AOP思想构成的‘异常过滤器’.我们的目的只有一个,让try...catch...无处盾形,让代码更健壮优美. 一.理解mvc里filter是怎么运行的 老外的一篇文章是这样的草图 通过翻译中文是这样的 其

静态分析——自动化代码扫描如何预防缺陷和加速交付?

一.什么是静态代码分析? 静态代码分析(简称静态分析)是一种必要的开发测试行为,通过扫描代码模式和结构以及分析逻辑关系,查找潜在缺陷代码,最终将报告呈现给用户以便修复代码缺陷.当高风险代码被侦测到后,静态分析扫描工具就会报告相应违规,指引用户修复代码漏洞.静态分析方法一般有如下一些类型: 模式匹配静态分析 模式匹配静态分析方法是静态分析的一种最简单形式,即根据预先配置的规则库去自动化进行代码扫描,如果发现规则库中匹配的模式代码即报告违规.例如,工程师们有时候不小心使用了字符串""进行字

艾伦 Visual Studio 批量自动化代码操作工具-VS插件发布

艾伦 Visual Studio 批量自动化代码操作工具 以下简称--艾伦工具箱. 艾伦工具箱是一个多文件批量处理插件,目的是为了广大开发者提高开发效率,减少项目代码规范化审计,缩短开发者的项目开发周期. 名称:艾伦 Visual Studio 批量自动化代码操作工具. 亮点:批量操作. 功能:1,代码格式化:2,移除与重排Using. 可选:1,针对整个解决方案进行自动化操作:2,针对选中的当前项目进行自动化操作:3,针对指定的后缀名代码文件进行操作: 注意事项:默认支持*.cs.*.vb,可

推荐一款华为最新的自动化代码检查工具

作为一枚软件攻城狮,你是不是总觉得自己撸代码的能力还有待提高却又无从下手?你是不是看到过XX大神美轮美奂的代码,然后佩服的五(ren)体(yang)投(ma)地(fan),然后躲在暗房里哭.然后你下定决心要痛改前非,然后发现无处下手,然后--又回到了以前的不归路? 如果你没有以上症状,请你关上浏览器,悄悄离开,千万别回头! 如果你有以上症状,但觉得自己已经病入膏肓,无法医治,让我拍拍你的肩,对你说"下辈子重新来过吧!". 如果你觉得自己还有救,就留下来继续观看,我给你开导开导. 要想修

使用docker实现半自动化代码自动部署与回滚

最近开发docker的caas平台,目前已经开发完成,在优化性能与套模板.对于docker最近是很好,很多人把docker做为vm来使用,当然作为测试来说是没问题,但我感觉docker本身在做沙箱.自动化部署与回滚方面更适合,下面介绍一下我这里是如何通过docker实现代码半自动化部署. 目前我这里已经实现能结合svn或者git代码库,对node.php.java代码进行半自动化部署,先给大家截图看效果,感觉满意在继续细看. 总界面如下 点击左上角的"新增开放项目"就可以新建立测试,下

怎么让你的代码更Pythonic?光有技巧可不行,你还需要看这些

写代码如同写文章,好的文章是反复修改出来的,代码也同样是反复的重构出来的.今天给大家分享下,怎么从一个编程学习者变为一个程序猿(程序媛)!起码不要让别人一看你的代码就知道你是个小菜鸟! 我们通常写一个代码,必然会经过一个简单-难-简洁的过程,那么在重构的过程中需要注意哪些呢? 1. 代码可以正常运行 首先必然要保证,代码可以正常运行! 不论你是直接按逻辑写下来还是函数式编程,必须先能实现你的代码功能,可以正常运行起来 2. 精简代码,提高可读性 当你的代码可以运行起来以后,接着就要重新读一遍代码

uiautomatorviewer 优化定位符生成,支持生成Java,Python自动化代码

项目介绍 二次开发 uiautomatorviewer 优化定位符生成,支持生成Java,Python自动化代码,修复自带工具画面有动态加载时截图失败问题,优化自带工具截图速度 ,实现类似录制脚本功能.兼容IOS安卓. 软件架构 本工具以安卓SDK自带uiautomatorviewer为源码基础,在此上进行深度二次开发. 优化定位符Xpath生成,提取相对短的Xpath,解决自带工具Xpath太长不友好的问题 修复自带uiautomatorviewer截图报错,无法截图的Bug 优化截图速度优化

怎样让你的代码更好的被JVM JIT Inlining

好书推荐:Effective Java中文版(第2版) JVM JIT编译器优化技术有近100中,其中最最重要的方式就是内联(inlining).方法内联可以省掉方法栈帧的创建,方法内联还使让JIT编译器更多更深入的优化变成可能.本人在fastxml(速度比XPP3(基于xmlpull)还快的xml解析器)开源项目中针对方法内联进行了很多学习和实践,这里总结一下,介绍一下怎么让你的代码更好的被JVM JIT Inlining. Inlining相关的启动参数 上一篇博客<Java JIT性能调优

让代码更帅一点

博主的私人博客 写代码最重要的是实现功能,但是除了实现功能之外,我们还应该想办法,让代码变得更规范,更漂亮 最近在读<禅与Objective-C编程艺术>和<Effective Objective C 2.0:编写高质量iOS与OS X代码的52个有效方法>,这两本都讲解了代码规范方面的东西,结合自己平时的代码习惯,发现有很多地方自己做的还是不够好,代码写得不够帅,所以总结一下,让以后的代码更帅一点 条件语句 条件语句一定要使用括号,如果不使用括号,if后面的那行代码删除,之后的代