大数跨境

Playwright Test Agents 实践(附源码)

Playwright Test Agents 实践(附源码) 慧测
2026-01-08
0
导读:🎭 Playwright Test Agents:AI驱动的UI自动化,让AI成为你的测试工程师,自动规划、生成和修复测试用例

·  ·  ·

图片

但问智能出品

图片
  • 免费获取源码

    huice666/danwen668

  • 原创课程大纲

    https://huicewang.com/testing

  • B 站系列视频

    https://space.bilibili.com/1037858964

内容很长,收藏起来,未来可能用得上哦

🎭 Playwright Test Agents:AI驱动的UI自动化

让AI成为你的测试工程师,自动规划、生成和修复测试用例

📖 目录

1. 引言:测试自动化的新纪元

2. 什么是 Playwright Test Agents?

3. 三大核心Agent详解

4. 快速上手指南

5. 实战案例:TodoMVC应用测试

6. 高级应用场景

7. 最佳实践与技巧

🚀 引言:测试自动化的新纪元

Playwright Test Agents 将 AI Agent 技术与 Playwright 测试框架深度融合,实现了:

✅ 自动化测试规划:AI探索你的应用,生成完整测试计划

 ✅ 智能代码生成:将测试计划转换为可执行的 Playwright 测试

 ✅ 自愈能力:测试失败时自动修复,无需人工干预

 ✅ 持续学习:随着应用演进,测试代码自动适应变化

💡 核心理念:让AI成为你的测试工程师,从规划到执行,全程自动化

🤖 什么是 Playwright Test Agents?

整体架构图

架构概览

Playwright Test Agents 是一套由三个专业化 AI Agent 组成的智能测试系统:

┌─────────────────────────────────────────────────────────┐
   
   
   
│                  Playwright Test Agents                  │
├─────────────────────────────────────────────────────────┤
│                                                           │
│  🎭 Planner      🎭 Generator      🎭 Healer            │
│  (规划者)         (生成器)          (修复者)              │
│     │                │                 │                 │
│     ▼                ▼                 ▼                 │
│  探索应用         生成测试代码       自动修复失败         │
│  生成计划         验证选择器         重新运行测试         │
│                                                           │
└─────────────────────────────────────────────────────────┘

工作流程

技术特点

特性

传统方式

Playwright Test Agents

测试规划

人工编写测试用例文档

AI自动探索应用生成计划

代码编写

手动编写选择器和断言

AI生成完整测试代码

维护成本

UI变更需人工修复

自动检测并修复失败

学习曲线

需要深入学习Playwright API

自然语言描述需求即可

测试覆盖

依赖人工经验

AI系统化探索所有路径

🎯 三大核心Agent详解

1️⃣ 🎭 Planner(规划者)

功能定位

Planner 是测试的"架构师",负责探索你的应用并生成结构化的测试计划。

工作原理

输入                处理流程                    输出
   
   
   
┌──────────┐      ┌──────────────┐         ┌──────────────┐
│ 测试需求  │ ───> │ 1. 运行种子测试│ ───>   │ Markdown     │
│ 种子测试  │      │ 2. 探索应用UI │         │ 测试计划     │
│ PRD文档   │      │ 3. 分析用户流程│         │              │
└──────────┘      │ 4. 生成测试场景│         └──────────────┘
                  └──────────────┘

实战案例:电商网站测试规划

输入提示词

请为我们的电商网站生成一个完整的购物流程测试计划,
   
   
   
包括:浏览商品、加入购物车、结算、支付等场景。中文输出
https://www.saucedemo.com/

Planner 生成的计划(specs/shopping-flow-test-plan.md):

# SauceDemo 购物流程测试计划
   
   
   

## Application Overview

本测试计划涵盖 SauceDemo 电商网站的完整购物流程,包括浏览商品、加入购物车、结算和支付。网站地址:https://www.saucedemo.com/。测试假设从全新状态开始,使用标准用户登录。

## Test Scenarios

### 1. 成功购买流程

**Seed:**`tests/seed.spec.ts`

#### 1.1. 成功购买单个商品

**File:**`tests/shopping-flow/successful-purchase.spec.ts`

