前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自动化测试如此容易!多语言自动化测试框架 Selenium 编程(C#篇)

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

作者头像
痴者工良
发布2023-03-11 10:11:14
3.4K0
发布2023-03-11 10:11:14
举报
文章被收录于专栏:痴者工良

介绍

Selenium 官网:https://www.selenium.dev/

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

  • Selenium WebDriver
  • Selenium IDE
  • Selenium Grid

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

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

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

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

安装依赖

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

代码语言:javascript
复制
Selenium.WebDriver

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

代码语言:javascript
复制
Selenium.WebDriver.ChromeDriver

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

第一个 demo

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

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

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

代码语言:javascript
复制
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 以加快会话加载速度。

设置方法:

代码语言:javascript
复制
var chromeOptions = new ChromeOptions();
chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
IWebDriver driver = new ChromeDriver(chromeOptions);

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

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

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

代码语言:javascript
复制
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 一段时间。一旦设置好,隐式等待就被设置为会话的生命周期。

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

代码语言:javascript
复制
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

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

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

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

代码语言:javascript
复制
WebDriverWait wait = new WebDriverWait(driver, timeout: TimeSpan.FromSeconds(30))
{
	PollingInterval = TimeSpan.FromSeconds(5),
};

代理

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

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

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

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
var chromeOptions = new ChromeOptions();

chromeOptions.BrowserVersion = "67";
chromeOptions.PlatformName = "Windows XP";

元素操作

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

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

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

文件上传

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

代码语言:javascript
复制
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 表达式匹配的元素

下面是查找元素的用例:

代码语言:javascript
复制
// 通过 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"));

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

代码语言:javascript
复制
var element = driver.SwitchTo().ActiveElement();
string attr = element.GetAttribute("title");
页面元素交互

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

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

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

代码语言:javascript
复制
var submitButton = driver.FindElement(By.TagName("button"));
submitButton.Click();
输入

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

代码语言:javascript
复制
driver.FindElement(By.Name("my-file")).SendKeys("D:/Desktop/images/学习.jpg");
清除

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

代码语言:javascript
复制
IWebElement searchInput = driver.FindElement(By.Name("q"));
searchInput.SendKeys("selenium");
// Clears the entered text
searchInput.Clear();

获取元素属性

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

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

代码语言:javascript
复制
document.getElementById("my-text-id").value
"111111111"

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

代码语言:javascript
复制
Boolean is_email_visible = driver.FindElement(By.Name("email_input")).Displayed;

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

代码语言:javascript
复制
string attr = element.GetAttribute("title");

IWebElement 的定义如下:

代码语言:javascript
复制
  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();
  }

浏览器页面

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

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

示例代码也很简单:

代码语言:javascript
复制
// 打开
driver.Navigate().GoToUrl(@"https://selenium.dev");
// 后退
driver.Navigate().Back();
// 前进
driver.Navigate().Forward();
// 刷新
driver.Navigate().Refresh();

用户登录凭证

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

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

代码语言:javascript
复制
			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 的教程就到这里,读者可到官方文档了解更多。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 安装依赖
  • 第一个 demo
  • 页面加载策略
  • 代理
  • 浏览器版本
  • 元素操作
    • 文件上传
      • 查找元素
        • 页面元素交互
          • 点击
          • 输入
          • 清除
      • 获取元素属性
      • 浏览器页面
      • 用户登录凭证
      相关产品与服务
      云服务器
      云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档