news 2026/7/2 22:26:37

Fastbot智能测试工具:从原理到实战,取代Monkey的Android自动化测试方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Fastbot智能测试工具:从原理到实战,取代Monkey的Android自动化测试方案

1. 项目概述:从“猴子”到“AI探员”的测试进化

如果你做过Android应用的UI自动化测试,或者哪怕只是听说过,大概率对“Monkey”这个名字不会陌生。这个Android SDK自带的测试工具,以其简单粗暴的随机点击、滑动操作,成为了许多开发者进行压力测试和稳定性验证的“老朋友”。但这位“老朋友”的测试方式,就像它的名字一样,充满了不确定性——它像一只真正的猴子在屏幕上乱点,测试路径完全随机,效率低下,且难以复现特定场景的崩溃。对于追求精准、高效和深度覆盖的现代应用测试来说,Monkey已经显得有些力不从心。

今天要聊的,就是字节跳动开源的一款旨在彻底取代Monkey的智能测试工具:Fastbot。它不再是一只“瞎点的猴子”,而更像是一位经过训练的“AI探员”。这位探员能理解你的应用界面结构,学习用户的操作习惯,并基于模型智能决策下一步该点哪里、输入什么,从而以更高的效率、更深的覆盖率去发现那些隐藏的崩溃、ANR(应用无响应)和UI异常。简单说,Fastbot给你的APP做的不是一次“乱拳打死老师傅”的暴力测试,而是一次系统性的“AI体检”,它能更聪明地找到病灶所在。

这篇文章,就是为你准备的一份从零开始,手把手配置和使用Fastbot的完整指南。无论你是负责应用质量的测试工程师,还是希望提升自己应用稳定性的独立开发者,都能通过这篇内容,快速上手这个强大的工具,让它为你的应用质量保驾护航。

2. Fastbot核心原理与优势解析:为什么是“智能”测试?

在深入配置之前,我们有必要先搞清楚Fastbot到底“智能”在哪里。理解其核心原理,能帮助我们在后续使用中更好地配置和解读结果,而不是把它当作一个黑盒工具。

2.1 与Monkey的底层逻辑对比

传统的Monkey测试,其内核是一个伪随机数生成器。它从一组预定义的事件(如点击、长按、滑动、系统按键)中随机选择,再在屏幕坐标范围内随机选择一个位置执行。整个过程完全无视当前屏幕上的内容是什么。这就导致了几个经典问题:

  1. 无效操作极多:大量点击落在了空白区域、状态栏或者无法交互的静态图片上,浪费测试时间。
  2. 关键路径覆盖难:很难通过随机事件恰好触发登录、支付、深层次页面跳转等关键业务流程。
  3. 问题复现如大海捞针:即使发现了崩溃,由于事件序列完全随机且没有上下文记录,复现该崩溃的路径难以追溯。

Fastbot则采用了完全不同的思路。它的核心是一个“基于模型的强化学习智能体”。我们可以把它拆解开来理解:

  • “基于模型”:Fastbot在运行时会实时解析当前Activity的UI布局树(通过Android的AccessibilityService或UI Automator),构建一个当前屏幕的“模型”。这个模型知道哪些控件是可点击的(Button)、哪些是可输入的(EditText)、它们的文本内容是什么、位置在哪里。这就让它摆脱了“盲人摸象”的状态。
  • “强化学习”:Fastbot将测试过程视为一个智能体与APP环境交互的过程。智能体(即Fastbot)执行一个操作(如点击某个按钮),环境(APP)会给出一个反馈(如页面成功跳转、出现崩溃、或状态无变化)。Fastbot内部有一个奖励机制,例如,成功跳转到新页面会获得正奖励,触发崩溃或ANR会获得一个特殊的负奖励(但这正是我们想发现的),长时间停留在同一页面则获得负奖励。通过不断试错和学习,智能体倾向于选择那些能探索更多新状态、触发更多页面跳换的操作策略。
  • “智能体”:这就是做出决策的“大脑”。它根据当前UI模型和历史状态,决定下一个要执行的最优操作。这个决策可能基于一些启发式规则(如优先输入文本框、优先点击带有“登录”、“提交”文字的按钮),也可能基于更复杂的概率模型。

2.2 Fastbot带来的关键优势

