今天大家介绍一些Python自动化测试中常见的面试题,涵盖了Python基础、测试框架、测试工具、测试方法等方面的内容,希望能够帮助你提升自己的水平和信心。
项目相关
- 什么项目适合做自动化测试?
答:一般来说,适合做自动化测试的项目应该满足以下几个条件:
- 项目需求稳定,变更不频繁。
- 项目周期较长,需要反复进行回归测试。
- 项目功能较复杂,涉及多个模块和接口。
- 项目质量要求较高,需要保证高覆盖率和高可靠性。
- 你参与过哪些类型的自动化测试项目?
答:我参与过以下几种类型的自动化测试项目:
- Web UI自动化测试:使用Selenium WebDriver和Python编写测试脚本,对网页上的元素进行定位、操作和断言,验证网页的布局、功能和兼容性。
- 接口自动化测试:使用Requests和Python编写测试脚本,对HTTP接口进行请求、响应和断言,验证接口的正确性、性能和安全性。
- 性能自动化测试:使用Locust和Python编写测试脚本,对系统进行压力、负载和稳定性测试,评估系统的性能指标和瓶颈。
- 移动端自动化测试:使用Appium和Python编写测试脚本,对移动应用进行安装、启动、操作和断言,验证移动应用的功能和兼容性。
测试框架
- 什么是PO模式?
答:PO模式(Page Object Model)是一种设计模式,用于将页面上的元素和操作封装成对象,从而实现页面与业务逻辑的分离。PO模式可以提高代码的复用性、可读性和可维护性,同时也可以降低代码的耦合度和冗余度。
- PO模式的封装原则有哪些?
答:PO模式的封装原则有以下几个:
- 每个页面对应一个类,每个类对应一个文件。
- 每个类中定义页面上的元素属性和操作方法。
- 每个元素属性使用定位器(locator)来表示,每个操作方法返回相应的页面对象或结果。
- 每个类中不包含任何断言或验证逻辑,只负责页面上的元素和操作。
- 每个类中使用初始化方法(init)来实例化驱动对象(driver)和等待对象(wait)。
- 你使用过哪些Python测试框架?
答:我使用过以下几种Python测试框架:
- unittest:Python标准库中的单元测试框架,提供了测试用例、测试套件、测试运行器、测试报告等功能,支持断言、异常、装饰器、参数化等特性。
- pytest:Python社区中最流行的测试框架,提供了简洁的测试风格、灵活的插件机制、丰富的内置功能,支持断言、异常、装饰器、参数化、标记、钩子等特性。
- nose:Python社区中另一个流行的测试框架,提供了自动发现测试用例、扩展插件系统、多种输出格式等功能,支持断言、异常、装饰器、参数化等特性。
- robot framework:Python社区中一个通用的自动化测试框架,提供了关键字驱动、数据驱动、行为驱动等测试方法,支持多种测试库和工具,如Selenium Library、Requests Library等。
测试工具
- selenium中隐藏元素如何定位?
答:selenium中隐藏元素指的是在网页上不可见,但在DOM树中存在的元素。隐藏元素可以通过以下几种方法定位:
- 使用find_element_by_*方法定位元素,然后使用is_displayed方法判断元素是否可见,如果不可见,则说明是隐藏元素。
- 使用execute_script方法执行JavaScript代码,通过document.querySelector或document.getElementById等方法获取隐藏元素。
- 使用CSS选择器或XPath表达式,通过属性或函数来筛选出隐藏元素,如display:none或hidden()等。
- 关闭浏览器中quit和close的区别
答:quit和close都是selenium WebDriver中的方法,用于关闭浏览器。它们的区别如下:
- quit方法会关闭所有打开的浏览器窗口,并退出驱动程序(driver)进程,释放资源。
- close方法只会关闭当前激活的浏览器窗口,并不会退出驱动程序(driver)进程,如果有其他窗口还会保持打开状态。
- 举例一下你遇到过那些异常
答:我在使用selenium WebDriver进行自动化测试时,遇到过以下几种异常:
- NoSuchElementException:表示没有找到指定的元素。
- TimeoutException:表示在指定的时间内没有找到指定的元素或条件。
- StaleElementReferenceException:表示元素已经失效或不存在于当前页面。
- WebDriverException:表示与驱动程序(driver)或浏览器通信出现问题。
- ElementNotInteractableException:表示元素不可交互或被遮挡。
- 如何处理alert弹窗?
答:alert弹窗是一种JavaScript生成的对话框,用于显示一些信息或警告。selenium WebDriver提供了switch_to.alert方法,可以切换到alert弹窗,并进行以下操作:
- text属性:获取alert弹窗的文本内容。
- accept方法:点击alert弹窗的确定按钮。
- dismiss方法:点击alert弹窗的取消按钮。
- send_keys方法:向alert弹窗输入文本。
- 在selenium中如何处理多窗口?
答:在selenium中,有时候会遇到打开多个浏览器窗口的情况,比如点击一个链接或按钮后,会弹出一个新的窗口。这时候,我们需要切换到不同的窗口,才能进行相应的操作。selenium WebDriver提供了以下方法,可以处理多窗口:
- current_window_handle属性:获取当前激活的窗口句柄。
- window_handles属性:获取所有打开的窗口句柄,返回一个列表。
- switch_to.window方法:根据窗口句柄切换到指定的窗口。
- selenium中如何判断元素是否存在?
答:selenium中判断元素是否存在有以下几种方法:
- 使用find_element_by_*方法定位元素,如果找到了元素,则说明元素存在,如果没有找到,则会抛出NoSuchElementException异常,说明元素不存在。
- 使用find_elements_by_*方法定位元素,返回一个列表,如果列表为空,则说明元素不存在,如果列表不为空,则说明元素存在。
- 使用expected_conditions模块中的presence_of_element_located或visibility_of_element_located等条件,结合WebDriverWait对象进行显式等待,如果在指定时间内找到了元素,则说明元素存在,如果没有找到,则会抛出TimeoutException异常,说明元素不存在。
- 自动化中有哪三类等待?他们有什么特点?
答:自动化中有以下三类等待:
- 强制等待(sleep):指让程序暂停一定时间后再执行后续操作,时间是固定的,不受页面加载速度的影响。强制等待的优点是简单易用,缺点是浪费时间和资源,可能导致测试不稳定。
- 隐式等待(implicitly_wait):指设置一个全局的最大等待时间,在这个时间内,如果找到了元素,则继续执行后续操作,如果没有找到,则抛出异常。隐式等待的优点是可以提高测试效率和稳定性,缺点是只能判断元素是否存在,不能判断元素是否可见或可用。
- 显式等待(WebDriverWait):指设置一个特定的最大等待时间和一个或多个预期条件,在这个时间内,如果满足了预期条件,则继续执行后续操作,如果没有满足,则抛出异常。显式等待的优点是可以根据不同的条件进行灵活的等待,缺点是需要编写更多的代码。
- selenium中如何保证操作元素的成功率?也就是说如何保证点击的元素一定是可以点击的?
答:selenium中保证操作元素的成功率有以下几种方法:
- 使用显式等待(WebDriverWait)和expected_conditions模块中的element_to_be_clickable条件,等待元素可见且可用后再进行点击操作。
- 使用JavaScript代码,通过execute_script方法执行document.querySelector或document.getElementById等方法,直接获取并点击元素。
- 使用ActionChains类,模拟鼠标移动到元素上,然后执行click或click_and_hold等方法,进行点击操作。
- 如何提高selenium脚本的执行速度?
答:提高selenium脚本的执行速度有以下几种方法:
- 使用合适的定位器(locator),尽量避免使用CSS选择器或XPath表达式,因为它们的解析速度较慢。
- 使用合理的等待方式,尽量避免使用强制等待(sleep),而是使用隐式等待(implicitly_wait)或显式等待(WebDriverWait),根据实际情况设置合适的等待时间和条件。
- 使用多线程或多进程,将测试用例分配到不同的线程或进程中并行执行,提高测试效率和并发能力。
- 使用无头浏览器(headless browser),如PhantomJS或Chrome的无头模式,可以在不打开浏览器界面的情况下执行测试脚本,节省资源和时间。
- 用例在运行过程中经常会出现不稳定的情况,也就是说这次可以通过,下次就没办法通过了,如何去提升用例的稳定性?
答:提升用例的稳定性有以下几种方法:
- 分析用例失败的原因,找出导致不稳定的因素,如网络延迟、页面加载速度、元素定位不准确、数据依赖等,针对不同的因素采取相应的解决方案。
- 优化用例设计,遵循单一职责原则,保证每个用例只验证一个功能点,避免用例之间的相互影响。
- 增加用例重试机制,当用例失败时,可以重新执行一定次数,直到成功或达到最大重试次数。
- 增加用例日志和截图功能,当用例失败时,可以记录详细的日志和截图信息,方便分析和定位问题。
测试方法
- 你的自动化用例的执行策略是什么?
答:我的自动化用例的执行策略如下:
- 根据测试需求和测试计划,将测试用例分为不同的模块和优先级,按照模块和优先级进行组织和管理。
- 根据测试环境和测试资源,将测试用例分配到不同的测试机器上,并行或串行执行。
- 根据测试场景和测试目标,使用pytest或robot framework等测试框架,通过标记、参数化、钩子等功能,灵活地选择和控制需要执行的测试用例。
- 根据测试结果和测试报告,对测试用例进行分析和评估,对失败或不稳定的用例进行重试或修复。
- 什么是持续集成?
答:持续集成(Continuous Integration)是一种软件开发实践,指在软件开发过程中频繁地将代码集成到主干上,并进行自动化构建、测试、部署等操作。持续集成可以提高软件质量、效率和可靠性,同时也可以减少风险和成本。
- 自动化测试的时候是不是需要连接数据库做数据校验?
答:自动化测试的时候是否需要连接数据库做数据校验取决于具体的测试需求和测试目标。一般来说,在以下几种情况下需要连接数据库做数据校验:
- 当需要验证系统对数据库的增删改查操作是否正确时。
- 前端页面无法获知结果的时候,就需要操作数据库验证结果是否正确
- 纯接口测试中,没由提供任何可以直接获取结果的接口时,可以去数据库中验证结果是否正确
- 一些调用链路非常长才能知道一个结果是否准确时,可以通过数据库去验证结果是否正确
- 定时任务相关的业务:如数据同步,迁移等动作触发的时候可以考虑数据库验证结果
- 有些第三方的接口无法直接调用但是又步想mock的时候,可能需要往数据库修改数据进行后续操作
- 初始化或者清理测试数据的时候,可能需要数据库操作
- 以上等等是最常见的做法
-
有几种元素常用定位方式,分别是?你最偏爱哪一种,为什么?
答:8 种,分别是:- id、name、class name、tag name、link text、partial link text、xpath、css
- 我最常用的是 xpath(或 CssSelector)
- 因为很多情况下,html 标签的属性不够规范,无法通过单一的属性定位,这个时候就只能使用 xpath 可以去重实现定位唯一element
- 事实上定位最快的是Id,因为id是唯一的,然而大多数开发并没有设置id。
-
如何去定位页面上动态加载的元素?
答:属性动态变化是指该 element 没有固定的属性值,所以只能通过相对位置定位比如通过 xpath 的轴,找到该元素的父节点或者子节点等方式 -
点击链接以后,selenium是否会自动等待该页面加载完毕?
答:selenium WebDriver在点击链接以后,默认会使用隐式等待(implicitly_wait)来等待页面加载完毕。隐式等待会设置一个全局的最大等待时间,在这个时间内,如果页面加载完毕,则继续执行后续操作,如果没有加载完毕,则抛出异常。隐式等待的时间可以通过implicitly_wait方法来设置,一般建议设置为10秒左右。
但是,隐式等待有一个缺点,就是它只能判断页面是否加载完毕,不能判断页面上的元素是否加载完毕。因此,有时候即使页面加载完毕了,但是页面上的元素还没有加载完毕,这时候如果进行元素操作,就会出现找不到元素或元素不可交互的情况。为了避免这种情况,我们可以使用显式等待(WebDriverWait)和expected_conditions模块中的presence_of_element_located或visibility_of_element_located等条件,来等待页面上的元素出现或可见后再进行操作。
另外,我们也可以使用set_page_load_timeout方法来设置页面加载超时时间,并捕获TimeoutException异常。当页面加载超过设定的时间时,就会抛出异常,并停止等待。这样可以避免因为网络或服务器问题导致的无限等待。例如:
from selenium import webdriver | |
from selenium.common.exceptions import TimeoutException | |
driver = webdriver.Chrome() | |
driver.set_page_load_timeout(10) # 设置页面加载超时时间为10秒 | |
try: | |
driver.get("https://www.example.com") | |
except TimeoutException: | |
print("Page load timeout") | |
driver.execute_script("window.stop()") # 停止页面加载 |
- webdriver client的原理是什么?
答:webdriver client是指使用Python或其他语言编写的测试脚本,用于调用selenium WebDriver API来控制浏览器进行自动化测试。webdriver client的原理是基于客户端-服务器(client-server)模式的,具体如下:
- webdriver client作为客户端,通过HTTP协议向webdriver server发送请求,请求中包含了要执行的命令和参数。
- webdriver server作为服务器,接收到请求后,根据请求中的命令和参数,通过浏览器驱动(browser driver)向浏览器发送指令,控制浏览器进行相应的操作。
- 浏览器执行完指令后,返回执行结果给浏览器驱动(browser driver),浏览器驱动(browser driver)再将执行结果返回给webdriver server。
- webdriver server将执行结果封装成响应,通过HTTP协议发送给webdriver client。
- webdriver client接收到响应后,根据响应中的结果进行相应的处理。
- webdriver的协议是什么?
答:webdriver的协议是指WebDriver Wire Protocol,是一种基于RESTful风格的HTTP协议,用于定义webdriver client和webdriver server之间通信的规范。webdriver协议包括以下几个部分:
- URL:表示webdriver server提供服务的地址和端口号,以及要操作的会话(session)和元素(element)等资源。
- Method:表示请求使用的HTTP方法,如GET、POST、DELETE等。
- Parameters:表示请求中携带的参数,如命令、数据、选项等。
- Response:表示响应中返回的结果,包括状态码、状态信息、数据等。
- 启动浏览器的时候用到的是哪个webdriver协议?
答:启动浏览器的时候用到的是POST /session命令,这是一个webdriver协议中定义的命令,用于创建一个新的会话(session),并返回一个会话ID(session ID)。会话ID是用于标识和控制一个特定浏览器实例的唯一标识符。创建会话时,可以通过parameters参数来指定要启动的浏览器类型、版本、选项等信息。
- 怎样去选择一个下拉框中的value=xx的option?
答:选择一个下拉框中的value=xx的option有以下几种方法:
- 使用Select类,通过value属性来选择option,如Select(driver.find_element_by_id("dropdown")).select_by_value("xx")。
- 使用CSS选择器,通过value属性来定位option,然后进行点击操作,如driver.find_element_by_css_selector("option[value='xx']").click()。
- 使用XPath表达式,通过value属性来定位option,然后进行点击操作,如driver.find_element_by_xpath("//option[@value='xx']").click()。
- Python 中常见的可变参数类型和不可变参数类型,都有哪些?
答:Python 中常见的可变参数类型和不可变参数类型如下:
- 可变参数类型:指参数的值可以被修改的类型,如列表(list)、字典(dict)、集合(set)等。
- 不可变参数类型:指参数的值不能被修改的类型,如数字(int、float、complex)、布尔值(bool)、字符串(str)、元组(tuple)等。
- 如何在定位元素后高亮元素(以调试为目的)?
答:在定位元素后高亮元素有以下几种方法:
- 使用JavaScript代码,通过execute_script方法执行document.querySelector或document.getElementById等方法,获取元素对象,然后修改元素的style属性,如添加边框或背景色等。
- 使用ActionChains类,模拟鼠标移动到元素上,然后执行move_to_element或move_to_element_with_offset等方法,使元素处于悬停状态。
- 使用selenium IDE插件,录制或编辑测试脚本时,可以在右侧的界面中看到元素被高亮显示。
- 什么是断言?
答:断言是指在测试过程中对测试结果进行验证的操作,判断测试结果是否符合预期。断言可以提高测试的准确性和可信度,同时也可以发现和定位问题。断言有以下几种类型:
- 等值断言:判断两个值是否相等,如assertEqual、assertNotEqual等。
- 布尔断言:判断一个值是否为真或假,如assertTrue、assertFalse等。
- 包含断言:判断一个值是否包含或被包含于另一个值,如assertIn、assertNotIn等。
- 异常断言:判断一个代码块是否抛出指定的异常,如assertRaises、assertRaisesRegex等。
- 自动化测试过程中,你遇到了哪些问题,是如何解决的?
答:自动化测试过程中,我遇到了以下几种问题:
- 元素定位不准确或失败:我通过使用不同的定位器(locator)或组合多个定位器(locator)来尝试定位元素,或者使用JavaScript代码来直接获取元素对象。
- 元素不可交互或被遮挡:我通过使用显式等待(WebDriverWait)和expected_conditions模块中的element_to_be_clickable条件来等待元素可见且可用后再进行操作,或者使用JavaScript代码来直接操作元素对象。
- 页面加载缓慢或超时:我通过使用隐式等待(implicitly_wait)或显式等待(WebDriverWait)来设置合理的等待时间和条件来等待页面加载完毕后再进行操作,或者使用set_page_load_timeout方法来设置页面加载超时时间,并捕获TimeoutException异常。
- 测试用例不稳定或失败:我通过分析测试用例失败的原因和日志信息来找出导致不稳定的因素,并针对不同的因素采取相应的解决方案,如优化用例设计、增加用例重试机制、增加用例日志和截图功能等。
- 如何模拟浏览器的前进、后退、刷新操作?
答:模拟浏览器的前进、后退、刷新操作有以下几种方法:
- 使用selenium WebDriver中的back、forward和refresh方法,分别对应浏览器的后退、前进和刷新操作,如driver.back()、driver.forward()和driver.refresh()。
- 使用JavaScript代码,通过execute_script方法执行window.history.back、window.history.forward和window.location.reload等方法,分别对应浏览器的后退、前进和刷新操作,如driver.execute_script("window.history.back()")等。
- 使用键盘操作,通过send_keys方法发送组合键,分别对应浏览器的后退、前进和刷新操作,如driver.send_keys(Keys.ALT + Keys.LEFT)等。
- 什么是关键字驱动测试?
答:关键字驱动测试是一种测试方法,指将测试用例中的操作步骤和验证点从测试脚本中分离出来,封装成一系列的关键字,如click、input、assert等。在执行测试时,通过读取外部的关键字文件或表格,按照关键字的顺序和参数,调用相应的函数或方法来执行测试用例。关键字驱动测试可以提高测试用例的可读性、可扩展性和可维护性,同时也可以降低编码难度和技术要求。
- 如何实现关键字驱动测试?
答:实现关键字驱动测试有以下几个步骤:
- 设计测试用例,确定需要封装的操作步骤和验证点,以及对应的关键字和参数。
- 准备关键字文件或表格,选择合适的文件或表格格式,如TXT、Excel、CSV等,并将关键字和参数填充到文件或表格中。
- 编写测试脚本,使用Python或其他语言编写测试脚本,定义一系列的函数或方法,对应不同的关键字和参数,并使用相应的模块或库,如selenium WebDriver、unittest、xlrd等,来实现操作步骤和验证点。
- 执行测试脚本,使用Python或其他语言编写执行器(executor),使用相应的模块或库,如os、csv、xml等,来读取关键字文件或表格中的数据,并根据关键字和参数,调用相应的函数或方法来执行测试用例。
- 生成测试报告,使用allure或reportlab等工具,来生成可视化的测试报告,并展示测试结果和数据。
Python基础
- 什么是*args和kwargs?**
答:*args和**kwargs是Python中的两种特殊参数,用于接收不定数量的位置参数和关键字参数。它们的含义如下:
- *args:表示将位置参数打包成一个元组(tuple),并赋值给args变量,可以通过args[index]来访问元素。
- **kwargs:表示将关键字参数打包成一个字典(dict),并赋值给kwargs变量,可以通过kwargs[key]来访问元素。
- 如何使用*args和kwargs?**
答:使用*args和**kwargs有以下几种情况:
- 在定义函数时,使用*args和**kwargs作为形参,可以接收不定数量的位置参数和关键字参数,如def func(*args, **kwargs)。
- 在调用函数时,使用*args和**kwargs作为实参,可以将一个元组(tuple)或一个字典(dict)拆分成多个位置参数或关键字参数,如func(*args, **kwargs)。
- 在继承类时,使用*args和**kwargs作为实参,可以将父类的初始化方法中的位置参数和关键字参数传递给子类的初始化方法,如super().init(*args, **kwargs)。
- 在装饰器中,使用*args和**kwargs作为形参和实参,可以保证被装饰的函数不管有多少个位置参数或关键字参数都能正常运行,如def wrapper(*args, **kwargs): return func(*args, **kwargs)。
- Python中的垃圾回收机制是什么?
答:Python中的垃圾回收机制是指Python解释器自动管理内存的机制,用于回收不再使用的对象,释放内存空间。Python中的垃圾回收机制主要有以下两种方法:
- 引用计数(reference counting):每个对象都有一个引用计数属性,表示该对象被引用的次数。当一个对象被创建时,其引用计数为1;当一个对象被引用时,其引用计数加1;当一个对象被取消引用时,其引用计数减1;当一个对象的引用计数为0时,该对象就成为垃圾,可以被回收。
- 标记清除(mark-sweep):当出现循环引用(circular reference)时,即两个或多个对象相互引用,导致它们的引用计数都不为0,但实际上它们已经不再使用,这时候就需要标记清除来处理。标记清除分为两个阶段:标记阶段,从根对象(root object)出发,遍历所有可达对象,并将它们标记为可达;清除阶段,遍历所有对象,将未被标记为可达的对象回收。
- 如何手动触发垃圾回收?
答:Python中可以使用gc模块来手动触发垃圾回收,具体有以下几种方法:
- gc.collect():执行一次完整的垃圾回收,包括标记清除和分代回收,返回回收的对象数量。
- gc.set_threshold(threshold0, threshold1, threshold2):设置分代回收的阈值,当某一代的对象数量达到阈值时,就会触发该代及其上一代的垃圾回收。
- gc.enable():启用自动垃圾回收。
- gc.disable():禁用自动垃圾回收。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!