【问题标题】:How to integrate Appium with C#?如何将 Appium 与 C# 集成?
【发布时间】:2015-04-22 15:39:27
【问题描述】:

我找不到一篇可以在 C# 中使用 appium 自动进行移动测试的帖子。

我已经在规范流中编写了我的网站自动化代码。我也可以重复使用它吗?

【问题讨论】:

    标签: c# selenium-webdriver appium specflow


    【解决方案1】:

    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找到更多。

    【讨论】:

    • 嘿安德烈,我在 driver = new AppiumDriver 处遇到错误.....它说无法创建抽象类或接口“OpenQA.Selenium.Appium.AppiumDriver”的实例 :(
    • 可能是因为我让你包含了太多东西......只需在编辑的答案中包含命名空间。我假设您的项目中链接了 Appium dotnet 驱动程序 dll。
    • 对不起,它仍然给出相同的错误:(,我也用 AndroidDriver() 替换了它;它给了我错误:结果消息:System.InvalidOperationException:无法创建新会话。(原始错误:未设置应用程序;要么使用 --app 启动 appium,要么在所需功能中传入“app”值,或者将 androidPackage 设置为在设备上启动预先存在的应用程序)
    • 不一样的错误:) 现在你可以访问Appium了,当然你必须指定一个app文件。你想测试什么应用程序?你应该在你的问题中写下更多信息。所以这就是我需要的:1)您是否需要自动化已经安装在您的 Android 设备上的应用程序?或者您是否有要在测试时安装的 APK? 2)如果你想启动一个现有的应用程序,我需要知道 AppPackage 和 AppActivity。 3)如果您想安装它并拥有一个APK文件,请将其移动到运行Appium的PC上并记下该路径
    • 嘿,安德烈,事情已经整理好了。我想在设备的 chrome 和 firefox 上使用我的网站。我没有应用程序,但有一个网站可以在移动 chrome 和 firefox 中实现自动化。我现在面临的问题是无法在 Firefox 和 chrome 中打开网站,我得到一些会话问题,即会话从 chrome 重定向 ..
    【解决方案2】:

    终于找到了在C#中运行测试的解决方案。非常感谢 Andry。

    此方案在连接电脑的手机chrome浏览器中运行网站:

    使用 Appium 在安卓设备上设置和运行 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 窗口 -> 在 Android 设置(第一个按钮)中,选中“使用浏览器”选项并选择“浏览器”作为选项。

    7) 启动 appium 节点服务器(顶部的播放按钮)。

    8) 现在从 Visual Studio 运行测试,您将看到网站在手机浏览器中打开。

    【讨论】:

      【解决方案3】:

      为了更全面,我写了一篇博文,用图片清楚地解释了所有步骤。它是使用 c# 和 MSTest 使用 appium 的分步教程 你可以在这里阅读它。 http://www.binaryclips.com/2016/03/test-automation-on-android-using-appium.html

      【讨论】:

      • 好极了。一篇非常不言自明的文章。
      • @joinsaad。您的链接不再起作用。我收到错误“抱歉,您在此博客中查找的页面不存在。”。这是你的吗? binaryclips.com/2016/03/…
      • 链接已修复,请重试。
      【解决方案4】:

      这就是我实现 Appium 的方式。我认为这增加了讨论的深度。

      Appium 既是一个可以与项目中的设备交互的 WebDriver,也是一个将项目连接到物理设备或模拟器的服务器。

      您必须将 Appium 服务器作为侦听器运行并设置您的 Capabilities 以连接到它。这将启动应用程序并执行您的测试。

      除此之外还有很多其他功能,但这里有一个设置,您可以尝试让您顺利上路:

      在 WebDriver 支持类中,使用 [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 的内容都是从 .runsettings 文件中获取值。

      例子:

      <TestRunParameters>
      <Parameter name="appiumJobName" value="OBI App Automated Test"/>
      </TestRunParameters>
      

      您必须将所有内容添加到您正在使用的 .runsettings 文件中,以运行您想要从那里获取的项目。如果您不想通过 runsettings 文件,您可以对其进行硬编码,但我更喜欢这样做。您可以根据您选择的 runsettings 文件以这种方式进行更改。

      然后你必须定义 TestSetupHelper.GetComputerIpAddress(server, port, true);如果你对运行 Appium 服务器的计算机有一个硬编码的 IP 地址,你可以硬编码它。否则你需要一个 Helper 类(在这个例子中是 TestSetupHelper)。此示例启动到服务器的 Socket 连接并返回所有详细信息。这样您就不必担心 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;
      }
      

      这不会让你完全到达那里,但它会让你接近工作环境。然后你就可以开始着手让测试真正运行了。

      我希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2022-12-19
        • 2017-05-28
        • 2017-01-01
        • 2013-05-06
        • 2011-07-31
        • 2020-03-11
        • 2022-08-24
        • 2019-12-09
        • 2010-12-21
        相关资源
        最近更新 更多