
第1章 下拉框自动化测试里绕不开的“小刺头”做Web自动化测试的朋友应该都有这种感觉页面里最难处理的元素往往不是那些需要复杂等待的弹窗也不是各种框架切换反而是看起来最简单的下拉框。你说它简单它确实就是一个click加一个click的事你说它难一旦遇到非原生的、自定义的、带搜索的、懒加载的下拉框那排查起来的酸爽程度绝对不亚于任何一个疑难杂症。这几年我在公司做UI自动化框架的搭建和维护接触过各种稀奇古怪的下拉框。有最传统的原生select标签有前端框架UI封装的div模拟下拉有通过远程搜索接口加载数据的复合下拉框还有藏在表格里每行都有的小下拉。折腾得多了慢慢积累了一套从定位到操作再到异常排查的完整思路也踩过不少印象深刻的坑。这篇博文就把这套关于Select下拉框的操作经验整理出来分享给大家。先说清楚这篇文章适合谁看。如果你刚接触Selenium没多久正卡在select元素定位不上、操作没反应、或者点击了选项但页面上没变化这种问题上那这篇文章可以帮你少走很多弯路。如果你已经有了一段时间的自动化经验想系统梳理一下select相关操作的细节和底层逻辑那这篇文章同样有参考价值因为里面涉及的不只是API怎么用还有浏览器是如何渲染下拉框的、不同前端实现方式在自动化视角下有何区别这类偏底层的内容。在往下写之前先把一个核心原则亮出来做Web自动化测试永远不要用单纯“看起来能跑”的方式去操作元素而是要搞清楚元素背后的实现原理再选择对应的操作策略。尤其是下拉框同样一个显示效果底层可能是完全不同的实现方式操作方式也截然不同。搞清楚这一点后面所有问题都会迎刃而解。第2章 下拉框的本质先搞清楚你面对的是哪一种很多新手在操作下拉框的时候第一反应是不就是先点击展开再点击选项吗如果我告诉你这个逻辑对一半错一半你可能会觉得我在故弄玄虚。但在实际操作中这确实是最容易出问题的地方。2.1 三种常见的下拉框实现方式在自动化测试的视角下下拉框大概可以分成三类每一类的定位和操作逻辑都完全不一样。第一类原生select标签也就是HTML里的select元素。这种下拉框的选项放在option标签里浏览器原生渲染。Selenium为这类元素专门封装了Select类操作起来非常方便。判断标准很简单用定位表达式找到元素后看它的标签名是不是select就知道了。第二类div模拟下拉框。前端用div加CSS模拟下拉的外观和行为点击之后弹出的选项列表其实就是一个隐藏的div区域。这类下拉框在现在的各种前端框架项目里非常常见尤其是Ant Design、Element UI这些组件库很多组件默认就是用div模拟的。AutoTest脚本无法用Select类去操作这种元素只能模拟真实用户的操作点击展开后再点击目标选项。第三类带搜索功能的复合下拉框。这类下拉框通常基于第二类演化而来多了个输入框支持输入关键字过滤选项有的还支持远程搜索。做自动化测试的时候这类元素不仅要处理展开和点击还可能涉及输入、等待搜索结果加载、选择特定选项等一连串操作复杂度一下子高了很多。我在实际项目里见过一个很有意思的现象同一个系统不同页面里的下拉框有的是原生select有的是div模拟还有的居然混着用。如果你用一个统一的方法去处理所有的下拉框必然会遇到“这个页面能跑通换个页面就报错”的尴尬。这也是为什么我一直强调不管是写工具还是写用例第一步永远是判断元素类型。2.2 为什么原生select不能用纯点击的方式操作这里我想花点篇幅把原生select的原理讲透因为它直接关系到后面所有操作方式的理解。原生select在浏览器里展开的时候弹出的选项列表由浏览器原生绘制它不属于普通DOM的一部分。在自动化脚本里你虽然可以通过click命令让下拉框展开但展开后弹出的那个列表用普通的WebDriver方法去定位选项元素经常会出现定位不到或者定位到了但点击无效的情况。这是因为弹层的结构在DOM里并不是实时存在的或者说在不同浏览器里它的表现方式不一样。Selenium的Select类正是因为考虑了这个问题才专门封装了一套基于option属性的操作方法。它不是通过模拟点击去选中选项而是通过直接改变select元素的选中状态来生效。说白了Select类的工作原理更像是给表单赋值而不是模拟鼠标操作。这就是为什么它对那些“看起来没展开”的select也能直接操作。理解了这个底层机制你就能明白一个很关键的点用Select类操作原生select的时候不做展开动作也没关系因为我们操作的是select元素本身的状态而不是那个弹出层。2.3 一个快速判断下拉框类型的经验方法在实际工作里我一般用一个很快的方法判断下拉框类型。第一步用开发者工具或者Selenium的定位表达式拿到元素。第二步看元素的标签名。第三步如果标签名是select就直接上Select类如果标签名是input或者div就按div模拟下拉框的方式处理。有时候还会遇到伪装得比较深的比如标签名是ul、li组合的或者用canvas绘制的这些就属于纯自定义控件需要寻找容器元素、逐层定位。判断的标准万变不离其宗找到下拉框的展示元素跟一个普通选项的点击目标元素搞清楚这两者之间是什么结构关系就自然知道该怎么操作了。第3章 Selenium Select类的核心方法与实际使用前面讲完了原理这一章进入正题聊聊Selenium Select类具体怎么用。我用的是Java版本的Selenium不过Select类的API在Python版本里也几乎一模一样思路完全可以通用。3.1 引入依赖和构建Select对象如果你用的是Maven项目在pom.xml里加Selenium的依赖就行。当前稳定版本比较常用的是4.x系列我用4.x写示例不过下面要讲的API从3.x到4.x基本没有破坏性变化。dependency groupIdorg.seleniumhq.selenium/groupId artifactIdselenium-java/artifactId version4.21.0/version /dependency然后就是构建Select对象。构建方式很简单把定位到的WebElement传进去就行。WebElement element driver.findElement(By.id(city)); Select select new Select(element);这里有一个隐藏的小问题值得提一下如果传入的WebElement不是select标签Select类在构造的时候会抛异常。具体来说它会检查这个元素是否有select标签名如果没有就会抛出UnexpectedTagNameException。所以如果你在构建Select对象的时候报了类似的错不用怀疑你定位到的肯定不是原生select元素。3.2 三种常用选择方法selectByIndex、selectByValue、selectByVisibleTextSelect类里最常用的选选择方法就三个各自的适用场景也不一样。selectByIndex(int index)是根据选项在列表中的索引来选的索引从0开始。这种方式最直接但它有个先天的缺陷如果下拉框的选项顺序或内容发生变化脚本就会选错选项。所以我的建议是能用Value或VisibleText的时候尽量不要用Index。Index只适合在选项内容不稳定、但顺序相当恒定的特殊场景下用。selectByValue(String value)是根据option的value属性值来选的。这是我最推荐的方式因为value通常是开发人员在代码里定义好的配置项key一般是纯数字或英文标识和页面显示的中文文案没有绑定关系。即使前端改了文案显示只要value不变脚本就还能正常跑。select.selectByValue(beijing);selectByVisibleText(String text)是根据用户在下拉框里看到的文本来选。这种方式最贴近用户视角但风险点在于前端如果改了显示文案你的脚本就挂了。另外如果选项里的文本前后有空格用这个方法匹配也会失败。三种方法怎么取舍我的习惯是优先用Value其次用VisibleText最后才考虑Index。当然如果遇到那些option没有value属性的情况那没办法只能选VisibleText或者Index。3.3 多选下拉框的操作deselect系列方法除单选下拉框还有多选下拉框也就是在select标签上带有multiple属性或者class样式呈现为多选列表。Select类针对多选场景专门提供了一个判断方法isMultiple()返回true就是多选。多选下拉框的独有操作主要是deselect系列deselectByIndex、deselectByValue、deselectByVisibleText以及deselectAll()。对应的逻辑也很直观取消选中某一个选项或者清空所有选中。单选下拉框调用deselect方法会抛异常因为单选下拉框本来就不允许取消选中操作。这个坑我起初也踩过后来养成了一个习惯操作之前先调用isMultiple()做一个分支判断这样脚本的健壮性会好很多。if (select.isMultiple()) { select.deselectAll(); select.selectByValue(beijing); select.selectByValue(shanghai); }3.4 获取选项信息getOptions、getAllSelectedOptions、getFirstSelectedOption除了选择选项有时候我们还需要读取选项信息来做断言。比如测试一个“城市联动”的功能选择了某个省之后城市的选项列表应该跟着变化这时候就需要获取下拉框当前所有选项来验证是否符合预期。Select类提供的方法有getOptions()返回所有选项的WebElement列表。getAllSelectedOptions()返回所有已选中选项的WebElement列表。getFirstSelectedOption()返回第一个已选中的选项。实战里我用得最多的是getOptions()因为它可以配合断言去判断某个选项是否存在、选项数量是否符合预期以及选项文本是否与配置一致。ListWebElement options select.getOptions(); ListString actualTexts options.stream() .map(WebElement::getText) .collect(Collectors.toList()); Assert.assertTrue(actualTexts.contains(北京市));这种读取并断言的方式比纯靠肉眼和人工验证要可靠得多建议大家在自动化用例里多用。第4章 实操难点非原生下拉框的定位与选择策略说实话如果大家测的系统里全是原生select那这一章你根本不用看。但现实情况是现在的前端项目原生select的占比越来越低div模拟的下拉框反而是主流。这一章的实操经验说句不夸张的话全是踩坑换来的。4.1 div模拟下拉框的标准操作流程div模拟下拉框的操作逻辑跟真实用户的操作逻辑完全一致就三步先点击展开下拉层再等待下拉选项可见最后点击目标选项。这里先给一个最简单、最典型的操作示例UI组件库封装的普通下拉框基本都能套用这个流程。// 1. 点击输入框或者下拉框展示区触发下拉层出现 driver.findElement(By.cssSelector(.ant-select-selector)).click(); // 2. 等待下拉选项列表出现 WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement option wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//div[contains(class,ant-select-dropdown)]//div[contains(class,ant-select-item) and text() optionText ]) )); // 3. 点击目标选项 option.click();这个流程看着简单实际执行的时候有几个细节直接影响成败。第一个细节点击触发区域非常关键。有的下拉框点击展示区可以展开点击旁边的箭头图标也能展开但两者的触发逻辑可能不一样。比如某些组件点击展示区是展开下拉点击箭头是清空或切换状态。这种时候如果选错了触发区域展开动作就失败了。第二个细节等待条件一定要等待下拉选项本身可见而不是等待几秒固定时间。下拉层的出现分为两步先出现在DOM里再渲染为可见状态。如果只等待元素存在可能会出现元素存在但点位偏移、点不中的情况。用visibilityOfElementLocated可以稳妥地解决这个问题。第三个细节选项的定位表达式要尽量精确。最常见的翻车场景是页面上存在多个相似下拉框它们的选项都渲染在同一个容器里你定位到的选项可能是另一个下拉框的。解决办法是先定位到当前操作的这一个下拉框容器再在它的范围内查找选项。如果这个下拉框的选项是远程加载到页面底部的隐藏容器那就需要借助一些属性或层级关系来锁定“当前展开的这个下拉框”的选项列表。4.2 带搜索功能的复合下拉框处理带搜索功能的下拉框在Element UI、Ant Design这类组件库里很常见。它的特点是展开后多了一个输入框支持输入文字过滤选项有的是本地过滤有的是远程搜索。本地过滤型的操作流程是点击展开输入关键字等待过滤结果出现点击目标选项。这个流程相对容易因为过滤是前端立即完成的只要输入关键字立刻就能更新选项。远程搜索型的就要麻烦一些因为输入关键字之后选项数据是从后端接口异步加载的什么时候返回、返回什么内容都是不确定的。这种场景下等待策略必须做得更精细。// 远程搜索下拉框点击展开 driver.findElement(By.cssSelector(.el-select__input)).click(); // 输入搜索关键字 driver.findElement(By.cssSelector(.el-select__input)).sendKeys(北京); // 等待搜索结果加载完成这里等待的是某个标志性元素出现 WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//li[contains(class,el-select-dropdown__item) and text()北京市]) )); // 点击选项 driver.findElement(By.xpath(//li[contains(class,el-select-dropdown__item) and text()北京市])).click();这里面有一个很容易被忽略的问题远程搜索接口如果比较慢你输入关键字之后页面会先显示“加载中”的状态如果脚本立刻就去点击选项很可能就会点击失败或者点到上一轮的旧选项。所以在搜索型和远程加载型的下拉框前面等待元素的时候一定不要只等目标选项出现必要的时候还要等待加载状态消失。比如等待loading图标不可见再点击目标选项这样能避免很多莫名其妙的偶发失败。4.3 下拉框选项是异步加载的如何处理有些下拉框页面刚加载出来的时候下拉框和选项都是空的页面先发一个接口请求数据返回后才把选项渲染进去。这种场景下如果你在下拉框还没开始加载数据的时候就展开下拉框可能会看到一个空的面板选不了任何东西甚至点击后什么反馈都没有。这种情况的稳妥做法是先等待下拉框的选项数据加载完成再进行展开和选择的操作。判断数据加载完成的方法有很多最直接的是等待第一个option元素可见。// 等待第一个选项出现表示数据已经加载完成 WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//div[contains(class,ant-select-dropdown)]//div[contains(class,ant-select-item-option)][1]) ));这里再分享一个我自己觉得特别好用的通用思路凡是遇到异步加载数据的下拉框都可以先想清楚“数据从下发到渲染出来界面上会经历什么变化”然后针对这个变化来做等待。是loading图标从有到无等loading消失是选项从无到有等第一个选项出现是选项从不稳定到稳定等一个特定选项出现。这个思路可以覆盖绝大多数动态加载场景。第5章 实战案例一个完整的页面下拉框操作Demo前面理论讲了不少这一章直接给一个完整的实战示例。我模拟一个常见的表单页面场景个人信息填写包含城市下拉框原生select、职位下拉框div模拟、兴趣爱好多选框原生多选select和搜索式技能下拉框远程搜索型。5.1 用例场景描述假设我们要测试的页面是一个员工信息编辑表单页面上有四个需要操作的下拉类型的控件城市原生select单选选项是城市列表需要选择“北京市”。职位div模拟下拉框单选选项是公司职位列表需要选择“测试开发工程师”。兴趣爱好原生select多选选项是若干兴趣爱好需要同时选择“阅读”和“旅游”。技能标签远程搜索型下拉框输入关键字后从后端搜索匹配的技能需要搜索并选择“Java”。这个场景基本覆盖了前面讲到的所有类型下面我们一一写出自动化脚本的完整实现。5.2 完整代码实现与逐行解读城市的操作直接用Select类的最原始API。public void selectCity(String cityText) { WebElement element driver.findElement(By.id(city)); Select select new Select(element); select.selectByVisibleText(cityText); }这里我选了selectByVisibleText而不是value是因为城市的value可能是数字编码在用例代码里直接用“北京市”这种文本更直观可读性更好。职位下拉框是div模拟的需要走展开、等待、点击的完整流程。public void selectPosition(String positionText) { // 点击展示区域展开下拉框 WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement selector driver.findElement(By.cssSelector(.position-select .select-input)); selector.click(); // 等待下拉选项可见 WebElement option wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//div[contains(class,position-dropdown)]//li[text() positionText ]) )); option.click(); }这里有个很多人容易翻车的点展开之后不要立即点击选项一定要加等待。因为下拉层展开有动画动画没结束的时候表面上看着是显示了实际坐标可能还在移动中点击会落到空白位置。用visibilityOfElementLocated等待以后基本可以干掉这类偶发问题。兴趣爱好多选框用Select类操作多选下拉框。public void selectHobbies(ListString hobbies) { WebElement element driver.findElement(By.id(hobby)); Select select new Select(element); // 先判断是不是多选避免异常 if (select.isMultiple()) { select.deselectAll(); for (String hobby : hobbies) { select.selectByVisibleText(hobby); } } }这里之所以每次先deselectAll()是为了保证用例的可重复执行性。你想一下如果上一次跑完之后留了几个已选中的选项下一次跑的时候没有清空就直接选择最后的选中状态就会和预期不一致断言必挂。技能标签的远程搜索下拉框操作流程要复杂一些。public void selectSkill(String keyword, String fullName) { WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); // 点击展开搜索框 WebElement skillInput driver.findElement(By.cssSelector(.skill-select .el-select__input)); skillInput.click(); // 输入关键字 skillInput.sendKeys(keyword); // 等待搜索结果中目标选项出现 WebElement option wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//li[contains(class,el-select-dropdown__item) and text() fullName ]) )); option.click(); }这段代码里有一个小小的隐患如果搜索结果一直不出来或者搜索服务异常这个wait会一直等到超时才会报错。实际项目中我一般会再包一层捕获超时异常然后打印出当前的页面选项列表这样定位问题会方便很多。下面这段是改进版try { WebElement option wait.until(ExpectedConditions.visibilityOfElementLocated( By.xpath(//li[contains(class,el-select-dropdown__item) and text() fullName ]) )); option.click(); } catch (TimeoutException e) { ListWebElement allOptions driver.findElements( By.xpath(//li[contains(class,el-select-dropdown__item)]) ); ListString texts allOptions.stream().map(WebElement::getText).collect(Collectors.toList()); System.out.println(搜索[ keyword ]后下拉选项列表为: texts); throw e; }不要小看这个日志输出。自动化测试最怕的就是失败之后不知道当时页面上到底发生了什么只留一个element not found的报错信息排查起来全靠猜。加上这行打印失败的时候一眼就能看出是搜索结果里压根没有这个选项还是选项有但定位表达式写错了。5.3 这个Demo背后的设计思想看完代码你可能觉得这些东西简单不就是调API吗但我想说的是真正值钱的不是那几行API调用而是这几个细节设计。第一个设计是“每一个下拉框操作都是独立的方法”而不是把四个下拉框的操作都堆在一个大方法里。这样做的好处是后续如果某个下拉框的定位方式变了只需要改对应的一个方法其他调用它的用例完全不用动。第二个设计是“每个方法内部自动完成等待”。有的团队习惯把等待都写在用例层方法里只做点击结果就是用例里到处是Thread.sleep和一堆等待代码又丑又难维护。把等待封装进操作方法里调用方根本不需要关心等待逻辑代码干净维护也方便。第三个设计是“类型不同方法不同”。这四个下拉框没有一个统一的“万能下拉框操作方法”都是针对各自的实现方式单独写。刚开始可能觉得麻烦但是一旦遇到问题这种“一对一”的对应关系会让定位问题变得特别快。第6章 常见坑与排查技巧实录做Web自动化测试最大的特点就是看着代码没问题运行起来各种幺蛾子。这一章我把这几年跟下拉框死磕的过程里最值得记录的坑和排查方法整理出来全是实战经验。6.1 常见问题速查表现象可能原因解决办法Select类构造时报UnexpectedTagNameException定位到的元素不是select标签检查元素类型如果是div模拟下拉框就换div操作方式selectByValue选中后页面没变化value属性值不是你以为的那个值用开发者工具检查实际value或者改用selectByVisibleText下拉框展开后点击选项没反应点击的是隐藏层或者动画未完成等待选项可见后再点击必要时点击选项内部的span或div下拉选项定位到了但总是报元素不可点击选项在视口外或被遮挡先scrollIntoView滚动到可见位置再点击搜索型下拉框输入关键字后没有结果等待时间不够或搜索接口失败加长等待时间打印选项列表辅助判断多个下拉框选项都在同一个容器里没有在指定下拉框范围内定位选项先定位当前下拉框容器再在容器内查找选项下拉框每次运行结果不稳定有异步渲染或动态加载用显式等待替代固定等待等待具体条件满足多选下拉框无法取消选中单选下拉框不支持deselect先判断isMultiple()再决定是否走deselect流程6.2 显式等待的优先级问题在等待下拉框元素的时候三种等待方式里我最推荐的是显式等待也就是WebDriverWait配合ExpectedConditions的方式。强制等待Thread.sleep的问题是太死板环境快的时候浪费几秒环境慢的时候又不够用。隐式等待的问题在于它只能等待元素是否存在不能等待元素是否可点击、是否可见对于下拉框这种存在“加载动画”“展开动画”的场景隐式等待经常等了个寂寞。显式等待可以精确地等待某个状态成立比如“选项可见”“loading图标消失”“某个文本出现”。虽然写起来比前面两个要繁琐一点但稳定性高得多。我现在的习惯是凡是和下拉框打交道的操作一律用显式等待。我还习惯把一些常用的等待条件封装成方法让代码更简洁。比如public void waitForVisible(By locator, int timeoutInSeconds) { WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(timeoutInSeconds)); wait.until(ExpectedConditions.visibilityOfElementLocated(locator)); }6.3 下拉框选项被遮挡的定位与处理有一种很隐蔽的翻车场景右侧是下拉框左侧是固定定位的侧边栏展开下拉框之后选项面板被侧边栏遮挡住一部分。WebDriver点击元素的时候会先检查元素是否可以被点击如果元素的中心点被其他元素覆盖了就会报ElementClickInterceptedException。解决思路有两个。第一个思路是把选项滚动到视野中央再点击WebElement option driver.findElement(By.xpath(...)); ((JavascriptExecutor) driver).executeScript(arguments[0].scrollIntoView(true);, option); option.click();第二个思路是直接通过JavaScript点击绕过WebDriver的可点击性检查WebElement option driver.findElement(By.xpath(...)); ((JavascriptExecutor) driver).executeScript(arguments[0].click();, option);这两个方案没有绝对的好与坏第一种更贴近真实用户操作但要求元素确实在可视区域内第二种成功率更高但本质上是强行触发点击如果页面上有依赖于鼠标事件的逻辑可能会触发不完全。我个人的使用原则是先试常规点击不行再滚到可见位置最后才考虑JavaScript点击。6.4 文本框点击展开的特殊下拉框操作序列最后再讲一种特殊的下拉框形态。这种下拉框表面上是个input输入框不能直接点击展开选项列表而是必须先点击输入框让下拉面板出现然后再处理选项。比如一些日期选择器、带搜索的select以及一些自定义的自动补全组件。操作顺序要特别注意先给input输入框发送一个点击事件让它聚焦然后发送关键字如果是搜索型接着等待下拉面板出现再点击选择。如果漏掉了“等待下拉面板出现”这一步很容易出现“输入内容后立即点击选项但点击事件被输入框的失焦处理逻辑吞掉了”这种奇怪问题。WebElement input driver.findElement(By.id(autocomplete-input)); input.click(); input.sendKeys(测); WebDriverWait wait new WebDriverWait(driver, Duration.ofSeconds(10)); WebElement firstItem wait.until(ExpectedConditions.visibilityOfElementLocated( By.cssSelector(.autocomplete-item) )); firstItem.click();6.5 关于下拉框状态断言的一个小技巧测试下拉框不只要选得上还要验证选完之后的状态是不是正确的。我见过不少用例选完下拉框之后不校验直接在页面上点提交等后端报错了才发现前面选错了。一个实用的做法是选择操作完成之后用getFirstSelectedOption()把当前选中的选项值取出来做断言或者读取展示区的text进行校验。public void assertSelectedText(By selectLocator, String expectedText) { WebElement element driver.findElement(selectLocator); Select select new Select(element); String actualText select.getFirstSelectedOption().getText().trim(); Assert.assertEquals(actualText, expectedText); }第7章 最后再分享一点我的个人经验下拉框这块内容单看每一个知识点都不复杂但组合在一起配合不同的前端框架、不同的业务场景就会衍生出千奇百怪的问题。我在实际项目里最大的感受是页面上的每个控件都有自己的脾气摸透了脾气自动化脚本才能真正稳定下来。方法层面我建议团队里可以沉淀一份“控件操作白皮书”把下拉框、日期选择器、弹窗这类高频控件的标准操作方式统一规范新人照着写就能避免很多低级错误。这份白皮书不是一次写完的每踩一个新坑就往里补一条半年之后就是团队的宝贵资产。框架层面如果公司项目里前端框架用得比较统一比如都是Ant Design那可以写一个针对这个框架的控件操作基类把下拉框、级联选择、日期选择这些封装成通用方法。这样不仅用例写起来快遇到控件升级的时候只需要改基类里对应的一个方法就行。另外想提醒一句不要过度封装。有些团队喜欢写一个“万能控件操作方法”通过枚举类型区分各种控件结果方法参数大量膨胀可读性差得离谱后续维护的人恨不得把写这个方法的人打一顿。控件操作方法的粒度建议保持“一个控件一个方法、一个方法只做一件完整的事”就好。