自动化测试面试问答(二)

1、Java 执行selenium和Python 执行selenium有什么区别?

核心功能相同:二者都使用 Selenium WebDriver 的API,能实现完全相同的浏览器自动化操作(打开网页、点击、输入等)。

主要区别在于编程语言本身及生态

特性

Java + Selenium

Python + Selenium

语言特性

强类型、静态语言,代码严谨但相对冗长

弱类型、动态语言,语法简洁,编写速度快

代码示例

 (打开百度)

WebDriver driver = new ChromeDriver();

driver.get("https://www.baidu.com");

driver = webdriver.Chrome()

driver.get("https://www.baidu.com")

学习曲线

需理解面向对象、类型系统,入门门槛略高

语法接近自然语言,新手友好,上手更快

开发效率

代码量通常更大,编译步骤稍慢

代码简洁,无需编译,快速原型开发首选

生态与库支持

成熟企业级生态(JUnit/TestNG, Maven/Gradle)

丰富的数据科学库(Pandas, NumPy),适合爬虫

应用场景

大型企业级测试框架,需要强类型保障的长期项目

快速脚本、爬虫、中小型测试项目,AI结合场景

社区与资源

历史悠久,企业应用广泛,文档丰富

增长迅猛,尤其在测试自动化和爬虫领域

执行速度

JVM优化后通常更快

略慢于Java,但日常操作差异不明显

如何选择?

  • 选 Java:团队已有Java基础或企业级测试框架(如TestNG)。项目需要强类型检查和长期维护。
  • 选 Python:快速实现需求(写脚本、爬虫、小型测试)。团队熟悉Python或需要结合数据分析/机器学习。新手入门更轻松。

✅ 总结:功能无差距,差异在语言。Python适合敏捷开发和初学者,Java适合大型企业级项目。根据团队技术栈和项目需求选择即可。

2、隐性等待和显性等待的区别?

特性

隐性等待 (Implicit Wait)

显性等待 (Explicit Wait)

作用范围

全局(影响所有 find_element 操作)

局部(仅针对当前等待语句)

等待条件

仅检查元素存在

支持多种条件(可见、可点击、文本等)

灵活性

高(可定制复杂条件)

效率

可能产生冗余等待

高效(条件满足即退出)

适用场景

简单页面,元素加载稳定

动态页面(AJAX/SPA),需条件判断的操作

代码复杂度

简单(一行配置)

较高(需定义条件和等待对象)

3、如果页面上的元素用隐性等待和显性等待都没等到元素加载出来,请问要怎么办?

思路:

  • 优先手动验证:确认元素在HTML中真实存在
  • 定位器优化:使用更健壮的XPath/CSS,处理iframe/Shadow DOM
  • 精准等待条件:确保等待的是可交互状态(非仅存在)
  • 控制页面加载:设置 page_load_strategy 和超时时间
  • 环境兜底:最大化窗口、版本匹配、添加重试
  • 终极方案:用JavaScript直接探测元素状态

1)验证元素是否存在(基础检查)

  • 手动验证:在浏览器开发者工具(F12)中手动执行定位表达式,确认元素是否存在。
  • 检查时机:在等待后添加 driver.page_source 输出当前HTML源码,检查元素是否被加载(可能被动态移除)。

2)定位策略失效的排查(核心原因)

  • 定位器问题

问题类型

解决方案

过时定位器

检查元素属性(ID/Class)是否随页面刷新/重渲染变化(常见于SPA应用)

动态生成元素

使用更稳定的定位方式:XPath结合文本、父节点关系,或CSS属性选择器

元素在iframe中

切换至iframe:driver.switch_to.frame("frame_id/name/index")后再定位

元素在Shadow DOM

使用driver.execute_script()穿透Shadow Root(需JS脚本辅助)

  • 等待条件不匹配
# 显性等待的常见误用:等待"存在" ≠ 等待"可交互"
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "btn"))  # 元素存在但可能被遮挡/不可点击
)
# 应改用可交互条件:
EC.element_to_be_clickable((By.ID, "btn"))  # 确保元素可操作

3) 页面状态异常(进阶排查)

场景

解决方案

页面未完全加载

设置页面加载策略:options.page_load_strategy = 'eager'(放弃加载图片等资源)

AJAX/JS未完成

自定义等待条件:检查JS变量或特定元素状态

弹窗遮挡元素

关闭弹窗:driver.switch_to.alert.dismiss()或执行JS移除遮挡层

新窗口/标签页

切换窗口句柄:driver.switch_to.window(driver.window_handles[1])

4) 自定义等待条件(终极手段)

