自动化测试如此容易!多语言自动化测试框架 Selenium 编程(C#篇)

简介: 自动化测试如此容易!多语言自动化测试框架 Selenium 编程(C#篇)

Selenium 是功能强大的自动化测试工具集,是支持 Web 浏览器自动化的一系列工具和库的总括项目,一共包括以下三个项目:

  • Selenium WebDriver
  • Selenium IDE
  • Selenium Grid

Selenium 的核心是 WebDriver,可以在许多浏览器中交换运行,WebDriver 以原生的方式驱动浏览器,。

WebDriver 架构设计如下:

对每种浏览器编写一个 Driver,如 ChromeDriver,这是操作浏览器的驱动,对外提供了各类操作接口。Selenium 设计了 WebDriver 抽象,以便通过统一的抽象使用各类浏览器驱动。

或者还可以远程访问接口:

下面笔者介绍在 C# 中如何使用 Selenium WebDriver 编写自动化测试程序。

安装依赖

创建一个 C# 控制台项目,首先安装依赖包 Selenium.WebDriver,这个库提供了浏览器驱动接口的基础 API 和统一抽象。

Selenium.WebDriver

接着,安装浏览器对应的驱动实现:

Selenium.WebDriver.ChromeDriver

只要搜索 Selenium.WebDriver 即可,然后根据浏览器补充后缀,下载对应的浏览器驱动。

第一个 demo

打开:https://www.selenium.dev/selenium/web/web-form.html

这个地址是官方用于测试的页面,里面有比较多的 html 组件,足够我们学习使用。

下面这个示例中,包括了打开页面、查找元素、填充内容和获取信息的代码,读者可以运行这段代码从中了解编写自动化测试程序的基本执行流程,更多的细节将在后面的小节中讲解。

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
class Program
{
  static void Main()
  {
        // 使用 ChromeDriver 驱动
    IWebDriver driver = new ChromeDriver();
    // 启动的时候打开这个页面
    driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
    // 获取页面信息
    var title = driver.Title;
    // 隐式等待,页面元素不会立马出现,需要单独一段时间
    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
    // 搜索元素
    var textBox = driver.FindElement(By.Name("my-text"));
    var submitButton = driver.FindElement(By.TagName("button"));
    // 往输入框填充文本
    textBox.SendKeys("Selenium");
    // 点击提交按钮
    submitButton.Click();
    // 点击提交按钮之后,页面会刷新,此时获取的是跳转之后的页面的元素
    var message = driver.FindElement(By.Id("message"));
    var value = message.Text;
    // 退出
    driver.Quit();
  }
}

注意:demo 程序启动时,会启动 Chrome 浏览器,如果启动浏览器太慢,demo 程序会报错退出。

因此需要先启动 Chrome 浏览器,再启动 demo 程序,以便减少 Chrome 浏览器新窗口的启动时间。

demo 程序启动后,会自动填充表单和提交,接着跳转到新的页面。

页面加载策略

页面开发模式有多种多样,如 PHP、asp 这种一体式开发,如服务器渲染然后返回整个页面、前后端分离先加载静态资源然后从后端 API 中加载数据生成页面。

很多时候,页面不会短时间完成渲染,有些页面元素需要一段时间后才能出现。在使用 WebDriver 的时候,我们也可以根据需求决定在什么时候启动自动化操作。

页面有三种基本加载策略:

策略 就绪状态 备注
normal complete 默认值,,等待所有资源下载
eager interactive DOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载。
none Any 完全不会阻塞 WebDriver,WebDriver 仅等待初始页面已下载。

如果由于下载对自动化不重要的资源(例如, 图像、css、js) 而需要很长时间才能加载页面,,可以将默认参数 normal 更改为 eagernone 以加快会话加载速度。

设置方法:

var chromeOptions = new ChromeOptions();
chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
IWebDriver driver = new ChromeDriver(chromeOptions);

另外,WebDriver 提供了三种方式等待页面元素的出现:

  • 显式等待
  • 隐式等待
  • 流畅等待

我们可以使用等待来让 findElement 调用等待直到脚本中动态添加的元素被添加到DOM中:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement firstResult = wait.Until(e => e.FindElement(By.XPath("//a/h3")));

这种方法称为显式等待

WebDriver 会等待路径 //a/h3 的元素出现,最大等待时间为 10s。

而通过隐式等待,WebDriver 在试图查找_任何_元素时在一定时间内轮询DOM。当网页上的某些元素不是立即可用并且需要一些时间来加载时是很有用的。

隐式等待是告诉 WebDriver 如果在查找一个或多个不是立即可用的元素时轮询 DOM 一段时间。一旦设置好,隐式等待就被设置为会话的生命周期。

设置隐式等待的轮询时间:

driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

警告: 不要混合使用隐式和显式等待。这样做会导致不可预测的等待时间。例如,将隐式等待设置为10秒,将显式等待设置为15秒,可能会导致在20秒后发生超时。

流畅等待 定义了等待条件的最大时间量,以及检查条件的频率。

用户可以配置等待来忽略等待时出现的特定类型的异常,例如在页面上搜索元素时出现的NoSuchElementException

WebDriverWait wait = new WebDriverWait(driver, timeout: TimeSpan.FromSeconds(30))
{
  PollingInterval = TimeSpan.FromSeconds(5),
};

代理

代理服务器充当客户端和服务器之间的请求中介,使用代理服务器用于 Selenium 的自动化脚本, 可能对以下方面有益:

  • 捕获网络流量
  • 模拟网站后端响应
  • 在复杂的网络拓扑结构或严格的公司限制/政策下访问目标站点.

如果在公司环境中,或者需要开启飞机上网,浏览器无法连接到 URL,则需要借助代理进行访问。

Selenium WebDriver 提供了如下设置代理的方法,代码示例如下:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
class Program
{
  static void Main()
  {       
    ChromeOptions options = new ChromeOptions();
    Proxy proxy = new Proxy();
    proxy.Kind = ProxyKind.Manual;
    proxy.IsAutoDetect = false;
    proxy.SslProxy = "<HOST:PORT>";
    options.Proxy = proxy;
    options.AddArgument("ignore-certificate-errors");
    IWebDriver driver = new ChromeDriver(options);
    driver.Navigate().GoToUrl("https://www.selenium.dev/");
  }
}

浏览器版本

例如, 假设想使用 Chrome 版本 67 在 Windows XP 上运行 Chrome:

var chromeOptions = new ChromeOptions();
chromeOptions.BrowserVersion = "67";
chromeOptions.PlatformName = "Windows XP";

元素操作

元素操作主要分为下面这几种:

  • 文件上传
  • 查询网络元素:根据提供的定位值定位元素
  • Web元素交互:用于操纵表单的高级指令集
  • 定位策略:在 DOM中 标识一个或多个特定元素的方法
  • 元素的信息:html 元素的属性

下面来介绍不同 html 元素的操作方法示例。

文件上传

上传文件实际上是在 type=fileinput 标签中,填写本地路径的文件地址,这个地址需要填写文件的绝对路径。

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumPRs
{
  class FileUploadExample
  {
    static void Main(String[] args)
    {
      IWebDriver driver = new ChromeDriver();
      try
      {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
        // 文件路径一定是可以存在的,不能乱填,建议绝对路径
        driver.FindElement(By.Name("my-file")).SendKeys("D:/Desktop/images/学习.jpg");
        var submitButton = driver.FindElement(By.TagName("button"));
        submitButton.Click();
        if (driver.PageSource.Contains("File Uploaded!"))
        {
          Console.WriteLine("file uploaded");
        }
        else
        {
          Console.WriteLine("file not uploaded");
        }
        driver.Quit();
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex);
      }
    }
  }
}

查找元素

在 WebDriver 中有 8 种不同的内置元素定位策略:

定位器 Locator 描述
class name 定位class属性与搜索值匹配的元素(不允许使用复合类名)
css selector 定位 CSS 选择器匹配的元素
id 定位 id 属性与搜索值匹配的元素
name 定位 name 属性与搜索值匹配的元素
link text 定位link text可视文本与搜索值完全匹配的锚元素
partial link text 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。
tag name 定位标签名称与搜索值匹配的元素
xpath 定位与 XPath 表达式匹配的元素

下面是查找元素的用例:

// 通过 id 或 name
IWebElement vegetable = driver.FindElement(By.ClassName("tomatoes"));
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
// 通过 css 选择器
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
// 返回多个元素
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));