基于上述原理,Fastbot相比Monkey展现出几个显著优势:

  1. 测试效率倍增:由于避免了大量无效操作,Fastbot在相同时间内能执行更多“有意义”的交互,从而更快地遍历应用的不同状态和页面。
  2. 路径覆盖更深:其智能策略让它更容易“找到”并触发那些隐藏较深的页面和功能,比如通过连续的表单输入和提交进入后台管理界面。
  3. 问题可复现性高:Fastbot会完整记录下触发崩溃或ANR前的一系列操作步骤(包括操作的对象和内容),生成清晰的日志和截图。这极大简化了开发人员定位和修复问题的过程。
  4. 支持自定义:你可以通过编写“测试脚本”来引导Fastbot,例如,告诉它必须先输入特定的用户名密码完成登录,然后再进行随机探索。这结合了脚本测试的确定性和智能探索的随机性,非常灵活。

注意:Fastbot的“智能”是相对Monkey而言的,它并非一个具备应用业务理解能力的AI。它不理解“购物车”或“朋友圈”的语义,它只知道这是一个可点击的、ID为cart_button的视图。它的目标是探索状态空间,而非验证业务逻辑。业务逻辑的正确性,仍然需要传统的用例脚本或人工测试来保证。

3. 环境准备与Fastbot部署

理论清楚了,我们开始动手。首先需要搭建运行Fastbot的环境。整个过程主要分为两部分:在测试电脑(通常是Windows或Mac)上准备命令行环境,以及在待测Android设备上安装Fastbot的客户端组件。

3.1 电脑端环境搭建

Fastbot的运行控制依赖于电脑端的Python脚本和ADB(Android Debug Bridge)工具。因此,我们需要先确保这两者就绪。

第一步:安装PythonFastbot的控制器脚本是用Python 3编写的。前往Python官网下载并安装最新版本的Python 3.7或更高版本。安装时务必勾选“Add Python to PATH”选项,这样可以在命令行中直接使用python命令。

安装完成后,打开命令行(CMD或PowerShell),输入python --version来验证安装是否成功。

第二步:配置Android SDK Platform-Tools (ADB)ADB是电脑与Android设备通信的桥梁。Fastbot通过ADB发送命令、安装APK、获取UI布局信息等。

  1. 下载Android SDK Platform-Tools。你可以通过Android开发者官网下载独立的platform-tools包,也可以安装完整的Android Studio,它自带platform-tools。
  2. 将platform-tools的目录路径添加到系统的环境变量PATH中。例如,如果你将其解压到了C:\android-sdk\platform-tools,就将此路径加入PATH
  3. 验证:打开新的命令行窗口,输入adb version,应该能看到ADB的版本信息。

第三步:获取Fastbot源码前往Fastbot在GitHub上的官方仓库,你可以直接下载ZIP包,或者使用Git克隆:

git clone https://github.com/bytedance/Fastbot_Android.git

解压或克隆后,你会得到一个目录,其中fastbot文件夹是核心。我们后续的操作主要在这个目录下进行。

3.2 设备端Fastbot安装与权限配置

Fastbot需要在待测设备上运行一个辅助应用(一个APK文件)来执行UI解析和操作。这个APK文件就在你下载的源码包的fastbot目录下,通常名为Fastbot.apk

第一步:安装Fastbot APK使用ADB命令安装此APK到设备:

adb install -r fastbot/Fastbot.apk

参数-r表示如果已存在则替换安装。

第二步:授予关键权限安装成功后,你需要在设备的“设置”->“应用管理”中找到名为“Fastbot”的应用,手动授予它以下关键权限。这是Fastbot能否正常工作的核心:

  • 无障碍服务 (Accessibility Service):这是最重要的权限。Fastbot依赖此服务来获取屏幕上的控件信息。在设置中搜索“无障碍”或“辅助功能”,找到Fastbot并开启其服务。
  • 悬浮窗权限:允许Fastbot在屏幕上显示一个小的控制窗口,用于手动暂停、停止测试。
  • 后台弹出界面权限:确保测试过程中Fastbot的界面能正常显示。
  • (可选)安装未知应用权限:如果你需要Fastbot在测试中自动安装某些APK(如覆盖安装),则需要开启此权限。

