我正在使用硒测试对非公共科学用例执行基于GUI的系统测试。尽管我围绕selenium模块构建了一个或多或少的完整包装器,其功能始终等待元素出现(WebDriverWait),处理嵌套的iframe(switch-to-frame),甚至捕获异常以再次尝试(就像首先获得WebDriver一样),这些测试始终无法正常运行。我一直在不同的测试中出现随机故障,没有明显的原因且不可重复。

由于测试失败的原因,我的猜测是:


硒根本不是用户友好的,并且无缘无故地引发了许多奇怪的错误。
我加载的页面使用了我控制范围之外的许多其他服务(身份验证框架,分析框架等)
页面加载时间可能很长(10秒),有时甚至根本无法加载。 br />
硒周围是否有其他框架或某种包装方法,它提供了用于SOLID测试的方法,这些方法可提供一致,可靠和可重复的测试结果?还是有其他一些想法可以使硒测试一致,可靠和可重现?

一些错误:


随机Timeout错误(我等待了足够的时间出现一个元素,
,但是没有出现。原因目前未知,很难调试
,因为在手动测试时这些错误不会显示)
随机WebDriverException:例如can't access dead object(再次,手动或自动运行单个测试用例时不出现)。
套接字级别上的随机超时。
StaleElementReferenceException
虽然可见,存在,可单击和在屏幕截图中可见,但未找到元素,并且在本地工作但不在docker内部工作...

/>

评论

您为什么认为Selenium不友好?错误可能看起来很奇怪,因为页面上发生了奇怪的意外事件,而浏览器确实使发生的事情感到困惑。但这不是硒的问题,而是我们所处的复杂世界。责怪硒是不公平的。

没有随机或奇怪的问题,请至少发布一些常见错误。通常是错误的代码或错误的应用程序。

什么是错误?

当事情进入不希望的意外状态时,就会发生松软。在测试之前和之后,不要假设状态,必须声明状态。

如果您真的有一个系统,那么有时会出现按钮而有时却没有出现按钮的情况,我认为您遇到的问题要比不稳定的测试大得多。

#1 楼

我曾在多家公司中为这个问题苦苦挣扎。它似乎总是在某个时候出现,然后随着时间的推移成为一个主要问题。

我也已经走过了睡觉,轮询等待,检查ajax完成,检查js完成,检查动画完成等。它们有时会帮助解决一些错误,但似乎总是在您认为自己已修复某些问题并且经过一堆运行之后才感到遗憾!最令人沮丧的是,当您自己运行规范时,似乎总是第二次过去。

我现在的处理方法是:重新运行示例

在诉诸于此之前,我投入了大量工作来诊断问题并尝试各种方法。当各种方法失败时,我将考虑添加1到2秒的固定睡眠时间(在轮询之前,即发出find element命令)。如果这样做没有帮助,我可以使用重试示例路由。

我可以通过WebDriver的ruby-rspec-capybara实现以及使用rspec-retry gem轻松地做到这一点。

基本上,当我确定了我无法解决的间歇性错误中的一种时,我允许使用重试方法来解决它。

最初我只是这样做是为众所周知的红宝石Net::ReadTimeout错误。最近,我将其用法扩展到了Capybara::ElementNotFound,并且效果很好。

主要缺点是,在测试自动化开发过程中,您可能希望禁用此功能,以使真正的元素找不到情况错误立即消失。

显然,这种方法也不是理想的方法,某些开发人员也不喜欢这种方法。我认为这是“现实世界”的折衷方案,考虑到以下警告,这是一种很好的方法:


规范通常会通过
故障率很低,例如2-5%
规范通常会重试通过
更具体的方法(如轮询等待或ajax等待)仍未解决问题
您限制了重试次数/>您可以确定要重试的错误的范围-这很重要,例如,我使用数组[Net::ReadTimeout, Capybara::ElementNotFound]来限制要重试的内容。


#2 楼

薄片测试是众所周知的痛点:




如何处理具有间歇性故障的薄片测试? (关于SO及其链接)