获取当前页面的焦点在哪个元素:

var element = driver.SwitchTo().ActiveElement();
string attr = element.GetAttribute("title");

页面元素交互

仅有五种基本命令可用于元素的操作:

  • 点击 (适用于任何元素)
  • 发送键位 (仅适用于文本字段和内容可编辑元素,.SendKeys())
  • 清除 (仅适用于文本字段和内容可编辑元素)
  • 提交 (仅适用于表单元素)(在Selenium 4中不再建议使用)
  • 选择(查找元素)
点击

可以触发元素的点击事件:

var submitButton = driver.FindElement(By.TagName("button"));
submitButton.Click();
输入

元素发送键位命令,即 .SendKeys() ,这个方法对可编辑的元素都通用,如 input、select 等元素。

driver.FindElement(By.Name("my-file")).SendKeys("D:/Desktop/images/学习.jpg");
清除

对于可编辑文本或具有输入的元素,如文本域、选择框、文件上传框的,可以清除元素当前的value 属性。

IWebElement searchInput = driver.FindElement(By.Name("q"));
searchInput.SendKeys("selenium");
// Clears the entered text
searchInput.Clear();

获取元素属性

  • 是否显示
  • 是否启用
  • 是否被选定
  • 获取元素标签名
  • 位置和大小
  • 获取元素CSS值
  • 文本内容
  • 获取特性或属性

