如何将 Appium 与 C# 集成?
How to integrate Appium with C#?
我找不到可以在 C# 中使用 appium 自动进行移动测试的 post。
我已经在 specflow 中编写了我的网站自动化代码。我也可以重复使用它吗?
Appium 提供 dotnet-appium-driver,这是您与 Appium 交互的 API。您可以使用它来编写您的应用程序自动化。
您在这里没有提供任何示例或代码,所以我无法真正采取行动向您展示。我将只写一些 C# 代码,让您了解如何在 C# 中编写一个简单的测试:
namespace AppiumTests
{
using System;
// .NET unit test namespaces needed here as well, just not mentioning them
using OpenQA.Selenium; /* Appium is based on Selenium, we need to include it */
using OpenQA.Selenium.Appium; /* This is Appium */
[TestClass]
public class TestSuite
{
private AppiumDriver driver;
private static Uri testServerAddress = new Uri("http:127.0.01:4723/wd/hub"); // If Appium is running locally
private static TimeSpan INIT_TIMEOUT_SEC = TimeSpan.FromSeconds(180); /* Change this to a more reasonable value */
private static TimeSpan IMPLICIT_TIMEOUT_SEC = TimeSpan.FromSeconds(10); /* Change this to a more reasonable value */
[TestInitialize]
public void BeforeAll()
{
DesiredCapabilities testCapabilities = new DesiredCapabilities();
testCapabilities.App = "<your-app-file>";
testCapabilities.AutoWebView = true;
testCapabilities.AutomationName = "";
testCapabilities.BrowserName = String.Empty; // Leave empty otherwise you test on browsers
testCapabilities.DeviceName = "Needed if testing on IOS on a specific device. This will be the UDID";
testCapabilities.FwkVersion = "1.0"; // Not really needed
testCapabilities.Platform = TestCapabilities.DevicePlatform.Android; // Or IOS
testCapabilities.PlatformVersion = String.Empty; // Not really needed
driver = new AppiumDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
driver.Manage().Timeouts().ImplicitlyWait(IMPLICIT_TIMEOUT_SEC);
}
[TestCleanup]
public void AfterAll()
{
driver.Quit(); // Always quit, if you don't, next test session will fail
}
///
/// Just a simple test to heck out Appium environment.
///
[TestMethod]
public void CheckTestEnvironment()
{
var context = driver.GetContext();
Assert.IsNotNull(context);
}
}
}
你可以在我写的 this article 中找到更多信息。
终于找到解决方案 运行 在 C# 中进行测试。非常感谢 Andry。
此解决方案运行在您phone的chrome浏览器中连接到计算机的网站:
使用 Appium 在 android 设备上设置和 运行 C# 程序的步骤和短程序:
namespace poc
{
using NUnit.Framework;
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Interfaces;
using OpenQA.Selenium.Appium.MultiTouch;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
[TestFixture()]
public class TestAppium
{
public IWebDriver driver;
[TestFixtureSetUp]
public void SetUp()
{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.SetCapability("device", "Android");
capabilities.SetCapability("browserName", "chrome");
capabilities.SetCapability("deviceName", "Motorola Moto g");
capabilities.SetCapability("platformName", "Android");
capabilities.SetCapability("platformVersion", "5.0.2");
driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities, TimeSpan.FromSeconds(180));
}
[Test()]
public void OpenHofHomePage()
{
driver.Navigate().GoToUrl("http://YourWebsiteToTest.com");
Assert.IsTrue(driver.Title.Equals("Your Website")," Sorry , the website didnt open!!");
}
[TestFixtureTearDown]
public void End()
{
driver.Dispose();
}
}
}
1) 在 C# 中设置常用项目,使用 NuGet 包管理器安装 Appium 和 Selenium,并使用相同的过程安装 Nunit。
2) 下载Android SDK
3) 环境变量:添加变量名称 "ANDROID_HOME" 并在变量中提供 sdk 文件夹的路径,在 PATH(位于系统变量中)中,将路径附加到 sdk 文件夹中的工具并将路径附加到平台工具。
4) 连接您的设备(a.mobile 设备的驱动程序应该安装在计算机中(我的情况是安装了 moto g adb 驱动程序) b. 设备应该打开开发者模式选项并选中调试器选项和始终唤醒选项选中)
5) 现在下载 Appium 并打开 Appium.exe。
6) Appium window -> 在 Android 设置(第一个按钮)中,选中 "Use Browser" 选项和 select "Browser" 作为选项。
7) 启动appium节点服务器(顶部的播放按钮)。
8) 现在 运行 来自 visual studio 的测试,您将看到网站在 phone 的浏览器中打开。
为了更全面,我写了一篇博客post,用图片清楚地解释了所有步骤。它是将 appium 与 c# 和 MSTest 结合使用的分步教程
你可以在这里阅读它。
http://www.binaryclips.com/2016/03/test-automation-on-android-using-appium.html
这就是我实现 Appium 的方式。我认为这增加了讨论的深度。
Appium 既是可以与项目中的设备交互的 WebDriver,也是将项目桥接到物理设备或模拟器的服务器。
您必须 运行 Appium 服务器作为侦听器并设置您的 Capabilities 以连接到它。这将启动应用程序并执行您的测试。
除此之外还有很多其他设置,但您可以尝试按照自己的方式进行设置:
在 WebDriver 支持中 Class 使用 [BeforeScenario] 标签在测试前执行此代码。这有一个 Sauce Labs 实现。
[BeforeScenario]
public void BeforeScenario()
{
var name = Locale == "sauce" ? "AppiumSauceDriver" : "AppiumDriver";
InitializeServiceLocator();
if (WebDriver == null)
{
InitializeWebDriver(name);
}
ObjectContainer.RegisterInstanceAs(WebDriver);
if (WebDriver != null)
{
Console.WriteLine("Driver Already Exists");
}
}
然后您需要填充 InitializeServiceLocator() 方法。这里有一个设备选择器方法,它除了设置名称外什么都不做。您可以将其硬编码为您的功能。
private static void InitializeServiceLocator()
{
if (ServiceLocator == null)
{
var ip = "";
var deviceType = TestSetupHelper.DeviceSelector["iphone7"];
var capabilities = TestSetupHelper.SetAppiumCababilities(deviceType, Locale);
string server = MSTestContextSupport.GetRunParameter("appiumServer");
var port = Convert.ToInt32(MSTestContextSupport.GetRunParameter("appiumPort"));
if (Locale != "sauce")
{
ip = TestSetupHelper.GetComputerIpAddress(server, port, true);
}
var kernel = new StandardKernel();
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://" + ip + ":" + port + "/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumDriver");
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://ondemand.saucelabs.com:80/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumSauceDriver");
ServiceLocator = new NinjectServiceLocator(kernel);
Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => ServiceLocator);
}
}
从这里您需要设置您的能力。下面的方法是我的做法。
public static DesiredCapabilities SetAppiumCababilities(string deviceType, string locale, bool realDevice = false, string udid = "FAKEUDIDFOREXAMPLE")
{
string appiumAppFilePath = MSTestContextSupport.GetRunParameter("appiumAppFilePath");
//Universal Capabilities
capabilities.SetCapability("platformName", "iOS");
capabilities.SetCapability("deviceName", deviceType);
capabilities.SetCapability("automationName", "XCUITest");
capabilities.SetCapability("app", appiumAppFilePath);
capabilities.SetCapability("xcodeOrgId", "GET_THIS_FROM_APP_DEV");
capabilities.SetCapability("xcodeSigningId", "iPhone Developer");
capabilities.SetCapability("noReset", true);
capabilities.SetCapability("newCommandTimeout", 80);
if (locale == "sauce")//Sauce specific capabilities
{
capabilities.SetCapability("appiumVersion", "1.7.2");
capabilities.SetCapability("name", MSTestContextSupport.GetRunParameter("appiumJobName"));
capabilities.SetCapability("username", MSTestContextSupport.GetRunParameter("sauceId"));
capabilities.SetCapability("accessKey", MSTestContextSupport.GetRunParameter("sauceKey"));
capabilities.SetCapability("tunnel-identifier", MSTestContextSupport.GetRunParameter("sauceTunnel"));
capabilities.SetCapability("browserName", "");
capabilities.SetCapability("platformVersion", "11.2");
}
else//Local specific capabilities
{
capabilities.SetCapability("platformVersion", "11.3");
}
if (realDevice)//Sauce real device testing will not need this. This is for Local Real Device testing only
{
capabilities.SetCapability("udid", udid);
}
return capabilities;
}
任何引用 GetRunParameter 的东西都从 .运行settings 文件中获取值。
示例:
<TestRunParameters>
<Parameter name="appiumJobName" value="OBI App Automated Test"/>
</TestRunParameters>
您必须将所有内容添加到您正在使用的 .运行settings 文件中,以 运行 您希望从那里获取资源的项目。如果您不想通过 运行settings 文件,您可以对其进行硬编码,但我更喜欢这样做。您可以根据您选择的 运行 设置文件以这种方式设置变量。
然后你要定义TestSetupHelper.GetComputerIpAddress(server, port, true);如果你有一个硬编码的 IP 地址到 运行 连接你的 Appium 服务器的计算机,你可以硬编码它。否则你需要一个 Helper class 某处(在这个例子中它是 TestSetupHelper)。此示例启动到服务器的套接字连接和 returns 所有详细信息。这样您就不必担心 IP 地址会发生变化。您只需传递您将 Appium 配置为 运行 的主机名和端口,您就可以从该连接获取连接信息,并与 Appium Server 实例建立实际连接。
public static string GetComputerIpAddress(string computerName, int port, bool remote)
{
var ip = "";
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect(computerName, port);
//If remote it gets the connection destination IP, else it gets the connection initiator IP
IPEndPoint endPoint = remote ? socket.RemoteEndPoint as IPEndPoint : socket.LocalEndPoint as IPEndPoint;
ip = endPoint.Address.ToString();
}
return ip;
}
这不会让您完全达到目标,但会让您接近工作环境。然后你就可以开始进行测试了 运行.
希望对您有所帮助。
我找不到可以在 C# 中使用 appium 自动进行移动测试的 post。
我已经在 specflow 中编写了我的网站自动化代码。我也可以重复使用它吗?
Appium 提供 dotnet-appium-driver,这是您与 Appium 交互的 API。您可以使用它来编写您的应用程序自动化。
您在这里没有提供任何示例或代码,所以我无法真正采取行动向您展示。我将只写一些 C# 代码,让您了解如何在 C# 中编写一个简单的测试:
namespace AppiumTests
{
using System;
// .NET unit test namespaces needed here as well, just not mentioning them
using OpenQA.Selenium; /* Appium is based on Selenium, we need to include it */
using OpenQA.Selenium.Appium; /* This is Appium */
[TestClass]
public class TestSuite
{
private AppiumDriver driver;
private static Uri testServerAddress = new Uri("http:127.0.01:4723/wd/hub"); // If Appium is running locally
private static TimeSpan INIT_TIMEOUT_SEC = TimeSpan.FromSeconds(180); /* Change this to a more reasonable value */
private static TimeSpan IMPLICIT_TIMEOUT_SEC = TimeSpan.FromSeconds(10); /* Change this to a more reasonable value */
[TestInitialize]
public void BeforeAll()
{
DesiredCapabilities testCapabilities = new DesiredCapabilities();
testCapabilities.App = "<your-app-file>";
testCapabilities.AutoWebView = true;
testCapabilities.AutomationName = "";
testCapabilities.BrowserName = String.Empty; // Leave empty otherwise you test on browsers
testCapabilities.DeviceName = "Needed if testing on IOS on a specific device. This will be the UDID";
testCapabilities.FwkVersion = "1.0"; // Not really needed
testCapabilities.Platform = TestCapabilities.DevicePlatform.Android; // Or IOS
testCapabilities.PlatformVersion = String.Empty; // Not really needed
driver = new AppiumDriver(testServerAddress, capabilities, INIT_TIMEOUT_SEC);
driver.Manage().Timeouts().ImplicitlyWait(IMPLICIT_TIMEOUT_SEC);
}
[TestCleanup]
public void AfterAll()
{
driver.Quit(); // Always quit, if you don't, next test session will fail
}
///
/// Just a simple test to heck out Appium environment.
///
[TestMethod]
public void CheckTestEnvironment()
{
var context = driver.GetContext();
Assert.IsNotNull(context);
}
}
}
你可以在我写的 this article 中找到更多信息。
终于找到解决方案 运行 在 C# 中进行测试。非常感谢 Andry。
此解决方案运行在您phone的chrome浏览器中连接到计算机的网站:
使用 Appium 在 android 设备上设置和 运行 C# 程序的步骤和短程序:
namespace poc
{
using NUnit.Framework;
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Interfaces;
using OpenQA.Selenium.Appium.MultiTouch;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
[TestFixture()]
public class TestAppium
{
public IWebDriver driver;
[TestFixtureSetUp]
public void SetUp()
{
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.SetCapability("device", "Android");
capabilities.SetCapability("browserName", "chrome");
capabilities.SetCapability("deviceName", "Motorola Moto g");
capabilities.SetCapability("platformName", "Android");
capabilities.SetCapability("platformVersion", "5.0.2");
driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4723/wd/hub"), capabilities, TimeSpan.FromSeconds(180));
}
[Test()]
public void OpenHofHomePage()
{
driver.Navigate().GoToUrl("http://YourWebsiteToTest.com");
Assert.IsTrue(driver.Title.Equals("Your Website")," Sorry , the website didnt open!!");
}
[TestFixtureTearDown]
public void End()
{
driver.Dispose();
}
}
}
1) 在 C# 中设置常用项目,使用 NuGet 包管理器安装 Appium 和 Selenium,并使用相同的过程安装 Nunit。
2) 下载Android SDK
3) 环境变量:添加变量名称 "ANDROID_HOME" 并在变量中提供 sdk 文件夹的路径,在 PATH(位于系统变量中)中,将路径附加到 sdk 文件夹中的工具并将路径附加到平台工具。
4) 连接您的设备(a.mobile 设备的驱动程序应该安装在计算机中(我的情况是安装了 moto g adb 驱动程序) b. 设备应该打开开发者模式选项并选中调试器选项和始终唤醒选项选中)
5) 现在下载 Appium 并打开 Appium.exe。
6) Appium window -> 在 Android 设置(第一个按钮)中,选中 "Use Browser" 选项和 select "Browser" 作为选项。
7) 启动appium节点服务器(顶部的播放按钮)。
8) 现在 运行 来自 visual studio 的测试,您将看到网站在 phone 的浏览器中打开。
为了更全面,我写了一篇博客post,用图片清楚地解释了所有步骤。它是将 appium 与 c# 和 MSTest 结合使用的分步教程 你可以在这里阅读它。 http://www.binaryclips.com/2016/03/test-automation-on-android-using-appium.html
这就是我实现 Appium 的方式。我认为这增加了讨论的深度。
Appium 既是可以与项目中的设备交互的 WebDriver,也是将项目桥接到物理设备或模拟器的服务器。
您必须 运行 Appium 服务器作为侦听器并设置您的 Capabilities 以连接到它。这将启动应用程序并执行您的测试。
除此之外还有很多其他设置,但您可以尝试按照自己的方式进行设置:
在 WebDriver 支持中 Class 使用 [BeforeScenario] 标签在测试前执行此代码。这有一个 Sauce Labs 实现。
[BeforeScenario]
public void BeforeScenario()
{
var name = Locale == "sauce" ? "AppiumSauceDriver" : "AppiumDriver";
InitializeServiceLocator();
if (WebDriver == null)
{
InitializeWebDriver(name);
}
ObjectContainer.RegisterInstanceAs(WebDriver);
if (WebDriver != null)
{
Console.WriteLine("Driver Already Exists");
}
}
然后您需要填充 InitializeServiceLocator() 方法。这里有一个设备选择器方法,它除了设置名称外什么都不做。您可以将其硬编码为您的功能。
private static void InitializeServiceLocator()
{
if (ServiceLocator == null)
{
var ip = "";
var deviceType = TestSetupHelper.DeviceSelector["iphone7"];
var capabilities = TestSetupHelper.SetAppiumCababilities(deviceType, Locale);
string server = MSTestContextSupport.GetRunParameter("appiumServer");
var port = Convert.ToInt32(MSTestContextSupport.GetRunParameter("appiumPort"));
if (Locale != "sauce")
{
ip = TestSetupHelper.GetComputerIpAddress(server, port, true);
}
var kernel = new StandardKernel();
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://" + ip + ":" + port + "/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumDriver");
kernel.Bind<IOSDriver<AppiumWebElement>>().ToConstructor(x => new IOSDriver<AppiumWebElement>(new Uri("http://ondemand.saucelabs.com:80/wd/hub"), capabilities, TimeSpan.FromMinutes(10))).Named("AppiumSauceDriver");
ServiceLocator = new NinjectServiceLocator(kernel);
Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => ServiceLocator);
}
}
从这里您需要设置您的能力。下面的方法是我的做法。
public static DesiredCapabilities SetAppiumCababilities(string deviceType, string locale, bool realDevice = false, string udid = "FAKEUDIDFOREXAMPLE")
{
string appiumAppFilePath = MSTestContextSupport.GetRunParameter("appiumAppFilePath");
//Universal Capabilities
capabilities.SetCapability("platformName", "iOS");
capabilities.SetCapability("deviceName", deviceType);
capabilities.SetCapability("automationName", "XCUITest");
capabilities.SetCapability("app", appiumAppFilePath);
capabilities.SetCapability("xcodeOrgId", "GET_THIS_FROM_APP_DEV");
capabilities.SetCapability("xcodeSigningId", "iPhone Developer");
capabilities.SetCapability("noReset", true);
capabilities.SetCapability("newCommandTimeout", 80);
if (locale == "sauce")//Sauce specific capabilities
{
capabilities.SetCapability("appiumVersion", "1.7.2");
capabilities.SetCapability("name", MSTestContextSupport.GetRunParameter("appiumJobName"));
capabilities.SetCapability("username", MSTestContextSupport.GetRunParameter("sauceId"));
capabilities.SetCapability("accessKey", MSTestContextSupport.GetRunParameter("sauceKey"));
capabilities.SetCapability("tunnel-identifier", MSTestContextSupport.GetRunParameter("sauceTunnel"));
capabilities.SetCapability("browserName", "");
capabilities.SetCapability("platformVersion", "11.2");
}
else//Local specific capabilities
{
capabilities.SetCapability("platformVersion", "11.3");
}
if (realDevice)//Sauce real device testing will not need this. This is for Local Real Device testing only
{
capabilities.SetCapability("udid", udid);
}
return capabilities;
}
任何引用 GetRunParameter 的东西都从 .运行settings 文件中获取值。
示例:
<TestRunParameters>
<Parameter name="appiumJobName" value="OBI App Automated Test"/>
</TestRunParameters>
您必须将所有内容添加到您正在使用的 .运行settings 文件中,以 运行 您希望从那里获取资源的项目。如果您不想通过 运行settings 文件,您可以对其进行硬编码,但我更喜欢这样做。您可以根据您选择的 运行 设置文件以这种方式设置变量。
然后你要定义TestSetupHelper.GetComputerIpAddress(server, port, true);如果你有一个硬编码的 IP 地址到 运行 连接你的 Appium 服务器的计算机,你可以硬编码它。否则你需要一个 Helper class 某处(在这个例子中它是 TestSetupHelper)。此示例启动到服务器的套接字连接和 returns 所有详细信息。这样您就不必担心 IP 地址会发生变化。您只需传递您将 Appium 配置为 运行 的主机名和端口,您就可以从该连接获取连接信息,并与 Appium Server 实例建立实际连接。
public static string GetComputerIpAddress(string computerName, int port, bool remote)
{
var ip = "";
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect(computerName, port);
//If remote it gets the connection destination IP, else it gets the connection initiator IP
IPEndPoint endPoint = remote ? socket.RemoteEndPoint as IPEndPoint : socket.LocalEndPoint as IPEndPoint;
ip = endPoint.Address.ToString();
}
return ip;
}
这不会让您完全达到目标,但会让您接近工作环境。然后你就可以开始进行测试了 运行.
希望对您有所帮助。