如何处理具有间歇性故障的易碎测试?我们的片状测试来自哪里?在Goggle博客上。

如何修复Flaky Test Automation-另一个集合,这要归功于@Rsf

,因为这么多非常聪明的人长时间无法解决它,我相信脆弱性将继续存在,作为我们生活的不可靠世界的固有组成部分。比Java WebDriver稍差一些,这可能表示未修复的错误),但是他们的结论是,与脆弱性的最佳相关性会影响测试大小:测试时间越长,其易出错的可能性就越大。

因此:


反对片状考验,甚至Google自己也徒然满意。徒劳-艾萨克·阿西莫夫(Isaac Asimov)着名的科幻小说。

詹金斯(Jenkins)是持续集成(CI)的流行测试跑步者,它反复运行测试并显示f的“平均”状态过去以“天气”运行:测试的晴天都通过了,如果通过和失败的混合都为“多云”,而如果测试始终失败则为“多雨”。您所需要做的就是:如果有时间,请检查“阴天”,但请担心(并修复)“阴雨天”。

评论


另外一个[如何修复Flaky Test Automation](eviltester.com/page/flaky)

–Rsf
18年3月14日在15:18

#3 楼

不稳定测试的第一大原因是因为不稳定的网站
如果您要在完全静态的网页上运行测试,并且要在本地进行测试,那么我敢肯定,写得很好的测试可以工作100时间百分比。
但是,如果发生以下情况:

使用数据库填充数据,
使用js / node / ajax动态更新页面,
在来自远程服务器的资源(js / css)中,
托管在不受您直接控制的服务器上,
或依靠angular / react /任何框架来添加动画和其他漂亮的内容

...您需要接受一定程度的失败。
其中任何一个都可能是失败和/或缓慢的点,这将导致测试变得不稳定。考虑到大多数值得测试的网站都是基于这些因素中的大多数(即使不是全部),因此您正在战胜一场失败的战斗。

评论


网页不是静态的,可以访问许多其他服务,包含iframe ...

– Alex
18-3-15的7:27

当场评论!

–Rain9333
18/12/6在9:34

#4 楼

简短的答案:通过断言数据和测试对象(定位符)的状态而不是假设。

长的答案:

通过使UI(包括硒)自动化测试可以更加稳定

为什么首先要发生片状????

当事物进入不希望的和意外的状态时,会发生片状。解决方案吗?
在执行任何UI操作之前不要假定状态,在对象和数据上声明状态。

通过声明状态是数据还是对象,易碎的系统/应用与测试自动化隔离。

执行任何UI操作之前,请确保您位于预期的页面上,应用程序数据处于预期状态,并且要对其进行操作的对象也处于预期状态。测试数据:对于数据(测试数据),我将确保在测试开始之前数据始终处于已知的基本状态。我通常建议在运行之前进行刷新/还原数据库,这是设置/配置步骤的一部分。

定位器:对于对象(定位器),在执行操作之前,我会在加载和其他定位器状态(显示,isEnabled,isClickable等)之后声明页面。

将断言用作安全网,以便在出现问题时帮助您快速查明根本原因。
我将断言视为单元测试f或UI测试自动化。

#5 楼

从外观上看,最大的问题不是您的Selenium测试,而是应用程序(或测试环境)本身。

如果您的测试是用健壮的方式编写的,并且它们仍然显示出很多问题,错误(例如页面加载超时,未及时显示的元素……),那么我建议您:保持测试不变,因为它们通过显示存在的(性能)问题来证明其价值。

通过更新测试以在错误的应用程序上工作,您将一无所获。

#6 楼

硒本身不会无故抛出很多奇怪的错误。所有错误都描述发生了什么,当您在Google上搜索它们时,有很多建议说明发生了什么原因以及如何解决该问题。显然,无法通过测试来改善这一点,但是您可以检查什么无效以及何时使用。页面的部分加载可能真的很慢-因此,最好编写一种方法来验证其中的一部分并在测试中使用。

如果页面加载缓慢,则添加等待页面加载