在 JS 中,我们可以这样获取一个元素的值或其它属性:

document.getElementById("my-text-id").value
"111111111"

在 WebDriver 中可以通过 IWebElement 接口的 字段/属性 获取元素属性,但不多:

Boolean is_email_visible = driver.FindElement(By.Name("email_input")).Displayed;

其它需要的属性可以通过 GetAttribute 等方法获取,如:

string attr = element.GetAttribute("title");

IWebElement 的定义如下:

public interface IWebElement : ISearchContext
  {
    string TagName { get; }
    string Text { get; }
    bool Enabled { get; }
    bool Selected { get; }
    Point Location { get; }
    Size Size { get; }
    bool Displayed { get; }
    void Clear();
    void SendKeys(string text);
    void Submit();
    void Click();
    string GetAttribute(string attributeName);
    string GetDomAttribute(string attributeName);
    string GetDomProperty(string propertyName);
    string GetCssValue(string propertyName);
    ISearchContext GetShadowRoot();
  }

浏览器页面

对于浏览器页面的操作,无外乎下面四种:

  • 打开网站
  • 后退
  • 前进
  • 刷新

示例代码也很简单:

// 打开
driver.Navigate().GoToUrl(@"https://selenium.dev");
// 后退
driver.Navigate().Back();
// 前进
driver.Navigate().Forward();
// 刷新
driver.Navigate().Refresh();

用户登录凭证

目前只发现了使用 Basic、Cookie 两种登录认证方式, JWT Token 这种需要设置 Header 头的方式找不到实现。

下面是使用 Cookie 打开网页的示例:

var chromeOptions = new ChromeOptions();
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try
      {
        driver.Navigate().GoToUrl("https://www.google.com");
        // Adds the cookie into current browser context
        driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");
        // Get attribute of current active element
        var btnK = driver.FindElement(By.Name("btnK"));
        btnK.Click();
      }
      finally
      {
        driver.Quit();
      }

关于使用 C# 开发 Selenium WebDriver 的教程就到这里,读者可到官方文档了解更多。

