.NET项目web自动化测试实战——Selenium 2.0

news2024/11/15 17:44:45

🔥 交流讨论:欢迎加入我们一起学习!

🔥 资源分享耗时200+小时精选的「软件测试」资料包

🔥 教程推荐:火遍全网的《软件测试》教程  

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

PS:这次用公司的项目来练手,希望公司不会起诉我,因为我绝对是抱着学习的态度,没有任何恶意。仅供交流学习。

该项目是基于SharePoint平台所开发的门户网站,为了切身感受一下Selenium 2.0我决定自己动手写一个自动化测试用例,而不是通过录制的方式,以加深我对一些web操作的理解。

我设计的测试用例是:检查Staff Spotlight中所包含的item对应三级页面显示的信息是否正确。具体逻辑是,在英语浏览器下检查后台list中英语Column的value和三级page中对应Column的value是否一致,在日语浏览器下检查后台list中日语Column的value和三级page中对应Column的value是否一致,如果是英语浏览器下后台list中没有勾选“English Ready”项,则在三级page中显示日语Column的value。

三级page如下:

点击页面右上角的“Edit Item”按钮可以跳转到后台list中相应的item编辑页面;点击上方的“日本语”按钮可以进行英语和日语的语言切换,点击“日本语”将切换到日本语,再点击“English”将切换到英语。

我们本次要取的页面元素就是Department,Location,Title以及Join Date的页面value。然后点击“Edit Item”按钮跳转到后台item编辑页面,按“F12”,找到对应要获取的后台元素值:

获取到对应的Column的value所在页面的元素,然后获取页面上显示的值,将其与三级page上的value按我们之前说过的逻辑进行比对,如果一样,测试通过;如果不一样,测试失败。

代码如下:

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support;
using OpenQA.Selenium.Support.UI;
using Selenium;
using mySelenium;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Globalization;