**Steps:**
1. 导航到 https://www.saucedemo.com/
2. 在用户名字姓案中输入 'standard_user'
3. 在密码字段中输入 'secret_sauce'
4. 点击登录按钮
5. 在产品页面,点击 'Sauce Labs Backpack' 的 'Add to cart' 按钮
6. 点击购物车链接
7. 在购物车页面,点击 'Checkout' 按钮
8. 在第一步结算页面,输入姓名 'John',姓 'Doe',邮政编码 '12345'
9. 点击 'Continue' 按钮
10. 在概述页面,验证订单详情
11. 点击 'Finish' 按钮

**Expected Results:**
- 用户成功登录到产品页面
- 产品页面显示所有商品
- 购物车标志显示正确数量
- 订单完成页面显示感谢信息

#### 1.2. 购买多个商品

**File:**`tests/shopping-flow/multiple-items-purchase.spec.ts`

**Steps:**
1. 导航到 https://www.saucedemo.com/
2. 登录使用标准用户
3. 添加 'Sauce Labs Backpack' 到购物车
4. 添加 'Sauce Labs Bike Light' 到购物车
5. 点击购物车链接
6. 验证购物车中有两个商品
7. 进行结算流程直到完成

**Expected Results:**
- 用户成功登录
- 产品页面显示所有商品
- 购物车标志显示正确数量
- 订单完成页面显示感谢信息

#### 1.3. 从产品详情页面购买

**File:**`tests/shopping-flow/product-details-purchase.spec.ts`

**Steps:**
1. 登录到系统
2. 点击 'Sauce Labs Backpack' 的标题链接
3. 在详情页面,点击 'Add to cart' 按钮
4. 点击购物车链接
5. 验证购物车内容
6. 完成购买流程

**Expected Results:**
......略

### 2. 产品浏览和排序

**Seed:**`tests/seed.spec.ts`

#### 2.1. 产品排序功能

**File:**`tests/shopping-flow/product-sorting.spec.ts`

**Steps:**
1. 登录到系统
2. 验证默认排序为名称 A-Z
3. 选择排序为名称 Z-A,验证顺序
4. 选择排序为价格低到高,验证顺序
5. 选择排序为价格高到低,验证顺序

**Expected Results:**
......略

#### 2.2. 产品详情页面导航

**File:**`tests/shopping-flow/product-details-navigation.spec.ts`

**Steps:**
......

**Expected Results:**
......略

### 3. 购物车管理

**Seed:**`tests/seed.spec.ts`

#### 3.1. 添加和移除购物车项

**File:**`tests/shopping-flow/cart-management.spec.ts`

**Steps:**

...... 略

💡 关键优势

 ✅ 人类可读:测试计划使用 Markdown 格式,产品经理也能审阅

 ✅ 结构化:清晰的场景划分,便于后续生成和维护

 ✅ 可追溯:每个测试场景都关联到具体的业务需求

2️⃣ 🎭 Generator(生成器)

功能定位

Generator 是测试的"工程师",将 Markdown 计划转换为可执行的 Playwright 测试代码。

工作原理

输入                处理流程                    输出
   
   
   
┌──────────────┐  ┌──────────────────┐     ┌──────────────┐
│ Markdown     │  │ 1. 解析测试步骤   │     │ TypeScript   │
│ 测试计划     │─>│ 2. 实时验证选择器 │ ──> │ 测试代码     │
│              │  │ 3. 生成断言       │     │ .spec.ts     │
└──────────────┘  │ 4. 优化代码结构   │     └──────────────┘
                  └──────────────────┘

实战案例:生成购物车测试代码

输入提示词

请根据 specs/shopping-flow-test-plan.md 生成测试代码,
   
   
   
重点关注"添加商品到购物车"场景。

Generator 生成的代码(tests/cart-management.spec):

// spec: shopping-flow-test-plan.md
   
   
   
// seed: tests/seed.spec.ts

import{ test, expect }from'@playwright/test';

test.describe('购物车管理',()=>{
test('添加和移除购物车项',async({ page })=>{
// 登录到系统
await page.goto('https://www.saucedemo.com/');
await page.locator('[data-test="username"]').fill('standard_user');
await page.locator('[data-test="password"]').fill('secret_sauce');
await page.locator('[data-test="login-button"]').click();
// 添加一个商品到购物车
await page.locator('[data-test="add-to-cart-sauce-labs-backpack"]').click();
// 验证购物车标志显示 '1'
awaitexpect(page.getByText('1')).toBeVisible();
// 点击购物车链接
await page.locator('[data-test="shopping-cart-link"]').click();
// 验证购物车页面显示商品
awaitexpect(page.getByText('Sauce Labs Backpack')).toBeVisible();
// 点击 'Remove' 按钮
await page.locator('[data-test="remove-sauce-labs-backpack"]').click();
// 验证购物车为空
awaitexpect(page.locator('.cart_item')).toHaveCount(0);
// 验证购物车标志不可见
awaitexpect(page.locator('.shopping_cart_badge')).not.toBeVisible();
});
});