实操心得:权限授予是新手最容易卡住的地方。特别是“无障碍服务”,很多手机将其藏在“更多设置”或“高级设置”里。如果测试时发现Fastbot无法点击或获取不到控件,第一个要检查的就是这里。开启后,最好在Fastbot应用内或通过ADB命令验证一下服务是否已激活。

第三步:验证连接与权限在电脑上执行以下命令,检查设备是否已连接且Fastbot服务就绪:

adb devices # 应看到你的设备序列号,状态为`device` adb shell dumpsys package com.bytedance.fastbot | grep version # 查看Fastbot版本,确认安装成功

你可以手动打开设备上的Fastbot应用,如果界面正常,通常表示基础权限已OK。

4. 核心配置文件详解与定制策略

Fastbot的强大之处在于其高度的可配置性。通过修改配置文件,你可以精细地控制测试行为,使其更贴合你的应用。核心配置文件是位于电脑端fastbot目录下的config.properties。我们来逐一拆解关键配置项。

4.1 基础运行参数配置

打开config.properties,你会看到类似以下的内容,我们需要理解并调整它们:

# 测试策略相关 strategy=dfs # 探索策略,深度优先(dfs)或广度优先(bfs),dfs更容易深入单一路径,bfs覆盖更广 depth=10 # 每次测试的最大操作步数(深度) timeout=30 # 全局超时时间(分钟) throttle=200 # 每个操作之间的延迟(毫秒),模拟真人操作速度,可调低以提高测试速度 # 设备与应用相关 package_name=com.example.app # 待测应用的包名,必须修改 serialno=emulator-5554 # 设备序列号,多设备时需要指定
  • package_name:这是最重要的配置,必须改为你待测APP的包名。获取包名的方法有很多,例如adb shell pm list packages | grep your_app_keyword,或者查看APP的AndroidManifest.xml
  • strategydepthdfs策略会沿着一条操作路径尽可能深地探索,适合测试深层次流程;bfs策略则更均匀地探索当前层级的所有可能操作,再进入下一层。对于结构扁平的应用,bfs可能更快覆盖更多界面。depth控制单次探索的深度,设置过大可能导致在某个复杂页面循环过久。
  • throttle:这个值非常实用。设为0会让Fastbot以最快速度执行,但可能因为操作过快导致一些依赖动画或网络请求的页面状态判断出错。设为300-500毫秒更接近真人操作,稳定性更高。

4.2 控件选择与操作权重调整

Fastbot如何决定点哪个按钮?它会给不同类型的控件分配不同的权重。

# 控件操作权重 (值越高,被选中的概率越大) weight.click=10 weight.long_click=5 weight.scroll=8 weight.input=15 # 输入框权重通常较高,因为输入能触发新状态 weight.back=2

如果你的应用有很多需要长按才能触发的菜单(如列表项长按删除),可以适当提高weight.long_click。如果发现Fastbot过于频繁地点击返回键退出关键流程,可以降低weight.back

4.3 黑名单与白名单设置(提升测试精准度)

这是避免无效测试、聚焦核心功能的关键配置。

  • 黑名单 (blacklist.txt):列出你不希望Fastbot操作的控件。比如,应用内的“退出登录”按钮、测试环境下的“清除数据”按钮、第三方广告弹窗的关闭按钮等。一旦误点,会导致测试中断或进入非预期状态。

    • 格式:每行一个控件的部分识别信息,支持通过text(文本)、resource-id(资源ID)、class(控件类名)来匹配。例如:
      text=退出登录 resource-id=com.example.app:id/ad_close_btn class=android.widget.CheckBox
  • 白名单 (whitelist.txt):与黑名单相对,列出只允许Fastbot在特定页面操作的控件。这通常用于将测试范围锁定在某个核心模块内,例如,只测试应用的“设置”页面。使用白名单时,其他页面的所有控件都会被忽略。

    • 格式:同样每行一个匹配规则。

注意事项:黑/白名单的配置需要你对应用的UI结构有一定了解。一个快速获取控件信息的方法是:开启Fastbot测试,让它运行一会儿,然后查看它生成的日志文件(如max.xpath.actions.txt),里面会记录所有它操作过的控件及其属性,你可以从中筛选需要加入名单的项。

4.4 自定义事件与数据池注入