namespace mySelenium
{
    class LoginSPSite
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();
        static void Main(string[] args)
        {
            IWebDriver driver = new InternetExplorerDriver();
            IWebDriver iw = login(driver,"https://insite.ccqa11apps.com/Pages/default.aspx");
            INavigation navi = iw.Navigate();
            string language = checkLanguage(iw);
            if (language == "English")
            {
                //Check the English page.(检查英语页面信息。)
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("--English page check--");
                checkPageInfo(iw,"En");
                //Turn to the Japanese page.(转换到日语页面。)
                navi.GoToUrl("https://insite.ccqa11apps.com/Pages/default.aspx");
                waitUntilPageLoaded(iw, "ctl00_ctl21_ToggleLanguage");
                iw.FindElement(By.Id("ctl00_ctl21_ToggleLanguage")).Click();
                //Check the Japanese page.(检查日语页面信息。)
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("--Japanese page check--");
                checkPageInfo(iw,"Ja");
            }
            //Language is "Japanese".
            else 
            {
                //Check the Japanese page.(检查日语页面信息。)
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("--Japanese page check--");
                checkPageInfo(iw,"Ja");
                //Turn to the English page.(转换到英语页面。)
                navi.GoToUrl("https://insite.ccqa11apps.com/Pages/default.aspx");
                waitUntilPageLoaded(iw, "ctl00_ctl21_ToggleLanguage");
                iw.FindElement(By.Id("ctl00_ctl21_ToggleLanguage")).Click();
                //Check the English page.(检查英语页面信息。)
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("--English page check--");
                checkPageInfo(iw, "En");
            }
        }//Get the 3rd page info.(从三级page中获取指定的Column的value,需要传入IWebDriver对象以及当前页面的语言种类。)
        private static void checkPageInfo(IWebDriver iw,string LanType)
        {
            //Check 3rd page with the format: "https://insite.ccqa11apps.com/_layouts/15/InSite/pages/StaffDetails.aspx?id=" under the English environment.
            INavigation navi = iw.Navigate();
            for (int i = 1; i <= 5; i++)
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("This is the " + i + " staff item check info:");
                navi.GoToUrl("https://insite.ccqa11apps.com/_layouts/15/InSite/pages/StaffDetails.aspx?id=" + i.ToString());
                var eles = iw.FindElements(By.ClassName("apps-staffdetail-content-splitline"));
                //Get the info from the 3rd page.(获取三级page上Column的value信息。)
                StaffSpotlight staffSpotlight = new StaffSpotlight();
                staffSpotlight.Department = eles[0].FindElement(By.ClassName("apps-staffdetail-content-splitline-bottom")).Text;
                staffSpotlight.Location = eles[1].FindElement(By.ClassName("apps-staffdetail-content-splitline-bottom")).Text;
                staffSpotlight.Title = eles[2].FindElement(By.ClassName("apps-staffdetail-content-splitline-bottom")).Text;
                staffSpotlight.JoinDate = eles[3].FindElement(By.ClassName("apps-staffdetail-content-splitline-bottom")).Text;
                //Find the "Edit Item" button.(找到“Edit Item”按钮并点击。)
                iw.FindElement(By.ClassName("apps-staffdetail-edit")).Click();
                //Wait until the element on page loaded.(等待页面元素加载完成。)
                waitUntilPageLoaded(iw, "Inpex_Department_$containereditableRegion");
                //Get the info from the backend list.(获取后台list中Column的value信息。)
                StaffSpotlight staffInfoFromBackend = new StaffSpotlight();
                staffInfoFromBackend.Department = iw.FindElement(By.Id("Inpex_Department_$containereditableRegion")).FindElement(By.ClassName("valid-text")).Text;
                staffInfoFromBackend.Location = iw.FindElement(By.Id("Inpex_Office_$containereditableRegion")).FindElement(By.ClassName("valid-text")).Text;
                //Job title is the title under English IE.(Title是日语浏览器中显示的Title,EnTitle是英语浏览器中显示的Title。)
                staffInfoFromBackend.Title = iw.FindElement(By.Id("Inpex_Job_Title_30756774-5931-4844-bac1-a2f463d04ca0_$TextField")).GetAttribute("value").ToString();
                staffInfoFromBackend.EnTitle = iw.FindElement(By.Id("Inpex_Job_Title_E_ef6d11a7-f73e-4885-bef1-527a1c03c924_$TextField")).GetAttribute("value").ToString();
                staffInfoFromBackend.JoinDate = iw.FindElement(By.Id("Inpex_Join_Date_b133dcfe-4e0c-4f0f-8b82-92a549516e6d_$DateTimeFieldDate")).GetAttribute("value").ToString();
                //Compare the actual 3rd info with the expected backend info.(将三级page中的Column value和预期value比较。)
                Compare("Department", staffSpotlight.Department, staffInfoFromBackend.Department);
                Compare("Location", staffSpotlight.Location, staffInfoFromBackend.Location);
          //英语页面的Title信息比对检查逻辑。
                if (LanType == "En")
                {
                    try
                    { 
                        //If can get the element underneath, it means "English Ready" has been checked.(如果可以在页面上获取到该元素,说明“English Ready”这一项是勾选的。)
                        string ifChecked = iw.FindElement(By.Id("Inpex_E_Text_a355a229-a1bb-48f5-81dd-e428a0d4fbd2_$BooleanField")).GetAttribute("checked").ToString();
                        Console.WriteLine("The Englisht ready has been checked: " + ifChecked);
                        //Compare the title with the backend "En" one.(比对EnTitle和三级page中的Column value是否一致。)
                        Compare("Title", staffSpotlight.Title, staffInfoFromBackend.EnTitle);
                    }
                    //If can not get the element by the ID above, it means "English Ready" has not been checked.(如果获取不到“English Ready”元素下的“checked” Attribute,说明没勾选。)
                    catch(Exception ex)
                    {
                        WriteLog(ex);
                        //Compare the title with the backend "Jp" one.(比对Title和三级page中的Column value是否一致。)
                        Console.WriteLine("The Englisht ready has been checked: false");
                        Compare("Title", staffSpotlight.Title, staffInfoFromBackend.Title);
                    }          
                }
          //日语页面的Title信息比对检查逻辑。
                else 
                {
                    staffInfoFromBackend.Title = iw.FindElement(By.Id("Inpex_Job_Title_30756774-5931-4844-bac1-a2f463d04ca0_$TextField")).GetAttribute("value").ToString();
                    Compare("JapTitle", staffSpotlight.Title, staffInfoFromBackend.Title);
                }
                //Change the time format into the same.(统一转换三级page上的join date时间格式以及后台list item的join date时间格式,并进行比较。)
                string joinDateOnPage;
                string joinDateFromBackend;
                if (staffSpotlight.JoinDate != "")
                {
                    DateTime dt = Convert.ToDateTime(staffSpotlight.JoinDate);
                    joinDateOnPage = dt.ToString("yyyy-MM-dd");
                }
                else 
                {
                    joinDateOnPage = "";
                }
                if (staffInfoFromBackend.JoinDate != "")
                {
                    DateTime dt2 = Convert.ToDateTime(staffInfoFromBackend.JoinDate);
                    joinDateFromBackend = dt2.ToString("yyyy-MM-dd");
                }
                else 
                {
                    joinDateFromBackend = "";
                }
                Compare("JoinDate", joinDateOnPage, joinDateFromBackend);
            }
        }
     //Compare value method.(传入:对应要检查的Column的标题,三级page中Column的value,后台list中item对应Column的value。)
        private static void Compare(string title, string p1, string p2)
        {
            if (p1 == p2)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(title + " info on the 3rd page has passed the check.");
            }
            else 
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(title + "info on the 3rd page has not passed the check.");
                Console.WriteLine("The info on the 3rd page: " + p1);
                Console.WriteLine("The info from the backend page: " + p2);
            }
        }
        //Check language method.(检查当前页面所处于的语言环境,判断是英语还是日语,并返回当前语言种类。)
        private static string checkLanguage(IWebDriver iw)
        {
            string currentLanguage;
            //Wait until the element on page loaded.
            waitUntilPageLoaded(iw, "ctl00_ctl21_ToggleLanguage");
            string language = iw.FindElement(By.Id("ctl00_ctl21_ToggleLanguage")).Text;
            if (language.Length == 3)
            {
                currentLanguage = "English";
                return currentLanguage;
            }
            else 
            {
                currentLanguage = "Japanese";
                return currentLanguage;
            }
        }
        //Wait until loaded method.(等待网页加载完毕指定元素,如果没有加载完,获取不到,捕获异常,继续等待,直到指定元素加载完毕。)
        private static void waitUntilPageLoaded(IWebDriver iw, string element)
        {
            try
            {
                iw.FindElement(By.Id(element));
            }
            catch (Exception ex)
            {
                WriteLog(ex);
                Thread.Sleep(2000);
                waitUntilPageLoaded(iw, element);
            }
        }
        //Login method.(登陆网站的方法,需要传入IWebDriver对象以及网站的url。)
        public static IWebDriver login(IWebDriver driver, string url) 
        {
            INavigation navigation = driver.Navigate();
            navigation.GoToUrl(url);
            driver.FindElement(By.Id("overridelink")).Click();
            IntPtr myPtr = GetForegroundWindow();
            //IntPtr hWnd = FindWindow(null, "abc");
            if (myPtr != IntPtr.Zero)
            {
                //Send message to the window.
                System.Windows.Forms.SendKeys.SendWait("dswu");
                System.Windows.Forms.SendKeys.SendWait("{TAB}");
                System.Windows.Forms.SendKeys.SendWait("1qaz2wsxE");
                System.Windows.Forms.SendKeys.SendWait("{ENTER}");
            }
            return driver;
        }
        //Write log method.(将捕获到的异常打印到本地log文件中。)
        private static void WriteLog(Exception ex)
        {
            string logUrl = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\SeleniumAutoTest.txt";
            if (File.Exists(@logUrl))
            {
                using (FileStream fs = new FileStream(logUrl, FileMode.Append))
                {
                    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                    {
                        try
                        {
                            sw.Write(ex);
                        }
                        catch (Exception ex1)
                        {
                            WriteLog(ex1);
                        }
                        finally
                        {
                            sw.Close();
                            fs.Close();
                        }
                    }
                }
            }
            else
            {
                using (FileStream fs = new FileStream(logUrl, FileMode.CreateNew))
                {
                    using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                    {
                        try
                        {
                            sw.Write(ex);
                        }
                        catch (Exception ex1)
                        {
                            WriteLog(ex1);
                        }
                        finally
                        {
                            sw.Close();
                            fs.Close();
                        }
                    }
                }
            }
        }
    }
}