💡 关键优势

 ✅ 智能选择器:Generator 实时验证选择器的有效性,避免生成无效代码

 ✅ 完整断言:自动生成结构化和行为化的验证逻辑

 ✅ 最佳实践:遵循 Playwright 官方推荐的代码风格

 ✅ 可维护性:代码注释清晰,关联原始测试计划

3️⃣ 🎭 Healer(修复者)

功能定位

Healer 是测试的"医生",当测试失败时自动诊断问题并修复代码。

工作原理

测试失败 ──> 🎭 Healer 介入
   
   
   
                │
                ├─> 1. 重放失败步骤
                ├─> 2. 检查当前UI状态
                ├─> 3. 定位等效元素
                ├─> 4. 生成修复补丁
                ├─> 5. 重新运行测试
                │
                ▼
           测试通过 ✅ / 标记为跳过 ⏭️

实战案例:自动修复UI变更导致的失败

场景:产品团队将"加入购物车"按钮改为"立即购买"

原始测试代码

await page.getByRole('button',{ name:'加入购物车'}).click();
   
   
   

测试失败日志

Error: locator.click: Timeout 30000ms exceeded.
   
   
   
=========================== logs ===========================
waiting for getByRole('button', { name: '加入购物车' })
============================================================

Healer 自动修复过程

1. 检测失败:识别到选择器超时

2. UI分析:扫描当前页面,发现按钮文本已变更

3. 生成补丁

// 修复前
   
   
   
await page.getByRole('button',{ name:'加入购物车'}).click();

// 修复后
await page.getByRole('button',{ name:'立即购买'}).click();

4. 验证修复:重新运行测试,确认通过

💡 关键优势

 ✅ 零人工干预:UI变更后测试自动适应

 ✅ 智能判断:区分真实Bug和UI变更

 ✅ 安全机制:如果是功能性Bug,会标记测试为跳过而非强制通过

🚀 快速上手指南

环境要求

 Node.js20+

 VS Code:最新版本

 Playwright: 最新版本

 AI工具: VS Code

步骤1:初始化 Playwright Test Agents

解压缩playwright-test-agents.zip然后通过VSCode打开目录VSCode终端执行命令

npminstall
   
   
   

步骤2:创建种子测试(Seed Test)

种子测试是所有测试的起点,提供基础的页面上下文。

创建 tests/seed.spec.ts

import{ test, expect }from'@playwright/test';

test('seed',async({ page })=>{
// 访问应用首页
await page.goto('https://your-app.com');

// 等待页面加载完成
awaitexpect(page.locator('body')).toBeVisible();

// 可选:执行登录等初始化操作
// await page.getByRole('button', { name: '登录' }).click();
// await page.fill('#username', 'testuser');
// await page.fill('#password', 'password123');
// await page.getByRole('button', { name: '提交' }).click();
});

步骤3:使用 Planner 生成测试计划

在 VS Code 中打开 AI 助手,输入提示词:

🎭 Planner,请为我的应用生成一个用户注册流程的测试计划。
   
   
   
使用 tests/seed.spec.ts 作为基础。
测试计划应该包括:
1. 正常注册流程
2. 表单验证(邮箱格式、密码强度)
3. 重复邮箱注册
4. 注册成功后的跳转

Planner 输出:specs/user-registration.md

步骤4:使用 Generator 生成测试代码

🎭 Generator,请根据 specs/user-registration.md 生成测试代码。
   
   
   

Generator 输出:tests/user-registration.spec.ts

步骤5:运行测试并自动修复

npx playwright test
   
   
   

如果测试失败,使用 Healer:

🎭 Healer,请修复失败的测试:tests/user-registration.spec.ts
   
   
   

📚 实战案例:TodoMVC应用测试

让我们通过一个完整的案例,演示如何使用 Playwright Test Agents 为经典的 TodoMVC 应用构建测试套件。

