如何对 android 和 iOS 使用相同的 Cucumber 步骤定义

How do I use same Cucumber step definitions for android and iOS

我目前正在为 Android 和 iOS 在流程和设计上相同的应用程序开始一个自动化项目。我正在使用 Ruby 和 Cucumber 框架。

我已经开始自动化 Android,基本上我需要做的是为每个步骤定义 android 和 ios 有点像这个伪代码:

Then (/^I click the Login Button$/) do
 if mobile_platform = android
     #android locators and code here
 else
     #iOS locators and code here
 end 
end

我将如何设置我的项目以允许使用这种特定的步骤定义?

每个 OS 都有单独的特征和步骤定义而不是试图将它们融合在一起更好吗?

感谢您能给我的所有帮助。

我不会为不同的操作系统准备单独的功能文件。您希望您的应用程序以相同的方式独立于操作系统运行。如果您有两个特征,您的特征很可能会有所不同。

我的方法是执行两次并在堆栈中将目标环境分开。我会使用环境变量来指示我当前针对的是哪个操作系统。

将在特定环境中执行某些操作的代码会非常不同,因此我会使用工厂来 select 当前要使用的实现。正如您的小示例所建议的那样,我不会考虑在代码中使用多个条件来分离执行。我唯一会遇到这种类型的条件的地方是在创建将使用您的应用程序的实际 class 的工厂方法中。

您应该使用不依赖于任何 O.S.

的单个功能文件

如果您发现任何此类情况,您必须根据 O.S 将操作分开,您已经为上面显示的 it.Like 添加了检查

if mobile_platform = android
     #android locators and code here
 else
     #iOS locators and code here

但是您的代码的 95% 应该适用于 O.S。

鉴于应用程序之间的共性,共享功能文件很有意义。管理特定平台 step_definitions 的一种简洁方法是将它们保存在单独的目录中。

以下面的简单示例项目为例。

您可以使用 cucumber -r(要求)选项在备用步骤定义文件夹之间切换,如下所示:

cucumber -r features/step_definitions_android -r features/support

请注意,一旦您使用 -r 选项,自动加载就会被禁用,因此您需要明确包含第二个 require 以提取您在 features/support 文件夹中的任何代码。

为了更容易运行针对替代目标,您可以创建相应的配置文件:

# cucumber.yaml
android: -r features/step_definitions_android -r features/support
ios: -r features/step_definitions_ios -r features/support

如下所示,当这些配置文件中的每一个都是 运行 时,将调用相关的特定于平台的步骤定义。

为什么不在 cucumber.yml 中添加一行来表示您使用的是 android 还是 ios?

mobile_platform: 'android'

在环境文件中,您可以这样做:

require 'yaml'
cucumber_options = YAML.load_file('cucumber.yml')
$mobile_platform = cucumber_options['mobile_platform']

然后在您的步骤定义文件中,您可以开始这样做:

Then (/^I click the Login Button$/) do
 if $mobile_platform == 'android'
     #android locators and code here
 else
     #iOS locators and code here
 end 
end

正如 Thomas 所说,让事情变得简单的关键是将事情推入堆栈。为此,您需要应用具有大量纪律的简单模式。

该模式是使每个步骤定义实现对辅助方法的单个调用。一旦进入辅助方法,您就可以使用诸如使用环境变量、配置或某些条件来选择实现等技术。

一个例子可能会阐明这一点。假设这两个应用程序都具有添加朋友的功能。当你第一次添加这个功能时,你会有一个像

这样的步骤
When 'I add a friend' do
  fill_in first_name: 'Frieda'
  fill_in last_name: 'Fish'
  ...
end

这需要变成

When 'I add a friend' do
   add_friend name: 'Frieda'
end

实施
module FriendStepHelper
  def add_friend( ...)
    // Only start thinking about IOS or Android from here down.
    ...
  end
end

现在这可能看起来有点痛苦,但您所做的是将此问题从 Cucumber 领域中移除(它不是为处理此类问题而设计的)并将其移至 Ruby 这当然是为了解决这类问题而设计的。

现在你在你的编程语言中,你可以使用各种技术来优雅和简单地应用你的条件,例如

#use hungarian prefix's
def ios_add_friend
def droid_add_friend

#return early from os specific functions if wrong OS
def ios_add_friend
  return if droid?
  ...
end

# run both implementations when they are different
def add_friend
  ios_add_friend
  droid_add_friend
end

# loads of other alternatives

...

单独使用 (-r) require 选项无法解决此问题。比方说,您在两个不同的文件夹中定义步骤,

--features
----step_definitions_android
----step_definitions_ios

解决方案是启用 (-e) exclude 选项,而不是设置所需的步骤。

IOS

的执行命令
cucumber -e features/step_definitions_android -r features/scenarios/

Android

的执行命令
cucumber -e features/step_definitions_ios -r features/scenarios/