复制代码

这里我创建一个类,用来存储三级page以及后台list中获取到的Staff item的信息:

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace mySelenium
{
    class StaffSpotlight
    {
        public string Department { get; set; }
        public string Location { get; set; }
        public string Title { get; set; }
        public string EnTitle { get; set; }
        public string JoinDate { get; set; }
    }
}

复制代码

按F5进行测试,结果如下:

测试通过。

覆盖多浏览器在Selenium也是很容易实现的,只需要把IE打开方法改用为指定浏览器所对应的打开方法:

 IWebDriver driver = new InternetExplorerDriver(); 

把这句换了,之后的步骤对应做些修改即可。

自动化测试从某些方面讲确实是一劳永逸的,但是有很多时候自动化测试是完全没有必要的,尤其是项目周期很短的情况下,自动化的封装应该更偏向于具有普遍性的可复用过程,而不是业务逻辑。

有时候,产出决定付出。我们没必要为了一个两三月交付的项目写一堆自动化测试用例,否则得不偿失。自动化测试应该更偏向于长期上线、持续迭代的项目展开!否则最后失落感是一定有的。

最后我邀请你进入我们的【软件测试学习交流群:785128166】, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1463809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

猫头虎分享已解决Bug || Web服务故障:WebServiceUnavailable, HTTPServerError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