但是,是的,我发现使用硒方法无需包裹非常烦人的事情。我像这样(C#)类似地扩展了它们:

 public static string GetAttribute(this IWebElement e, string attr, IWebDriver d, WebDriverWait w)
    {

        Pause(1000);

        var c = WaitInSeconds(w);

        c = c - 2;

        var w2 = new WebDriverWait(d, TimeSpan.FromSeconds(c));

        string att = null;

        if (c <= 1)
        {
            throw new Exception("Could not get attribute.");
        }         

        try
        {
            att = e.GetAttribute(attr);              
        }

        catch (Exception ex)
        {
            Console.WriteLine("\nTried to get attribute, but got an exception: \n" + ex + "\n");
            Pause(500);
            e.GetAttribute(attr, d, w2);

        }

        Console.WriteLine("Got: " +attr+ " value: "+att+ " and counter is at: " +c);

        return att;
    }


减少了随机陈旧元素,短暂地覆盖了另一个元素,这样就大大减少了错误。 />
问题是测试以后失败很多。但是,硒测试本身并不快,并且可以通过许多不同的方式来提高速度,因此我认为这是一个很好的折衷,不必调试每个测试中的每个单击并在其中捕获错误。

#7 楼


硒周围是否可能存在不同的框架或某种包装,它提供了用于SOLID测试的方法,这些方法可提供一致,可靠和可重现的测试结果?如果您使用Java:

用于AJAX应用程序,建议您使用Selenide。在测试AJAX应用程序时,测试通常需要等待直到某些元素更改其状态。 Selenide具有内置的等待方法。
此外,如果您测试AngularJS应用程序,我发现NgWebDriver对于等待Angular完成异步活动非常有用。例如,我有一个带有过滤器的表,我想检查是否存在针对我放入过滤器中的特定查询的条目。输入查询结果会在后台更新表,但是您需要等到表完成后才能检查结果。


或者还有其他一些想法可以使硒测试一致,可靠可以重现吗?

是的,有一些错误。

一些错误:

随机Timeout错误(我等待了足够的时间让元素出现,但它没有出现。原因目前未知,很难调试,因为在手动测试时这些错误不会显示)


这些东西很难重现。其背后可能有不同的原因,但它们可能与硒本身无关。在不同的测试环境,不同的浏览器(Chrome与Firefox)甚至同一浏览器的不同版本(Firefox 49与56)上进行测试时,我发现了此类问题。

随机WebDriverException:例如无法访问死对象(再次,手动或自动运行单个测试用例时不会出现)。

这是非常通用的。这实际上取决于您要记住的WebDriverException

套接字级别的随机超时。

这是非常通用的。这实际上取决于您的意思是什么套接字,也许应该在此处单独提出一个问题。

StaleElementReferenceException

我上面提到的硒化通常可以解决这些问题。还有整个线程如何在Selenium中避免“ StaleElementReferenceException”?关于如何处理该问题。

评论


现在,我无法解决自动化测试的问题。它们只是没有明显的原因而无法工作。对于如何调试它们,我没有更多的想法。我现在迷路了。

– Alex
18年3月19日在14:07

@Alex开发良好且稳定的Selenium(或一般而言,进行端到端测试)是一项复杂的任务:许多难以控制的动态部件。我将把您遇到的问题归为不同的问题:每个问题都应有一个单独的问题。而且总有一个原因。运行时的堆栈跟踪,日志和调试可以提供帮助。

– dzieciou
18 Mar 19 '18在15:08



是否有关于此主题的书,其中最详细地讨论了这些要点?硒的日志从没有帮助过我。如何在运行时调试?

– Alex
18年3月19日在15:25

@Alex Re:调试jetbrains.com/help/idea/…或与您的开发人员配对

– dzieciou
18年3月19日在15:29

在我的情况下,开发人员无法提供帮助。

– Alex
18年3月19日在15:30

#8 楼

在我们公司,我们进行了大约1000次硒测试。我们为每次推送运行测试(作为CI流程的一部分),而使测试稳定的工作是简单地再次运行失败的测试,然后再次运行。如果3次相同的测试失败,则构建也将失败。