应用介绍

TodoMVC 是一个标准的待办事项应用,功能包括:

 ✅ 添加、编辑、删除待办事项

 ✅ 标记完成/未完成

 ✅ 批量操作(全部标记完成、清除已完成)

 ✅ 过滤器(全部/活动/已完成)

完整工作流程

1. 创建种子测试

// tests/seed.spec.ts
   
   
   
import{ test, expect }from'@playwright/test';

test('seed',async({ page })=>{
await page.goto('https://todomvc.com/examples/react/dist/');
awaitexpect(page.locator('.todoapp')).toBeVisible();
});

2. Planner 生成测试计划

提示词

🎭 Planner,请为 TodoMVC 应用生成完整的测试计划。
   
   
   
使用 tests/seed.spec.ts 作为基础。
覆盖所有核心功能和边界场景。

生成的计划(specs/todomvc-basic-operations.md):

......
   
   
   

生成测试代码

提示词

🎭 Generator,请根据 specs/todomvc-basic-operations.md 生成测试代码。
   
   
   

生成的代码(tests/todomvc-add-todo.spec.ts):

// spec: specs/todomvc-basic-operations.md
   
   
   
// seed: tests/seed.spec.ts

import{ test, expect }from'@playwright/test';

test.describe('Adding New Todos',()=>{
  test.beforeEach(async({ page })=>{
await page.goto('https://todomvc.com/examples/react/dist/');
});

test('Add Valid Todo',async({ page })=>{
// 1. Click in the "What needs to be done?" input field
const todoInput = page.getByPlaceholder('What needs to be done?');
await todoInput.click();

// 2. Type "Buy groceries"
await todoInput.fill('Buy groceries');

// 3. Press Enter key
await todoInput.press('Enter');

// Expected Results:
// - Todo appears in the list with unchecked checkbox
const todoItem = page.getByTestId('todo-item');
awaitexpect(todoItem).toBeVisible();
awaitexpect(todoItem).toHaveText('Buy groceries');

const checkbox = page.getByRole('checkbox',{ name:'Toggle Todo'});
awaitexpect(checkbox).not.toBeChecked();

// - Counter shows "1 item left"
awaitexpect(page.getByText('1 item left')).toBeVisible();

// - Input field is cleared and ready for next entry
awaitexpect(todoInput).toHaveValue('');
awaitexpect(todoInput).toBeFocused();
});

test('Add Multiple Todos',async({ page })=>{
const todoInput = page.getByPlaceholder('What needs to be done?');

// Add three todos
const todos =['Buy groceries','Walk the dog','Read a book'];
for(const todo of todos){
await todoInput.fill(todo);
await todoInput.press('Enter');
}

// Verify all todos appear
const todoItems = page.getByTestId('todo-item');
awaitexpect(todoItems).toHaveCount(3);

// Verify counter
awaitexpect(page.getByText('3 items left')).toBeVisible();

// Verify order
const todoTexts =await todoItems.allTextContents();
expect(todoTexts).toEqual(todos);
});
});

test.describe('Completing Todos',()=>{
  test.beforeEach(async({ page })=>{
await page.goto('https://todomvc.com/examples/react/dist/');
// Add a todo for testing
await page.getByPlaceholder('What needs to be done?').fill('Buy groceries');
await page.getByPlaceholder('What needs to be done?').press('Enter');
});

test('Mark Single Todo as Complete',async({ page })=>{
// Click the checkbox
const checkbox = page.getByRole('checkbox').first();
await checkbox.click();

// Verify strikethrough styling
const todoItem = page.getByTestId('todo-item').first();
awaitexpect(todoItem).toHaveClass(/completed/);

// Verify checkbox is checked
awaitexpect(checkbox).toBeChecked();

// Verify counter
awaitexpect(page.getByText('0 items left')).toBeVisible();
});
});

4. 运行测试

npx playwright test tests/todomvc-add-todo.spec.ts
   
   
   

输出

Running 3 tests using 3 workers
   
   
   
 
  ✓ tests/todomvc-add-todo.spec.ts:8:3 › Adding New Todos › Add Valid Todo (1.2s)
  ✓ tests/todomvc-add-todo.spec.ts:35:3 › Adding New Todos › Add Multiple Todos (1.5s)
  ✓ tests/todomvc-add-todo.spec.ts:58:3 › Completing Todos › Mark Single Todo as Complete (1.1s)
 
  3 passed (4.8s)

