自动化测试:Selenium webdriver 学习笔记-C#版(三)
对象定位
前面提到过如何用IE进行找元素,那么找到元素属性后,我们该如何使用呢?下面就来了解下webdriver提供的一系列的定位方法。
常见的方法有:
1>Id
IWebElement ele= driver.FindElement(By.Id("idValue")); 或者 IWebElement ele = driver.FindElementById("idValue");
2>Name
IWebElement ele= driver.FindElement(By.Name("nameValue")); 或者 IWebElement ele= driver.FindElementByName("nameValue");
3>TagName
IWebElement ele= driver.FindElement(By.TagName("xx")); 或者 IWebElement ele= driver.FindElementByTagName("xx");
4>ClassName
IWebElement ele= driver.FindElement(By.ClassName("xx")); 或者 IWebElement ele= driver.FindElementByClassName("xx");
5>CssSeletor
IWebElement ele= driver.FindElement(By.CssSeletor("xx")); 或者 IWebElement ele= driver.FindElementByCssSeletor("xx");
6>XPath
单条件 IWebElement ele= driver.FindElement(By.XPath("//xx[@id='id']")); 多条件 IWebElement ele= driver.FindElement(By.XPath("//xx[@id='id'][@id='id'][]")); 或者 IWebElement ele= driver.FindElementByXPath("//xx[@id='id']"); IWebElement ele= driver.FindElementByXPath("//xx[@id='id'][@id='id'][]"));
以上每种定位方法都有两种定位方式:FindeElement(By.xx),FindeElementByxx。他们都属于命名空间OpenQA.Selenium.Remote下的方法,只不过前者是根据(By.xx)这个对象来找,后者是根据元素的属性(Id,name...)来找。总的来讲,在这里没有太大区别。
不过,我无意中的一次发现,他们虽然在使用上都可以满足我们的需求,但是在找元素的性能上海市略有差别的。
下面是我写的一个简单的测试例子:
找百度首页的输入框
//使用FindElementByxx方法
var a = DateTime.Now.Millisecond; var searchBox1 = driver.FindElementsByName("wd"); var b = DateTime.Now.Millisecond; //使用FindElement(By.xx)方法
var c = DateTime.Now.Millisecond; var searchBox2 = driver.FindElements(By.Name("wd")); var d = DateTime.Now.Millisecond; Console.WriteLine("'FindElementByName' spent " + (b - a).ToString() + "millisecond"); Console.WriteLine("'FindElement(By.Name)' spent " + (d - c).ToString() + "millisecond");
结果如下:
不难发现使用FindElement(By) 方法找对象还是要快蛮多的,所以这里推荐使用它,但是说实话本人个人习惯喜欢用FindElementBy_xx方法,不为别的,只因为在vs上用它比较快,不知道这算不算vs一族的通病。。。
至于为什么使用FindElement(By) 方法要快这么多?本人功力有限,还待来日再研究。。。。。。嘿嘿!
对于以上几种方法,我这里暂时就不提供例子了,方法1-4很常见也很好理解的,至于5-6,后面再续。
下面我要讲的是一个有点小特殊的例子,因为我发现很多人写的blog里面都用到它(非C# 语言),但是今天我去发现这个行不通,下面就来看具体实例:
找到百度首页的搜索框,并输入搜索内容:在前面一篇里我是用FindElementById来找对象的(下面这个代码,是可以实现效果的)。
//找到对象 var searchBox = driver.FindElementById("kw1"); ...... //发送搜索内容 searchBox.SendKeys("selenium");
下面,我们用FindElementByName来实现:我们用IE的"Developer Tools" 不难发现name的值为"wd"。如是我们会用到以下代码:
1 var searchBox1 = driver.FindElementsByName("wd"); 2 ...... 3 searchBox1.SendKeys("selenium");
按理说,这个因该可以实现效果的,大家都这么写的,我也是这么认为的,但是代码运行到第3行的时候,会弹出异常:
未处理:ElementNotVisableException:Element is not displayed。
于是,对于这个异常我用了以下方法:将鼠标移动到元素上
1 var searchBox1 = driver.FindElementByName("wd"); 2 Actions builder = new Actions(driver); 3 builder.MoveToElement(searchBox1).Perform(); 4 Thread.Sleep(2000); 5 searchBox1.SendKeys("234");
结果还是异常,当获取对象的displayed属性时,发现在移动鼠标之前与移动之后它的值都是false。
var isDisplayed = searchBox1.Displayed.ToString();
于是,当我用FindElementsByName方法后,才发现问题所在(此方法:找出所有的符合条件的元素,返回ReadOnlyCollection)。
此时searchBox[1]才是我们需要的对象:
因为用FindElementByName不能唯一确定要找的对象,所以后面的操作出现异常。那么此时还是用对象的name来定位的话,应该如下:
1 var colSearchBox1 = driver.FindElementsByName("wd"); 2 colSearchBox1[1].SendKeys("123");