相关文章
|
2天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的前沿技术:AI与自动化的融合
在数字化时代的浪潮中,软件测试领域正经历着前所未有的变革。本文深入探讨了人工智能(AI)和自动化技术如何重塑软件测试的未来。通过分析最新的行业报告、案例研究和专家访谈,我们揭示了这些技术如何提升测试效率、准确性和灵活性。文章还讨论了实施这些技术的可能挑战和解决方案,为读者提供了宝贵的行业见解和实用建议。
20 6
|
6天前
|
敏捷开发 监控 测试技术
自动化测试框架的演进与实践
【7月更文挑战第19天】随着软件开发行业的飞速发展,自动化测试已成为确保软件质量的重要手段。本文将探讨自动化测试框架的发展历程,从早期的线性脚本到现代的模块化框架,以及它们如何适应敏捷开发和持续集成的需求。同时,我们还将深入分析几种流行的自动化测试工具,并讨论如何在实际项目中有效实施自动化测试策略。
|
6天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来:AI与自动化的融合之路
【7月更文挑战第19天】在数字化时代的浪潮中,软件测试领域正经历着前所未有的变革。随着人工智能(AI)技术的飞速发展和自动化测试工具的不断进步,传统的测试方法正在被重新定义。本文将深入探讨AI如何赋能软件测试,提升测试效率和质量,以及自动化测试在未来软件生命周期中的角色和挑战,为读者揭示一个智能化、高效率的软件测试新纪元。
|
2天前
|
机器学习/深度学习 人工智能 算法
探索软件测试的未来趋势:AI与自动化的融合
在技术不断演进的今天,软件测试领域正经历着前所未有的变革。本文将深入探讨人工智能(AI)和自动化技术如何重塑软件测试的面貌,从智能化测试用例生成到持续集成中的自动缺陷识别,我们将揭示这些技术如何提高测试效率、准确性和覆盖率。通过具体案例分析,本文旨在为读者提供对未来软件测试趋势的洞见,并讨论实施过程中的挑战与机遇。
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
软件测试的未来趋势:AI与自动化的融合
随着技术的不断进步,软件测试领域正迎来一场革命。本文将探讨人工智能(AI)和自动化技术如何共同推动软件测试的发展,提高测试效率,减少人为错误,并预测未来的发展趋势。通过分析当前市场上流行的测试工具和方法,以及它们如何整合AI和自动化技术,我们将揭示这一领域即将迎来的变革。
10 2
|
3天前
|
测试技术
测试过程中如何有效利用自动化测试
测试过程中如何有效利用自动化测试
|
3天前
|
机器学习/深度学习 人工智能 测试技术
软件测试的未来:自动化与人工智能的融合
随着技术的不断进步,软件测试领域正经历着一场变革。传统的手动测试方法正在逐渐被自动化测试所取代,而人工智能(AI)的引入则进一步推动了这一进程。本文将探讨自动化测试的现状和未来发展趋势,以及AI如何与自动化测试相结合,提高测试效率和质量。我们将通过具体的案例和数据来展示自动化和AI在软件测试中的应用,并讨论这一趋势对测试人员技能要求的影响。
12 1
|
1天前
|
机器学习/深度学习 人工智能 测试技术
软件测试的未来:自动化与人工智能的融合
本文将探讨软件测试领域的未来趋势,特别是自动化和人工智能(AI)如何共同塑造这一领域。我们将分析当前的挑战、技术进步以及这些变化如何影响测试工程师的角色和职责。通过具体的统计数据和案例研究,本文旨在为读者提供深入的技术洞察和行业前景预测。
|
8天前
|
测试技术 API Android开发
《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)
【7月更文挑战第15天】这是关于自动化测试框架中Selenium API二次封装的教程总结。教程中介绍了如何设计一个支持不同浏览器测试的页面基类(BasePage),该基类包含了对Selenium方法的二次封装,如元素的输入、点击、清除等常用操作,以减少重复代码。此外,页面基类还提供了获取页面标题和URL的方法。
24 2
|
9天前
|
Web App开发 XML Java
《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)
【7月更文挑战第14天】这篇教程介绍了如何使用Java和Selenium构建一个支持跨浏览器测试的自动化测试框架。设计的核心是通过读取配置文件来切换不同浏览器执行测试用例。配置文件中定义了浏览器类型(如Firefox、Chrome)和测试服务器的URL。代码包括一个`BrowserEngine`类,它初始化配置数据,根据配置启动指定的浏览器,并提供关闭浏览器的方法。测试脚本`TestLaunchBrowser`使用`BrowserEngine`来启动浏览器并执行测试。整个框架允许在不同浏览器上运行相同的测试,以确保兼容性和一致性。
21 3