5. 模拟UI变更并使用 Healer 修复

场景:假设 TodoMVC 将占位符文本从 “What needs to be done?” 改为 “Add a new task…”

测试失败

Error: locator.click: Timeout 30000ms exceeded.
   
   
   
waiting for getByPlaceholder('What needs to be done?')

使用 Healer

🎭 Healer,请修复失败的测试:tests/todomvc-add-todo.spec.ts
   
   
   

Healer 自动修复

// 修复前
   
   
   
const todoInput = page.getByPlaceholder('What needs to be done?');
 
// 修复后
const todoInput = page.getByPlaceholder('Add a new task...');

重新运行测试

✓ tests/todomvc-add-todo.spec.ts:8:3 › Adding New Todos › Add Valid Todo (1.1s)
   
   
   

🎨 高级应用场景

场景1:复杂的电商结算流程

业务需求

测试一个包含多个步骤的结算流程:

1. 选择商品

2. 添加到购物车

3. 填写收货地址

4. 选择支付方式

5. 确认订单

6. 支付成功

使用 Agents 的优势

传统方式

 需要手动编写100+行测试代码

 每个步骤的选择器需要逐一验证

 UI变更后需要人工定位并修复

使用 Playwright Test Agents

🎭 Planner,请为电商结算流程生成测试计划。
   
   
   
包括正常流程、地址验证、支付失败等场景。
使用 tests/seed.spec.ts(已登录状态)作为基础。

Planner 自动生成包含10+个测试场景的完整计划,Generator 生成可执行代码,Healer 确保长期稳定运行。

场景2:多语言国际化测试

业务需求

验证应用在不同语言环境下的功能正确性。

实现方式

种子测试(tests/seed-i18n.spec.ts):

import{ test as base }from'@playwright/test';

typeLocale='en'|'zh-CN'|'ja'|'es';

const test = base.extend<{ locale: Locale }>({
  locale:['en',{ option:true}],
page:async({ page, locale }, use)=>{
await page.goto(`https://your-app.com?lang=${locale}`);
awaituse(page);
},
});

export{ test };

提示词

🎭 Planner,请为用户注册流程生成多语言测试计划。
   
   
   
需要覆盖英语、中文、日语、西班牙语四种语言。
使用 tests/seed-i18n.spec.ts 作为基础。

Generator 会自动生成参数化测试:

import{ test }from'./seed-i18n';

const translations ={
'en':{ submit:'Submit', success:'Registration successful'},
'zh-CN':{ submit:'提交', success:'注册成功'},
'ja':{ submit:'送信', success:'登録成功'},
'es':{ submit:'Enviar', success:'Registro exitoso'},
};

for(const[locale, texts]of Object.entries(translations)){
test(`User registration in ${locale}`,async({ page, locale: currentLocale })=>{
    test.skip(currentLocale !== locale);

await page.getByRole('button',{ name: texts.submit }).click();
awaitexpect(page.getByText(texts.success)).toBeVisible();
});
}

场景3:API Mock 与测试隔离

业务需求

测试前端逻辑,但不依赖真实后端API。

实现方式

种子测试(tests/seed-with-mock.spec.ts):

import{ test, expect }from'@playwright/test';

test('seed with API mock',async({ page })=>{
// Mock API responses
await page.route('**/api/products',async route =>{
await route.fulfill({
      status:200,
      contentType:'application/json',
      body:JSON.stringify([
{ id:1, name:'Product 1', price:99.99},
{ id:2, name:'Product 2', price:149.99},
]),
});
});

await page.goto('https://your-app.com');
awaitexpect(page.locator('.product-list')).toBeVisible();
});

提示词

🎭 Planner,请为商品列表页面生成测试计划。
   
   
   
使用 tests/seed-with-mock.spec.ts(包含API Mock)作为基础。
测试场景包括:加载状态、空状态、错误状态。

场景4:视觉回归测试

业务需求

确保UI改动不会破坏页面布局和样式。

实现方式

提示词

🎭 Generator,请在生成的测试中添加视觉快照对比。
   
   
   
使用 Playwright 的 toHaveScreenshot() 断言。

生成的代码