网络安全“降本增笑”的三大帮手

在网络安全这个快速变化和危机四伏的领域中&#xff0c;通过使用正确的工具和方法&#xff0c;我们可以在工作中取得更高的效率&#xff0c;并降低相关成本。 雷池社区版 雷池社区版—开源Web应用防火墙。这款产品凭借强大的规则引擎&#xff0c;它允许用户自定义安全策略&…

钡铼技术的LoRa网关实现智能电网监测与控制

钡铼技术的LoRa网关在智能电网监测与控制方面发挥着关键作用&#xff0c;为电力系统的安全运行和高效管理提供了重要支持。下面将详细介绍钡铼技术的LoRa网关如何实现智能电网监测与控制。 首先&#xff0c;钡铼技术的LoRa网关通过接入各类传感器和监测设备&#xff0c;实现对…

ESP8266智能家居(2)——8266发布数据到mqtt服务器

1.公共服务器 学习物联网就离不开服务器&#xff0c;如果你资金充足的话&#xff0c;可以自己购买或者租用一个服务器。本次我选择&#xff0c;使用免费的公共MQTT服务器。它的端口及Broker信息如下&#xff1a; 网址为&#xff1a; 免费的公共 MQTT 服务器 | EMQ (emqx.com)h…

分享:大数据信用查询去什么样的平台查?

在当今社会&#xff0c;大数据信用查询已经成为企业和个人了解自身信用状况的重要途径。然而&#xff0c;面对众多的大数据信用查询平台&#xff0c;如何选择一个可靠的平台进行查询呢?本文将为您介绍一些选择大数据信用查询平台的关键因素。 一、平台信誉度 首先&#xff0c;…

面试redis篇-01开篇

使用场景 Redis的数据持久化策略有哪些什么是缓存穿透&#xff0c;怎么解决什么是布隆过滤器什么是缓存击穿&#xff0c;怎么解决什么是缓存雪崩&#xff0c;怎么解决redis双写问题Redis分布式锁如何实现Redis实现分布式锁如何合理的控制锁的有效时长Redis的数据过期策略有哪些…

《Solidity 简易速速上手小册》第2章:搭建 Solidity 开发环境(2024 最新版)

文章目录 2.1 安装和配置 Solidity2.1.1 基础知识解析安装 Solidity 编译器配置开发环境熟悉命令行工具2.1.2 重点案例:配置本地开发环境案例 Demo:配置本地 Solidity 环境案例代码:HelloWorld.sol2.1.3 拓展案例 1:设置 Remix IDE案例 Demo:在 Remix IDE 中编写和测试智能…

基于springboot vue的MOBA类游戏攻略分享平台源码和论文

基于springboot vue的MOBA类游戏攻略分享平台源码和论文390

linux逻辑卷/dev/mapper/centos-root扩容增加空间