这是Fastbot从“通用测试”走向“针对性强测试”的进阶功能。

  • 自定义事件脚本 (custom_script.py):你可以编写Python脚本,在Fastbot启动前、每个操作前后等钩子点插入自定义逻辑。最常见的用途是处理登录

    # custom_script.py 示例:自动登录 def before_start(device, app): # 判断是否在登录页 if device(resourceId="com.example.app:id/login_button").exists: device(resourceId="com.example.app:id/username").set_text("test_user") device(resourceId="com.example.app:id/password").set_text("password123") device(resourceId="com.example.app:id/login_button").click() # 等待登录成功 device(resourceId="com.example.app:id/home_tab").wait(timeout=5000)

    通过这样的脚本,可以确保Fastbot总是在已登录状态下开始探索,直接进入核心功能测试。

  • 数据池 (data.txt):当Fastbot遇到输入框(EditText)时,会从data.txt中随机选取一行文本进行输入。你可以预先填充这个文件,包含有效的测试数据,如邮箱、手机号、搜索关键词、地址等。这比输入随机乱码更能触发有意义的业务逻辑。

    tester@example.com 13800138000 北京 software testing 这是一个长文本测试数据用于测试输入框的滚动和显示

5. 完整测试执行流程与实战命令

配置妥当后,我们就可以启动一次完整的Fastbot测试了。整个过程在电脑端的命令行中完成。

5.1 单次测试启动与监控

  1. 进入工作目录

    cd path/to/your/Fastbot_Android/fastbot
  2. 确保配置文件正确:再次检查config.properties中的package_name是否正确,并根据需要调整好blacklist.txt/whitelist.txt

  3. 启动测试

    python fastbot.py

    如果一切正常,命令行会开始滚动日志,设备屏幕上的Fastbot小悬浮窗会显示当前状态,并且你会看到APP开始被自动操作。

  4. 测试过程监控

    • 命令行日志:关注是否有CrashANRException等关键字出现。Fastbot会标记出这些异常。
    • 设备屏幕:观察测试行为是否符合预期,是否有陷入死循环(如反复点击同一无效区域)或触发了黑名单功能。
    • Fastbot悬浮窗:可以点击暂停或停止测试。
  5. 测试自然结束:当达到config.properties中设置的timeout时间,或探索在一定时间内没有发现新的可操作状态时,测试会自动停止。

5.2 多轮次与稳定性测试方案

单次测试可能由于随机性无法覆盖所有路径。为了进行深入的稳定性测试(如Monkey常做的12小时/24小时压力测试),我们需要进行多轮次、循环测试。

Fastbot原生支持通过--round参数进行多轮测试。但更常见的做法是编写一个简单的Shell脚本或批处理文件来循环执行,并在每轮之间做一些清理工作。

示例:一个简单的循环测试脚本 (run_stability.sh 或 run_stability.bat)

#!/bin/bash # run_stability.sh MAX_ROUNDS=50 for ((i=1; i<=MAX_ROUNDS; i++)) do echo "=== 开始第 $i 轮 Fastbot 测试 ===" # 启动前,可以强制停止待测应用,确保每轮从冷启动开始 adb shell am force-stop com.example.app # 可选:清除应用数据,让每轮都在全新状态开始(谨慎使用,会清空用户数据) # adb shell pm clear com.example.app # 等待2秒 sleep 2 # 启动Fastbot测试 python fastbot.py # 一轮测试结束后,检查是否有崩溃日志,可以在这里加入邮件通知等逻辑 echo "第 $i 轮测试结束。" # 可选:短暂间隔,让设备降温 sleep 5 done echo "稳定性测试全部完成。"

执行这个脚本:bash run_stability.sh。它会自动进行50轮测试,每轮开始前重启应用,模拟用户长期、多次使用的场景,更容易发现内存泄漏、资源未释放等累积性问题。

5.3 测试结果分析与报告生成