test('Homepage visual regression',async({ page })=>{
await page.goto('https://your-app.com');

// 等待页面完全加载
await page.waitForLoadState('networkidle');

// 视觉快照对比
awaitexpect(page).toHaveScreenshot('homepage.png',{
    fullPage:true,
    animations:'disabled',
});
});

💡 最佳实践与技巧

1. 编写高质量的种子测试

种子测试是所有测试的基础,应该:

✅ 保持简洁:只包含必要的初始化逻辑

// ✅ 好的种子测试
   
   
   
test('seed',async({ page })=>{
await page.goto('https://your-app.com');
awaitexpect(page.locator('body')).toBeVisible();
});

// ❌ 不好的种子测试(包含太多业务逻辑)
test('seed',async({ page })=>{
await page.goto('https://your-app.com');
await page.click('.menu');
await page.click('.submenu');
// ... 太多步骤
});

✅ 使用 Fixtures:封装可复用的设置逻辑

// fixtures.ts
   
   
   
import{ test as base }from'@playwright/test';

exportconst test = base.extend({
authenticatedPage:async({ page }, use)=>{
await page.goto('https://your-app.com/login');
await page.fill('#username', process.env.TEST_USER);
await page.fill('#password', process.env.TEST_PASSWORD);
await page.click('button[type="submit"]');
await page.waitForURL('**/dashboard');
awaituse(page);
},
});

2. 优化 Planner 的提示词

明确测试范围

// ❌ 模糊的提示词
   
   
   
"为我的应用生成测试计划"

// ✅ 清晰的提示词
"为用户注册流程生成测试计划,包括:
1. 正常注册(邮箱+密码)
2. 表单验证(邮箱格式、密码强度、必填项)
3. 重复邮箱注册
4. 第三方登录(Google、GitHub)
5. 注册成功后的欢迎邮件验证"

提供上下文

"使用 tests/seed.spec.ts 作为基础。
   
   
   
参考 docs/user-registration-prd.md 中的产品需求。
重点关注边界场景和错误处理。"

3. 合理使用 Healer

何时使用 Healer

 ✅ UI元素位置或文本变更

 ✅ 选择器失效但功能未变

 ✅ 等待时间需要调整

何时不使用 Healer

 ❌ 真实的功能性Bug(应该修复代码而非测试)

 ❌ 业务逻辑变更(需要更新测试计划)

Healer 的安全机制

// Healer 会智能判断失败原因
   
   
   
// 如果是UI变更 → 自动修复
// 如果是功能Bug → 标记测试为 test.skip()
test.skip('This test is skipped because the feature appears to be broken',async({ page })=>{
// ...
});

4. 组织测试文件结构

推荐的项目结构:

your-project/
   
   
   
├── .github/
│   └── agents/              # Agent 定义(自动生成)
│       ├── planner.md
│       ├── generator.md
│       └── healer.md
├── specs/                   # 测试计划(Markdown)
│   ├── user-auth/
│   │   ├── registration.md
│   │   └── login.md
│   ├── shopping/
│   │   ├── cart.md
│   │   └── checkout.md
│   └── admin/
│       └── dashboard.md
├── tests/                   # 测试代码(TypeScript)
│   ├── seed.spec.ts
│   ├── fixtures.ts
│   ├── user-auth/
│   │   ├── registration.spec.ts
│   │   └── login.spec.ts
│   ├── shopping/
│   │   ├── cart.spec.ts
│   │   └── checkout.spec.ts
│   └── admin/
│       └── dashboard.spec.ts
└── playwright.config.ts

🎉 结语

Playwright Test Agents 不仅仅是一个工具,它代表了测试自动化领域的范式转变。通过将 AI 的智能与 Playwright 的强大能力结合,我们可以:

 解放测试工程师:从重复性工作中解脱,专注于更有价值的测试策略

 提升产品质量:更高的测试覆盖率,更快的Bug发现

 加速交付速度:测试不再是瓶颈,而是加速器

现在就开始你的 Playwright Test Agents 之旅吧!

让AI成为你的测试工程师,开启智能测试新时代! 🚀

 实测:100 个用例执行时间 < 2 分钟

图片
huice666
图片
danwen668


【声明】内容源于网络
0
0
慧测
专注人工智能前沿技术落地企业实战应用
内容 404
粉丝 0
慧测 专注人工智能前沿技术落地企业实战应用
总阅读104
粉丝0
内容404