软件测试大赛web测试-python【备赛4 复盘待完善】
2025年预选赛-百度地图
菜鸟一枚,需求3 6 8没写对,还没改,以下只是复盘,欢迎评论区一起讨论!!
测试需求
1. 公交线路查询
- 需求1(R001):用户访问百度地图首页,点击【路线】按钮
,然后点击左上角的【公交】
选项以进入公交查询窗口。在【输入起点或在图区上选点】输入框中输入起点,在【输入终点】输入框中输入终点。点击【搜索】按钮进行查询,系统应正确显示推荐路线,并截图查询结果。(共4条用例)
输入数据要求:
-起点:仅考虑以下2个地点(南京大学(鼓楼校区)、东南大学(四牌楼校区))
-终点:仅考虑以下2个地点(新街口商业步行区、先锋书店(五台山店))
- 需求2(R002):用户访问百度地图首页,点击【路线】按钮
,然后点击左上角的【公交】
选项以进入公交查询窗口。在【输入起点或在图区上选点】的输入框中输入起点,在【输入终点】的输入框中输入终点。用户点击搜索按钮进行查询,并依次点击切换【推荐路线】
、【时间短】
、【少换乘】
和【少步行】
按钮,系统应正确显示相应的查询结果。需要验证切换功能是否运作正常以及查询结果的准确性。注:每次切换后,都需要对查询结果进行截图。(共4条用例)
输入数据要求:起点为南京大学(鼓楼校区),终点为南京大学(仙林校区)
- 需求3(R003):用户访问百度地图首页,点击【路线】按钮
,选择左上角的【公交】
选项进入公交查询窗口。在输入框中分别输入起点和终点。点击【搜索】按钮进行查询,系统应正确显示相应的查询结果。接下来,将鼠标移动到指定位置
并点击【选为起点】按钮
,随后点击【查看全部线路】
。在展开的公交线路列表中(包括停运线路),选择并点击【48路】。在下方展开的公交线路详情列表中,双击先锋书店(五台山店)右侧的【摄像头图标】
以显示街景,系统应正确显示街景。需要验证摄像头图标功能是否正常运作,以及街景的清晰度。最后,对最终显示结果进行截图。(共1条用例)
输入数据要求:起点为玄武湖景区,终点为先锋书店(五台山店)
2. 路况信息
- 需求4(R004):用户访问百度地图首页,点击【地点下拉选择】控件
,在展开的城市列表中,选择【南京】。随后点击【路况】
选项。在展开的路况信息页面中,用户应点击【实时路况】
按钮。接着,用户单击【刷新】
按钮,系统应正确更新并显示最新的实时路况信息。完成操作后,用户需对刷新结果进行截图。(共1条用例)
- 需求5(R005):用户访问百度地图首页,点击【地点下拉选择】控件
,在展开的城市列表中,选择【南京】。随后点击【路况】
选项,在展开的路况信息页面中,点击【路况预测】
按钮。用户应能够通过点击【星期标签】
来切换查看不同星期的路况信息。系统应正确显示与所选星期标签相对应的路况信息。注意:用户需要点击每个星期标签进行切换,并且每次切换后都需要对查询结果进行截图。(共7条用例)
- 需求6(R006):用户访问百度地图首页,点击【地点下拉选择】控件
,在展开的城市列表中,选择【南京】。随后点击【路况】
按钮。在展开的路况信息页面中,用户需点击【路况预测】
按钮以进入预测模式。在此模式下,用户应将时间轴拖动至晚上21:00
,系统应准确显示该时间点的路况预测信息。需要验证时间轴操作的流畅性以及预测信息的准确性。完成验证后,用户应截图保存查询结果。(共1条用例)
3. 地铁线路图
- 需求7(R007):用户访问百度地图首页,点击【地点下拉选择】控件
,在展开的城市列表中,选择【南京】,随后点击【地铁】
按钮以进入地铁线路图页面。在页面中,用户需要在【输入起点】输入框中输入起点站点,在【输入终点】输入框中输入终点站点。输入完成后,用户点击【搜索】按钮进行查询。系统应正确显示出乘车方案以及地铁乘车路线。为了验证查询结果,用户需要对查询结果进行截图。(共4条用例)
输入数据要求:
起点:仅考虑以下2个地点(珠江路、新街口)
终点:仅考虑以下2个地点(南京站、卡子门)
- 需求8(R008):用户访问百度地图首页,点击【地点下拉选择】控件
,在展开的城市列表中,选择【南京】,随后点击【地铁】
按钮以进入地铁线路图页面。在页面中,用户应点击【大行宫站】
作为起点,并选择【马群站】
作为终点。完成选择后,用户点击【搜索】按钮。系统应正确显示乘车方案以及地铁乘车路线。在验证过程中,用户需要对查询结果进行截图以确认结果的正确性。(共1条用例)
代码:
import os
from datetime import datetime
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service@pytest.fixture( scope="function" )
def driver():# 提交最终代码脚本时,请将驱动路径换回官方路径"C:\\Users\\86153\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"service = Service(executable_path="C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe" )driver = webdriver.Chrome( service=service )driver.get( "https://map.baidu.com/ " )driver.maximize_window()driver.implicitly_wait( 10 )yield driverdriver.quit()class TestBaiDuMap:# test-code-start# 请在此处插入Selenium+Pytest代码def test_BaiDuMap_R001(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.keys import Keysimport time# 起点和终点组合(按需求文档)test_cases = [("南京大学(鼓楼校区)", "新街口商业步行区"),("南京大学(鼓楼校区)", "先锋书店(五台山店)"),("东南大学(四牌楼校区)", "新街口商业步行区"),("东南大学(四牌楼校区)", "先锋书店(五台山店)"),]for idx, (start, end) in enumerate(test_cases, start=1):# 重新进入首页以清除状态driver.get("https://map.baidu.com/")driver.maximize_window()driver.implicitly_wait(10)# 点击【路线】按钮(使用 class + data-title 精确定位)route_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.route-button[data-title="路线"]')))route_button.click()# 点击【公交】选项(class="tab-item bus-tab")bus_tab = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.tab-item.bus-tab')))bus_tab.click()# 定位起点输入框(class="route-start-input")start_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-start-input")))start_input.clear()start_input.click()start_input.send_keys(start)start_input.send_keys(Keys.ENTER)# 定位终点输入框(class="route-end-input")end_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-end-input")))end_input.clear()end_input.click()end_input.send_keys(end)end_input.send_keys(Keys.ENTER)# 点击搜索按钮(ID="search-button")search_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "search-button")))search_button.click()# 等待路线结果加载(等待至少一个路线方案出现)WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".route-wrap")))time.sleep(2) # 额外缓冲确保渲染完成# 截图:用例编号 BaiDuMap_R001_001 ~ BaiDuMap_R001_004case_id = f"BaiDuMap_R001_{idx:03d}"self.take_screenshot(driver, f"{case_id}.png")def test_BaiDuMap_R002(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.keys import Keysimport timestart = "南京大学(鼓楼校区)"end = "南京大学(仙林校区)"# 进入首页并初始化公交路线查询driver.get("https://map.baidu.com/")driver.maximize_window()driver.implicitly_wait(10)# 点击【路线】route_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.route-button[data-title="路线"]')))route_button.click()# 点击【公交】bus_tab = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.tab-item.bus-tab')))bus_tab.click()# 输入起点start_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-start-input")))start_input.clear()start_input.click()start_input.send_keys(start)start_input.send_keys(Keys.ENTER)# 输入终点end_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-end-input")))end_input.clear()end_input.click()end_input.send_keys(end)end_input.send_keys(Keys.ENTER)# 点击搜索search_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "search-button")))search_button.click()# 等待结果加载WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".route-wrap")))time.sleep(2)# 定义策略顺序与对应截图编号strategies = [("type0", "BaiDuMap_R002_001"), # 推荐路线(默认已选,但仍需显式点击确保状态)("type5", "BaiDuMap_R002_002"), # 时间短("type2", "BaiDuMap_R002_003"), # 少换乘("type3", "BaiDuMap_R002_004"), # 少步行]for strategy_id, case_id in strategies:# 点击策略按钮(即使“推荐路线”是默认,也点击一次以确保一致性)strategy_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, strategy_id)))strategy_btn.click()time.sleep(1.5) # 等待结果刷新# 截图self.take_screenshot(driver, f"{case_id}.png")def test_BaiDuMap_R003(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.keys import Keysfrom selenium.webdriver.common.action_chains import ActionChainsimport timestart = "玄武湖景区"end = "先锋书店(五台山店)"driver.get("https://map.baidu.com/")driver.maximize_window()driver.implicitly_wait(10)# 点击【路线】route_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.route-button[data-title="路线"]')))route_button.click()# 点击【公交】bus_tab = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.tab-item.bus-tab')))bus_tab.click()# 输入起点和终点start_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-start-input")))start_input.clear()start_input.click()start_input.send_keys(start)start_input.send_keys(Keys.ENTER)end_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "route-end-input")))end_input.clear()end_input.click()end_input.send_keys(end)end_input.send_keys(Keys.ENTER)# 搜索search_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "search-button")))search_button.click()# 等待地址选择浮层中的“选为起点”按钮出现(关键!)sel_start_btn = WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.selInfoWndBtn')))sel_start_btn.click()time.sleep(1.5)# 步骤2: 点击【查看全部线路】view_all = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.route_show')))view_all.click()time.sleep(2)# 步骤3: 点击【48路】方案# 1. 找到“48路”元素bus_48 = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, '//div[contains(@class, "schemeName") and contains(text(), "48路")]')))# 2. 找到它的可滚动父容器( .route-wrap)scrollable_container = driver.find_element(By.CSS_SELECTOR, '.route-wrap')# 3. 滚动该容器,使 48 路可见(使用 scrollTop = 元素.offsetTop)driver.execute_script("arguments[0].scrollTop = arguments[1].offsetTop - 50;",scrollable_container,bus_48)time.sleep(1)# 4. 再次等待并点击(确保可见且可点击)WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, '//div[contains(@class, "schemeName") and contains(text(), "48路")]'))).click()time.sleep(2)# 步骤4: 双击“先锋书店(五台山店)”的摄像头图标camera_icon = WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.list_street_view_poi[data-name="先锋书店(五台山店)"]')))ActionChains(driver).double_click(camera_icon).perform()time.sleep(3) # 等待街景加载# 截图self.take_screenshot(driver, "BaiDuMap_R003_001.png")def test_BaiDuMap_R004(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECimport time# 1. 点击【地点下拉选择】控件("南京市")city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()# 2. 在弹出列表中点击【南京】# 使用 XPath 精准匹配文本为“南京”的 <a> 标签nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(1)# 3. 点击【路况】按钮traffic_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.trafficopt')))traffic_button.click()# 4. 点击【实时路况】real_time_traffic = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "tarffic_ss")))real_time_traffic.click()# 5. 点击【刷新】按钮refresh_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "bt_trafficCtrl")))refresh_button.click()time.sleep(2) # 等待刷新完成# 6. 截图self.take_screenshot(driver, "BaiDuMap_R004_001.png")def test_BaiDuMap_R005(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECimport time# 1. 选择城市为南京(复用 R004 的逻辑)city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(1)# 2. 点击【路况】traffic_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.trafficopt')))traffic_button.click()# 3. 点击【路况预测】forecast_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "tarffic_yc")))forecast_button.click()time.sleep(1)# 4. 依次点击星期一至星期日,并截图for i in range(7):# 构造 ID:week_trafficCtrl_0 ~ week_trafficCtrl_6week_id = f"week_trafficCtrl_{i}"case_id = f"BaiDuMap_R005_{i+1:03d}" # 001 ~ 007week_span = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, week_id)))week_span.click()time.sleep(1) # 等待预测图表更新self.take_screenshot(driver, f"{case_id}.png")def test_BaiDuMap_R006(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.action_chains import ActionChainsimport time# 1. 选择城市为南京city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(1)# 2. 点击【路况】traffic_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.trafficopt')))traffic_button.click()# 3. 点击【路况预测】forecast_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "tarffic_yc")))forecast_button.click()time.sleep(1)# 4. 获取时间轴容器和滑块time_container = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".time_line_arrow_cont")))time_slider = driver.find_element(By.ID, "bar_trafficCtrl")# 5. 计算 21:00 对应的偏移量container_width = time_container.size['width']slider_width = time_slider.size['width']hours_target = 21 # 21:00px_per_hour = container_width / 24offset = int(px_per_hour * hours_target - slider_width / 2)# 6. 拖动滑块到 21:00 位置ActionChains(driver).drag_and_drop_by_offset(time_slider, offset, 0).perform()time.sleep(1.5)# 7. 截图self.take_screenshot(driver, "BaiDuMap_R006_001.png")def test_BaiDuMap_R007(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.keys import Keysimport time# 1. 选择城市为南京city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(1)# 2. 点击【地铁】按钮subway_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.subwayopt')))subway_button.click()time.sleep(1)# 3. 定义测试数据starts = ["珠江路", "新街口"]ends = ["南京站", "卡子门"]case_index = 1for start in starts:for end in ends:# 每次查询前刷新页面(或重新进入地铁页)以清除状态driver.get("https://map.baidu.com/")driver.maximize_window()driver.implicitly_wait(10)# 重新选择南京city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(0.5)# 点击地铁subway_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.subwayopt')))subway_button.click()time.sleep(1)# 4. 定位地铁页面的起点和终点输入框(通过 placeholder)start_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="输入起点"]')))start_input.clear()start_input.click()start_input.send_keys(start)start_input.send_keys(Keys.ENTER)end_input = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="输入终点"]')))end_input.clear()end_input.click()end_input.send_keys(end)end_input.send_keys(Keys.ENTER)# 5. 点击搜索按钮(地铁页通常复用 #search-button)search_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "search-button")))search_btn.click()# 6. 等待结果卡片容器出现(最稳定)WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.ID, "cards-level1")))time.sleep(2)# 7. 截图case_id = f"BaiDuMap_R007_{case_index:03d}"self.take_screenshot(driver, f"{case_id}.png")case_index += 1def test_BaiDuMap_R008(self, driver):from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECimport time# 1. 选择城市为南京city_selector = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.ui3-city-change-inner')))city_selector.click()nanjing_option = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@name="南京" and text()="南京"]')))nanjing_option.click()time.sleep(1)# 2. 点击【地铁】按钮subway_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.subwayopt')))subway_button.click()time.sleep(2) # 等待地铁图加载完成# 3. 点击【大行宫站】作为起点daxinggong_station = WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH, '//image[@name="大行宫" and @eletype="0"]')))daxinggong_station.click()time.sleep(1)# 4. 点击【马群站】作为终点maqun_station = WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.XPATH, '//image[@name="马群" and @eletype="0"]')))maqun_station.click()time.sleep(1)# 5. 点击搜索按钮(部分版本自动查询,但显式点击更保险)search_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "search-button")))search_btn.click()time.sleep(2)# 6. 等待换乘结果加载(等待结果卡片出现)WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.ID, "cards-level1")))time.sleep(1)# 7. 截图self.take_screenshot(driver, "BaiDuMap_R008_001.png")# test-code-start@staticmethoddef take_screenshot(driver, file_name):timestamp = datetime.now().strftime( "%H%M%S%d%f" )[:-3]timestamped_file_name = f"{timestamp}_{file_name}"screenshots_dir = "screenshots"if not os.path.exists( screenshots_dir ):os.makedirs( screenshots_dir )screenshot_file_path = os.path.join( screenshots_dir, timestamped_file_name )driver.save_screenshot( screenshot_file_path )
问题记录:
R001
在自动化测试中,观察到起点和终点已经输入,已经显示出线路,没有截图并进行下一轮查询。
因为 WebDriverWait 等待的条件未在指定时间内满足。要确认真实 DOM 中路线结果项的 class 或结构。
打开浏览器开发者工具(F12),手动执行一次 R001 查询(如“南京大学(鼓楼校区)” → “新街口商业步行区”),观察:
- 路线结果列表的 外层容器 是什么?
- 每条路线项的 共同 class 是什么?
公交路线结果项通常包含如下特征:<div class="transit-item" ...> ... </div>
找到问题了!真实 DOM 中路线结果项的 class 的 外层容器 是<div class="route-wrap" ...>。
改为这样,运行成功
WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".route-wrap")) )
R003
1.观察到自动化测试时,没有点击【选为起点】按钮。输入起点和终点后,不用在路线结果项容器里选择选为起点按钮,直接在页面中的自动会弹出的组件里点击。
根本找不到元素 → 导致后续操作失败 → 最终 WebDriverWait 超时 → TimeoutException。
✅ “选为起点”按钮并不在 .route-wrap 的路线结果里,
✅ 而是在 搜索后自动弹出的地址选择浮层(info window)中,
✅ 其 class 是 selInfoWndBtn,而不是 selBtn。
2.观察到展开的公交线路列表中需要下滑列表才能找到并点击【48路】
“元素在视口外,未滚动到可见区域,导致无法点击”
解决方案:在点击前先滚动到该元素,滚动包含“48路”的父级可滚动容器
使用 ActionChains(driver).scroll_to_element(element).perform()(Selenium 4+ 支持)
或使用 JavaScript 滚动:driver.execute_script("arguments[0].scrollIntoView();", element)
第一步:确认“48路”所在的可滚动容器
第二步:先找到“48路”元素,再找到它的可滚动父容器,然后滚动该容器
以上方法都失败
R006
百度地图时间轴是 基于 margin-left 控制位置 的滑块,无法直接设置时间为 21:00,但可以通过以下方式模拟:
- 先点击【路况预测】加载时间轴;
- 获取滑块元素
#bar_trafficCtrl; - 使用
ActionChains拖动滑块到最右侧(模拟拖到 21:00); - 等待时间显示更新为 “21:00”(若支持)或至少滑到末端;
- 截图。
时间滑动有问题,不是滑到最末端,时间轴从0-24点,现在滑块在15点,应该滑到21点
失败
R007
观察到自动化测试中输入起点终点并执行了查询,但是没有截图,并且终端报错。因为等待出现换乘方案或站点列表中等待的元素错误。
根据 DOM 结构,地铁结果实际存在于:
<ul id="cards-level1" class="cardlist"><li id="card-4" class="card animated-card"> ... </li></ul>其中包含:
#trans_description(方案描述区域)#routes_detail(详细路线表格)#totalTime(预计时间)
R008
DOM 分析:
- 站点以
<image>标签渲染(SVG 或 Canvas 模拟); - 通过
name="大行宫"和name="马群"可识别; - 虽然
<image>不是标准可点击 HTML 元素,但在百度地图中,这些站点图层绑定了点击事件; - Selenium 可以直接点击
<image>元素(只要它在 DOM 中且可见)。
观察到加载出地铁图后,并没有点击大行宫站。是因为定位不够精准。
虽然使用了 //image[@name="大行宫"],但在百度地图的地铁图中:
- 站点
<image>元素是 SVG 图形的一部分; - 它们可能被包裹在
<g>、<svg>或其他容器中; - 有时元素虽然存在于 DOM 中,但 实际渲染区域很小或被遮挡,导致 Selenium 认为“不可点击”;
- 百度地图的站点点击事件通常绑定在 父级
<g>或<path>上,而不是<image>本身; - 更重要的是:直接点击
<image>可能无法触发地图的选点逻辑,因为地图引擎需要坐标或特定事件。
方法一:通过 name 属性定位其父级 <g> 元素(失败)
方法二:使用 JavaScript 模拟点击(失败)
方法三:使用稳定属性 + 相对 XPath(失败)
失败
测试用例注意:
按照提供的测试用例模板表头整理完整测试用例内容,各列之间使用分号 ; 分隔,每列内部的换行使用 \n 表示,便于直接复制粘贴到 Excel 中(在excel中使用文本粘贴向导的时候能正确区分。可通过“数据 → 分列”功能按分号拆分,或保存为 .csv 后用 Excel 打开)。
使用说明:
- 复制全部内容;
- 在 Excel 中:
- 新建工作表;
- 选中 A1 单元格;
- 粘贴;
- 选择 “数据” → “分列” → “分隔符号” → 勾选“分号”;
- 完成后,每列将正确对齐;
- 若需换行显示(如执行步骤、输入数据),可选中对应列 → “开始” → “自动换行”;
关键注意事项总结(查漏补缺)
1. DOM 结构必须实测,不能假设
- 百度地图 class 名高度混淆(如
.route-list-item不存在); - 解决方案:F12 手动操作 → 观察真实元素 → 复制 XPath/CSS → 验证唯一性。
2. 内部滚动容器 ≠ 页面滚动
- 路线列表、时间轴等都在 固定高度 div 内滚动;
- 必须操作容器的
scrollTop,而非scrollIntoView()。
3. SVG/Canvas 元素需特殊处理
- 地铁站点
<image>是 SVG 元素,Selenium 默认点击可能无效; - 必须用 JS 强制触发点击:
driver.execute_script("arguments[0].click();", el)
4. 动态 ID 和绝对 XPath 极其危险
svgjsImage4371、/html/body/div[1]/...会随加载顺序变化;- 应使用业务语义属性:
name="大行宫"、eletype="0"、data-name等。
5. 截图前必须确保结果已加载
- 不能仅靠
sleep(),应结合 显式等待关键元素(如#cards-level1、.route-wrap); - 若等待失败,临时加 debug 截图定位问题。
6. 时间轴拖动需数学计算
- 21:00 ≠ 最右端;
- 公式:
offset = (container_width / 24) * target_hour - slider_width / 2
