测试自动化之路--selenium

首先,先问自己是否真的需要使用浏览器。 奇怪的是,在某些情况下,如果您正在使用复杂的Web应用程序,则需要打开浏览器并进行实际测试。

但是,功能性的最终用户测试(例如Selenium测试)运行起来很昂贵。 此外,它们通常需要适当的基础结构才能有效运行。 始终问自己,要使用更轻量级的测试方法(例如单元测试)还是使用较低级别的方法来完成测试。

一旦确定要从事Web浏览器测试业务,并且准备好Selenium环境即可开始编写测试,则通常将执行以下三个步骤的组合:

  1. 设置数据

  2. 执行一组离散操作

  3. 评估结果

你会希望这些步骤越短越好;在大多数情况下,一个或两个操作就足够了。浏览器自动化被认为是不可靠的,但实际上,这是因为用户经常需要太多的自动化。在后面的章节中,我们将返回到您可以用来缓解测试中明显的间歇性问题的技术,特别是关于如何克服浏览器和WebDriver之间的竞争条件。

通过保持测试简短,并且只在绝对没有其他选择的情况下使用web浏览器,您可以使用最少的冗余来进行许多测试。

Selenium测试的一个明显优势是,从用户的角度测试应用程序的所有组件(从后端到前端)的固有能力。因此,换句话说,虽然功能测试运行起来可能很昂贵,但它们同时也包含了大量对业务至关重要的部分。

测试要求

如前所述,Selenium测试的运行成本可能很高。在何种程度上取决于您所针对的是哪个浏览器,但是从历史上看,浏览器的行为变化如此之大,以至于经常将针对多个浏览器进行交叉测试作为一个既定目标。Selenium允许您在多个操作系统上的多个浏览器上运行相同的指令,但是枚举所有可能的浏览器、它们的不同版本以及它们所运行的许多操作系统将很快成为一项重要的任务。

Selenium允许您在多个操作系统上的多个浏览器上运行相同的指令,但是枚举所有可能的浏览器、它们的不同版本以及它们所运行的许多操作系统将很快成为一项重要的任务。

让我们从一个例子开始

拉里(Larry)编写了一个网站,允许用户订购自己的定制独角兽。

一般的工作流程(我们称之为“快乐之路”)如下所示:

创建一个帐户

配置独角兽

将其添加到购物车

退房并付款

提供有关独角兽的反馈

编写一个宏伟的Selenium脚本来执行所有这些操作将很诱人-许多人会尝试的。 抵制诱惑! 这样做会导致以下测试:a)需要很长时间,b)会遇到一些与页面渲染计时问题有关的常见问题,并且c)这样的测试如果失败,将不会给您带来简洁的印象 诊断出问题的方法。

测试这种情况的首选策略是将其分解为一系列独立的,快速的测试,每个测试都有一个“原因”。

让我们假装您要测试第二步:配置您的独角兽。 它将执行以下操作:

创建一个帐户

配置独角兽

请注意,我们将跳过其余的步骤,在完成这一工作之后,我们将在其他小的离散测试用例中测试工作流的其余部分。

首先,您需要创建一个帐户。 您可以在这里做出一些选择:

您要使用现有帐户吗?

您要创建一个新帐户吗?

在配置开始之前,是否需要考虑此类用户的任何特殊属性?

不管您如何回答此问题,解决方案都是使其成为测试“设置数据”部分的一部分。 如果Larry公开了一个使您(或任何人)可以创建和更新用户帐户的API,请确保使用该API回答此问题。 如果可能的话,您只想在拥有用户“手”之后才启动浏览器,您可以使用该用户的凭据登录。

如果针对每个工作流程的每个测试都从创建用户帐户开始,那么执行每个测试的时间将增加很多秒。 调用API并与数据库对话是快速,“无头”的操作,不需要打开浏览器,导航到正确的页面,单击并等待表单提交等昂贵的过程。

// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());

可以想象,可以将UserFactory扩展为提供诸如createAdminUser()和createUserWithPayment()之类的方法。 关键是,这两行代码不会分散您本测试的最终目的:配置独角兽。

页面对象模型的复杂性将在后面的章节中讨论,但是我们将在这里介绍这个概念:

您的测试应由在网站页面范围内从用户角度执行的操作组成。 这些页面存储为对象,其中将包含有关网页的组成方式和操作方式的特定信息-作为测试人员,其中很少涉及您。

您想要哪种独角兽? 您可能想要粉红色,但不一定。 紫色最近很受欢迎。 她需要太阳镜吗? 明星纹身? 这些选择虽然很困难,但却是测试人员的首要考虑因素–您需要确保订单履行中心将正确的独角兽发送给合适的人,并且从这些选择开始。

请注意,我们在该段中没有任何地方讨论按钮,字段,下拉菜单,单选按钮或Web表单。 您的测试也不应该! 您希望像尝试解决他们的问题的用户一样编写代码。 这是执行此操作的一种方法(从上一个示例继续):

nicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

现在,您已经配置了独角兽,您需要继续进行第3步:确保它确实有效。

Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));

请注意,测试人员仍然没有做任何事情,只是在此代码中谈论独角兽-没有按钮,没有定位器,没有浏览器控件。 这种对应用程序建模的方法使您可以将这些测试级别的命令保留在原处,并且保持不变,即使Larry下周决定不再喜欢Ruby-on-Rails并决定在最新的Haskell绑定中重新实现整个站点 与Fortran前端。

您的页面对象将需要进行一些小的维护,以符合网站的重新设计要求,但是这些测试将保持不变。 采用此基本设计,您将希望以尽可能少的面向浏览器的步骤来完成工作流程。 下一个工作流程将涉及在购物车中添加独角兽。 您可能需要进行多次此测试,以确保购物车正确保持其状态:开始之前,购物车中是否有多个独角兽? 购物车中可以容纳多少个? 如果您创建多个具有相同名称和/或功能的产品,会不会破裂? 它会仅保留现有的一个,还是会添加另一个?

每次在工作流程中移动时,都希望避免创建帐户,以用户身份登录和配置独角兽。 理想情况下,您将能够通过API或数据库创建帐户并预配置独角兽。 然后,您要做的就是以用户身份登录,找到Sparkles,然后将她添加到购物车中。

自动化还是不自动化?

自动化总是有优势吗? 一个人应该何时决定自动化测试用例?

自动化测试用例并不总是有利的。 有时手动测试可能更合适。 例如,如果应用程序的用户界面在不久的将来会发生很大变化,那么任何自动化都可能需要重写。 而且,有时根本没有足够的时间来构建测试自动化。 从短期来看,手动测试可能更有效。 如果应用程序的截止日期非常紧迫,则目前没有可用的测试自动化功能,并且必须在该时间范围内完成测试,那么手动测试是最好的解决方案。