测试结束后,最重要的就是分析结果。Fastbot的输出主要保存在两个地方:

  1. 控制台输出:直接观察命令行最后输出的摘要。它会统计本次测试的总事件数、覆盖的Activity数量、发现的Crash/ANR数量等。

  2. 生成的日志文件(在fastbot目录下):

    • crash-detail.log:记录所有崩溃的详细堆栈信息。这是交给开发人员排查问题的首要文件。
    • anr-detail.log:记录应用无响应(ANR)的详细信息。
    • max.xpath.actions.txt:记录Fastbot执行的所有操作序列,包括操作对象的XPath路径和操作类型。用于复现问题。
    • coverage.txt:记录测试过程中覆盖到的所有Activity名称。用于评估测试覆盖率。
    • screenshots/目录:保存测试过程中截取的屏幕截图,通常在发生异常时自动截图,有助于可视化问题现场。

如何利用这些结果?

  • 问题排查:将crash-detail.log中的堆栈信息复制到IDE或日志分析工具中,能快速定位崩溃的代码行。
  • 路径复现:结合max.xpath.actions.txt和截图,可以清晰地还原导致崩溃的用户操作路径。你可以手动按照这个路径操作,或者编写一个简单的自动化脚本去精确复现。
  • 覆盖率评估:对比coverage.txt和你应用所有的Activity列表,可以直观看到本次测试触发了哪些页面,哪些核心页面还未被覆盖,从而指导你调整黑/白名单或测试策略。

6. 常见问题排查与实战技巧实录

在实际使用Fastbot的过程中,你肯定会遇到各种问题。下面是我在多次实践中总结的一些典型问题及其解决方案,以及一些提升效率的小技巧。

6.1 启动与运行阶段常见问题

问题现象可能原因排查与解决步骤
执行python fastbot.py后立即报错或无反应1. Python环境或依赖问题。
2. ADB设备未连接。
3. 配置文件package_name错误。
1. 确认python --versionadb version命令有效。
2. 执行adb devices确认设备在线且未被其他进程占用。
3. 检查config.propertiespackage_name是否与设备上安装的APP包名完全一致。
Fastbot开始运行,但设备上APP无任何反应,或只停留在首页1. Fastbot无障碍服务未开启。
2. 设备端Fastbot APK未成功运行。
3. 黑名单过于激进,屏蔽了所有控件。
1.首要检查:去设备设置中确认Fastbot的无障碍服务已开启。
2. 在设备上手动打开Fastbot应用,看是否有界面。
3. 临时注释或清空blacklist.txt,观察是否恢复正常。
Fastbot操作速度极快,但大量操作无效(如点击空白处)1.throttle参数设置过小(如0)。
2. UI布局解析延迟,操作发生在页面加载完成前。
1. 将throttle调整为300-500毫秒。
2. 检查网络或应用本身是否加载缓慢。可考虑在custom_script.pybefore_action钩子中加入time.sleep(0.5)等待。
测试频繁触发“退出登录”或进入非测试模块关键控件的黑名单未配置。分析max.xpath.actions.txt,找到触发退出的操作控件,将其特征(如text=退出resource-id)加入blacklist.txt

6.2 测试效果优化技巧

  1. “热身”策略:在正式启动大规模随机探索前,先通过custom_script.py执行一段固定的“热身”脚本,完成登录、跳过引导页、进入主功能界面等操作。这能确保Fastbot大部分时间都在核心业务场景内测试,大幅提升有效测试比例。

  2. 动态黑名单:有些控件只在特定页面出现时才需要屏蔽。可以在custom_script.py中根据当前页面动态地向内存中的黑名单添加或移除规则。这需要更高级的脚本编写能力,但控制精度更高。

  3. 利用max.xpath.actions.txt进行“回归测试”:当你通过Fastbot发现了一个崩溃,并修复后,如何验证修复是否有效?你可以从max.xpath.actions.txt中提取出触发崩溃的那一串操作步骤,将其转换成一个简单的UI Automator或Appium脚本,作为该崩溃点的专属回归用例。这样既能自动化验证修复,又丰富了你的用例库。

  4. 结合CI/CD流水线:将Fastbot集成到你的持续集成平台(如Jenkins、GitLab CI)中。每晚定时对开发中的新构建包进行一轮Fastbot测试,第二天早上直接查看生成的crash-detail.log和覆盖率报告,让问题在合入主干前就被发现。

  5. 多设备并行测试:如果你有多个测试设备(尤其是不同分辨率、不同系统版本的设备),可以编写脚本,同时在不同设备上运行Fastbot,并指定不同的serialno和输出目录。这样可以一次性获得更广泛的兼容性测试结果。

