1、在SE的执行过程中,一般都会有如下一行代码,代表着引入webdriver模板:
from selenium import webdriver
因为我用的是Chrome浏览器来进行自动化测试,那么会通过webdriver.Chrome()方法对webdriver进行实例化:
driver = webdriver.Chrome()
2、因为我们也可以用其他的浏览器,比如火狐FireFox,所以点击webdriver进入一个__init__.py的文件,可以看到有多个浏览器对应的webriver在这里做了个重命名,如下图所示:
3、点击上图中的“.chrome.webdriver”中的“webdriver”就会打开一个webdriver.py文件,可以看到他的初始化方法:
(1)其中executable_path的值就是对应我们安装时,环境变量配置的chromedriver文件的路径名称(默认),我的是在D盘,如下图所示:
(2)要注意的是两者的名称必须相同,如果说我把D盘下的chromewebdriver.exe重命名,那么就会报错。当然,也可以把配置的那个文件路径全部写入Chrome()方法中,代码如下:
driver = webdriver.Chrome(executable_path='D:\ChromeDriver\chromedriver.exe')
或
driver = webdriver.Chrome(r'D:\ChromeDriver\chromedriver.exe')
(3)如果还要设置Chrome()方法中的其他参数,也可以用(参数1=值1,参数2=值2...参数N=值N)得方式去设置。参数的释义如下:
executable_path 可执行文件的路径。如果使用默认值,则假定可执行文件位于$PATH中
port 希望服务运行的端口,如果保留为0,则会找到一个空闲端口。
options ChromeOptions的一个实例
service_args 要传递给驱动程序服务的参数列表
desired_capabilities 字典对象与非浏览器特定仅限功能,如“proxy”或“loggingPref”。
service_log_path 从驱动程序记录信息的位置
chrome options 选项的参数,已弃用
keep alive 是否将Chrome远程连接配置为使用HTTP keep alive。
4、那么当我们设置之后,又是怎么调用的呢?在webdriver.py文件里面我们会看到有这样一段代码:
self.service = Service(
executable_path,
port=port,
service_args=service_args,
log_path=service_log_path)
self.service.start()
可以看到的是,这里实例化了一个Service,调用了它的start()方法,查看start()方法则可以看到在这里利用的是进程间的调用,即利用子进程subprocess调用了Popen方法,把chromedriver(也就是源码中的“cmd”)传过去,代码如下图所示:
self.process = subprocess.Popen(cmd, env=self.env,
close_fds=platform.system() != 'Windows',
stdout=self.log_file,
stderr=self.log_file,
stdin=PIPE)
因此我们也可以直接写一个方法去代替webdriver.Chrome()达到实例化SE的效果,如下面的代码所示:
def test():
import subprocess
p = subprocess.Popen("chromedriver") #把chromedriver传进去
p.communicate() #调用进程间的通信方法
同样地,我们是把chromedriver作为参数放入subprocess的Popen方法中,执行后成功打开了Chrome浏览器,具体见下图:
当然,比起“webdriver.Chrome()”,两者还是有区别的,区别在于webdriver.Chrome()方法可以设置更多的参数,这就是SE实例化的主要内容。
(1)工程师编写自动化测试代码(Python、Java等多种语言不限),通过http协议把代码发送给浏览器驱动;
(2)浏览器驱动里面有个Http Server,它根据特定的端口号(port)监听到请求,对代码进行解析,再发送指令给浏览器;
(3)浏览器接收到后根据指令执行操作,执行完之后再把执行结果反馈给驱动;
(4)浏览器驱动再把结果返回给客户端,如果说是错误的http代码,那么也会把相应的报错信息显示在控制台。
具体图示如下:
要注意的是,API和浏览器驱动是一个C/S架构,也就是说客户机与服务器,客户端产生的每一条Selenium脚本,都会创建一个http请求发送给浏览器驱动。
为什么客户端的语言既可以用Java,也可以是Python呢?同一个驱动即可以接受Java请求,也可以接受Python请求?
因为WebDriver使用的是一个公共遵循的协议:Json Wire protocol,且通信格式也是Json。