当内置条件不满足时,用JavaScript轮询目标状态:

def wait_for_element_state(driver, selector, state="visible", timeout=10):
    script = """
        const el = document.querySelector(arguments[0]);
        if (arguments[1] === 'visible') 
            return el && getComputedStyle(el).display !== 'none';
        // 可扩展其他状态:enabled, hasText...
    """
    return WebDriverWait(driver, timeout).until(
        lambda d: d.execute_script(script, selector, state)
    )

# 使用示例
wait_for_element_state(driver, "#dynamicElement", "visible")

5) 环境与执行问题

问题

解决方案

浏览器窗口太小

最大化窗口:driver.maximize_window()

资源加载超时

增加页面加载超时:driver.set_page_load_timeout(60)

浏览器驱动版本不匹配

使用webdriver-manager自动匹配驱动

偶发性失败

添加重试机制(如tenacity库)

4、xpath查找元素时间过长,要怎么优化,提高效率?

思路:

  • 能否用CSS选择器替代? (优先选择)
  • 是否限定搜索范围? (父元素上下文)
  • 是否避免使用//和contains()?
  • 是否指定了标签类型? (避免*通配符)
  • 是否禁用不必要的全局等待?
  • 是否分阶段处理动态内容?
  • 是否使用浏览器原生XPath?

1)优化 XPath 表达式

  • 避免低效语法,使用精准定位
  • 低效:模糊匹配
  • 高效:精确匹配 + 属性限定

低效写法

高效替代方案

效率提升原理

//div//span

//div/span

减少中间节点扫描

//*[@class='btn']

//button[@class='btn']

限定标签类型减少搜索范围

//div[contains(@class,'icon')]

//div[@class='user-icon']

避免函数计算

2)缩小搜索范围

  • 从父节点开始查找
# 先快速定位父元素(用ID/CSS)
parent = driver.find_element(By.ID, "form-container")
# 再在父元素内用XPath
child = parent.find_element(By.XPATH, ".//input[@name='email']")  # 注意开头的点(.)
  • 利用最近定位点
# 已定位元素作为上下文
known_element = driver.find_element(By.CSS_SELECTOR, "#sidebar")
target = known_element.find_element(By.XPATH, "following-sibling::div[1]")

3)改用 CSS 选择器

CSS 选择器通常比 XPath 快 5-10 倍(浏览器原生优化)

# XPath 低效定位
//div[@class='container']/ul/li[3]/a

# CSS 高效替代
driver.find_element(By.CSS_SELECTOR, "div.container > ul > li:nth-child(3) > a")

 4)优化等待策略

  • 精准显性等待
# 只等待必要的最小元素出现
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "essential_element")))

# 后续再查找复杂XPath
element = driver.find_element(By.XPATH, "//div[...]")
  • 禁用隐性等待
# 复杂查找前关闭全局等待
driver.implicitly_wait(0)  # 临时禁用
try:
    element = driver.find_element(By.XPATH, complex_xpath)
finally:
    driver.implicitly_wait(10)  # 恢复

5)处理动态内容策略

  • 分阶段定位
# 第一阶段:等待容器加载
container = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "dynamic-container"))
)

# 第二阶段:在容器内查找
items = container.find_elements(By.XPATH, ".//li[contains(@class, 'item')]")
  • 直接 DOM 访问
# 通过JS直接获取元素(比XPath快3-5倍)
script = "return document.querySelector('div.container > ul > li:nth-child(2)');"
element = driver.execute_script(script)

6)XPath 引擎优化

  • 使用浏览器原生 XPath
# 启用浏览器原生XPath评估(比Selenium实现更快)
capabilities = {
    "goog:chromeOptions": {
        "args": ["--disable-blink-features=AutomationControlled"]
    }
}
driver = webdriver.Chrome(desired_capabilities=capabilities)
  • 预编译 XPath
# 重复使用的XPath预编译
from selenium.webdriver.common.by import By

search_xpath = (By.XPATH, "//div[@class='results']/span")

# 多次使用
element1 = driver.find_element(*search_xpath)
element2 = driver.find_element(*search_xpath)

#秋招##测试面经##测试#
测试岗面经 文章被收录于专栏

整理面试过程中的测试问答,常看常新,多多学习!有些问题是从其他人那里转载而来,会在文章下面注明出处,希望大家多多支持~~

全部评论

相关推荐

机械打工仔:我来告诉你原因,是因为sobb有在线简历,有些HR为了快会直接先看在线简历,初步感觉不合适就不会找你要详细的了
投了多少份简历才上岸
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务