6.3 性能与资源监控

长时间稳定性测试时,需要关注设备状态,避免因过热、内存耗尽等问题导致测试中断。

  • 内存监控:可以在循环测试脚本中,每轮结束后使用adb shell dumpsys meminfo com.example.app来抓取应用的内存快照,观察是否有持续增长的趋势。
  • CPU/温度监控:一些第三方工具或ADB命令可以监控设备温度和CPU占用。如果发现温度过高,应在脚本中增加更长的轮次间隔时间(sleep)。
  • 日志清理:长时间运行会产生大量日志。定期清理旧的日志文件,或使用带时间戳的文件夹来归档每次运行的输出,避免磁盘空间被占满。

从“猴子测试”的随机暴力,到Fastbot的智能探索,这无疑是Android应用自动化测试领域一次显著的效率提升。对我而言,Fastbot最大的价值不在于完全取代人工测试或脚本测试,而是作为一个不知疲倦的“探索者”,在无人值守的时间里,去触及那些人工用例设计可能遗漏的边角场景,去发现那些只有在特定操作序列下才会暴露的深层Bug。它和精准的脚本测试构成了互补的两极:一个负责“广度探索”,一个负责“深度验证”。

配置过程看似步骤不少,但一旦跑通,其收益是持续的。建议你先从一个简单的Demo应用开始,熟悉整个流程和配置项的含义,然后再应用到你的正式项目中。记住,好的黑名单和热身脚本是提升Fastbot测试效率的关键。当你在凌晨收到一封自动发出的邮件,里面是一个由Fastbot发现的、可稳定复现的崩溃日志时,你会觉得这一切的配置都是值得的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 22:25:47

2024年iOS自动化测试指南:告别Facebook版WDA,拥抱Appium官方驱动

1. 项目概述&#xff1a;为什么2024年要告别Facebook版WDA&#xff1f; 如果你是一名iOS自动化测试工程师&#xff0c;或者正在尝试将Appium引入你的移动端测试流程&#xff0c;那么“Facebook版WebDriverAgent”这个名字你一定不陌生&#xff0c;甚至可能因为它而头疼过。在过…

作者头像 李华
网站建设 2026/7/2 22:23:50

AI在自动化测试中的角色定位:从智能助手到自主测试的实践与思考

1. 项目概述&#xff1a;AI在测试领域的角色之争 最近和几个测试团队的朋友聊天&#xff0c;发现一个挺有意思的现象&#xff1a;大家一提到“AI自动化测试”&#xff0c;态度就两极分化。一部分人觉得AI就是个高级点的脚本生成器&#xff0c;顶多算个“助手”&#xff0c;核心…

作者头像 李华
网站建设 2026/7/2 22:21:54

Appium Android自动化测试入门:从环境搭建到实战脚本编写

1. 项目概述&#xff1a;为什么我们需要Appium自动化如果你是一名Android开发者或者测试工程师&#xff0c;每天重复着在手机上点点点、输入输入再输入的操作&#xff0c;是不是偶尔会感到一丝枯燥和低效&#xff1f;尤其是在回归测试阶段&#xff0c;一个功能改动可能需要你把…

作者头像 李华
网站建设 2026/7/2 22:20:29

iOS自动化测试:MAC通过Xcode连接真机与WDA环境搭建指南

1. 项目概述&#xff1a;为什么要在MAC上用Xcode连接真机做自动化测试&#xff1f; 作为一名在iOS开发和测试领域摸爬滚打了多年的老手&#xff0c;我见过太多团队在自动化测试的起步阶段就栽了跟头。最常见的误区就是&#xff1a;只在模拟器上跑自动化脚本&#xff0c;觉得又…

作者头像 李华
网站建设 2026/7/2 22:17:36

Playwright离线部署全攻略:内网环境自动化测试环境搭建

1. 项目概述&#xff1a;为什么我们需要离线部署Playwright&#xff1f;最近在给一个客户部署自动化测试环境时&#xff0c;遇到了一个经典难题&#xff1a;生产服务器位于一个严格的内网环境&#xff0c;完全无法访问外部互联网。客户的需求很明确&#xff0c;他们需要一套基于…

作者头像 李华