centos7中/dev/mapper/centos-root扩容 问题文件系统根目录&#xff0c;/dev/mapper/centos-root空间满了&#xff0c;导致k8s不停重启 1.查看磁盘情况 df -h #查看最大占用目录 du -h -x --max-depth12.查看磁盘信息 fdisk -l3.查看磁盘分区层级 lsblk4.新建分区 在/dev…

嵌入式Qt 计算器核心算法_3

一.后缀表达式实现算数运算思路 二.算法实现 #include "QCalculatorDec.h"QCalculatorDec::QCalculatorDec() {m_exp "";m_result ""; }QCalculatorDec::~QCalculatorDec() {}bool QCalculatorDec::isDigitOrDot(QChar c) {return ((0 < c)…

【人工智能学习思维脉络导图】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 知识图谱1. 基础知识2.人工智能核心概念3.实践与应用4.持续学习与进展5.挑战与自我提升6.人脉网络 知识图谱 人工智能学习思维脉络导图 1. 基础知识 计算机科学基础数学基础&#xff08;线性代数、微积分、概率论和统计学…

CapCut - 剪映国际版11.1.0

​【应用名称】&#xff1a;CapCut - 剪映国际版 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#CapCut #剪映国际版 【应用版本】&#xff1a;11.1.0 【应用大小】&#xff1a;231MB 【软件说明】&#xff1a;软件升级更新。目前大家广泛使用的最令人惊叹、最专…

【MySQL初阶】索引与事务

1. 索引 1.1 索引基本概念 1.1.1 索引介绍 索引(index)&#xff1a;是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或者多列创建索引&#xff0c;并指定索引的类型&#xff0c;各类索引有各自的数据结构实现。&#xff08;具体细节在My…

Kafka3.x进阶

来源&#xff1a;B站 目录 Kafka生产者生产经验——生产者如何提高吞吐量生产经验——数据可靠性生产经验——数据去重数据传递语义幂等性生产者事务 生产经验——数据有序生产经验——数据乱序 Kafka BrokerKafka Broker 工作流程Zookeeper 存储的 Kafka 信息Kafka Broker 总…

SDWAN组网基于软件,部署灵活且周期

在当今数字化时代&#xff0c;企业网络架构面临着日益复杂的挑战。传统的硬件路由器和专线连接已经不能满足企业对网络带宽、灵活性和安全性的需求。SD-WAN组网作为一种新兴的网络架构技术&#xff0c;通过基于软件的虚拟化和智能路由功能&#xff0c;为企业提供了部署灵活且周…

“警示”!中国大连证监局等七部门紧急发文:防范虚拟货币非法集资!受害人主要为中老年群体?

“国家发行了一种数字货币&#xff0c;一个人只能买一单&#xff0c;一单1000元&#xff0c;到年底时保底能赚回来5万元”……如此拙劣的骗局&#xff0c;6年间让超过1万名受害人上当。 2023年下半年&#xff0c;福建省漳州市公安机关成功打掉这一诈骗犯罪团伙&#xff0c;查明…

一样的代码不同项目跳转页面报404的解决办法

今天收到实施反馈的一个问题&#xff0c;点项目名称跳转项目详情页面时&#xff0c;有的页面跳转显示正常&#xff0c;有的页面跳转报404错误。错误如下&#xff1a; 发现报错的项目都有一个共性就是有特殊字符“[ ]” , 解决的办法就是把带有特殊字符的字段 用 encodeURI()…

HarmonyOS Stage模型基本概念讲解

本文 我们来说harmonyos中的一种应用模型 Stage模型 官方提供了两种模型 一种是早期的 FA模型 另一种就是就是 harmonyos 3.1才开始的新增的一种模型 Stage模型 目前来讲 Stage 会成为现在乃至将来 长期推进的一种模型 也就是 无论是 现在的harmonyos 4.0 乃至 之后要发布的 …

LeetCode.106. 从中序与后序遍历序列构造二叉树

题目 106. 从中序与后序遍历序列构造二叉树 分析 前面讲过根据前序和中序构建二叉树&#xff1a;博客链接 这道题是告诉我们一颗二叉树的后序和中序&#xff0c;让我们根据后序和中序构造出整颗二叉树。 拿到这道题&#xff0c;我们首先要知道中序的后序又怎样的性质&#…

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测 目录 时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间…