☰
Avito VAS 前端实习生测试任务全解:从零构建可序列化的 Banner 编辑器应用
2026/10/9 5:25:23 网站建设 项目流程
  • 教程

【免费下载链接】ru-test-assignments

Тестовые задания для самостоятельного выполнения от разных it компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载

导读

本文围绕 Avito VAS 团队(增值服务团队)的前端实习生测试任务展开:在两周内实现一个Banner 编辑器——通过表单填写参数、实时预览、序列化为 JSON,并支持将 Banner 导出为 PNG 图片、HTML/JSX 标记字符串与 JSON 配置。文章将完整拆解原任务文档中的功能需求与验收标准,给出数据模型设计、导出管线(canvas / 标记序列化 / 剪贴板)等实现路径,帮助你将该任务从需求文档落地为可在localhost:3999运行的可交付应用。

原始任务文档位于仓库 frontend/avito-tech/vas-frontend-trainee-assignment.md,本文以该文档为骨架,并结合作者所在的开源测试任务目录 README.md 的说明(该目录收录约 400 个真实企业测试任务、刻意不放解决方案)进行深入解读。

一、任务全景:产品目标与技术边界

VAS(Value Added Services)是 Avito 的增值服务方向,该任务要求在浏览器中实现一个Banner 编辑器(приложение-редактор для создания баннеров)。产品参照物是 Avito 主站 stories 中的 Banner 视觉风格,但最终的设计、框架与第三方库完全由候选人自行决定——这是任务对技术自由度最明确的放权。

核心闭环可以概括为一条单向工作流:

表单填写参数 → 实时预览 → 序列化为 JSON 配置 ↓ 导出:PNG 图片 / HTML 或 JSX 标记 / JSON 字符串

任务明确要求:表单内容可以序列化为json,得到的 Banner 可以导出为图片,也可以导出为标记(разметка)。这意味着「表单状态」与「JSON 配置」应当是同一份数据的两面,为后续的导出、恢复编辑、版本保存打下基础。

二、应用组成:三大核心模块

按原文档,应用由以下部分组成:

模块职责
Banner 预览(Превью баннера)实时渲染当前配置下的 Banner,所见即所得
参数输入表单(Форма ввода параметров)收集 Banner 的插图、文本、背景、链接等全部可配置项
导出面板(3 个导出按钮)① 保存为 PNG 图片;② 复制 Banner 为 HTML 或 JSX 字符串;③ 复制配置为 JSON 字符串

其中第 ② 项原文表述为「复制到剪贴板,作为html或jsx字符串(由你决定)」,即二选一即可,不必同时支持两种格式;第 ③ 项则是把当前表单对应的配置序列化后复制到剪贴板。

2.1 预览区:单一数据源驱动渲染

预览区应作为单一数据源(single source of truth)的只读投影:表单的任何改动即时反映到预览,而导出逻辑同样消费这份状态,而不是各自维护副本。这样能保证「预览、PNG、HTML/JSX、JSON」四者永远一致,避免出现「预览好看但导出变了样」的经典翻车点。

2.2 表单区:覆盖全部可配置参数

表单需要至少覆盖第 3 节中 Banner 的全部能力项,包括插图来源(URL 或本地文件转 dataURI)、文本行内容与字号、背景类型(纯色/渐变)及其参数、跳转链接等。

三、Banner 能力需求拆解(功能验收重点)

原文档给出了 Banner 必须支持的 4 项能力,这是功能验收与自测的核心清单:

3.1 插图:URL 或 dataURI 双通道

Banner 可以带插图,来源有两种:

  • URL:直接填写图片地址;
  • dataURI:本地选择文件后,经FileReader.readAsDataURL转为 base64 的 data URI 再回填。

选择 dataURI 通道有一个技术上的额外收益:PNG 导出走 canvas 时,外部 URL 图片会触发CORS 污染(tainted canvas),导致canvas.toDataURL()抛错;而 dataURI 属于同源内联资源,不会污染画布。如果任务要求「任意 URL 都可导出 PNG」,则建议在导出管线中对跨域插图统一做 CORS 代理或预取转码处理(此点属于实现建议,原文档未强制规定)。

3.2 文本:最多 3 行、任意长度

Banner 最多展示3 行文本,但文本内容本身可以任意长。这是典型的「视觉截断」需求,推荐 CSS 方案:

.banner-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; /* 最多 3 行 */ overflow: hidden; /* 可选:text-overflow: ellipsis 配合省略号 */ }

需要特别注意:预览、HTML/JSX 导出、PNG 导出三处必须采用一致的截断策略。CSS-webkit-line-clamp只对浏览器渲染有效;手动 canvas 绘制时需自行按行高与字号计算换行、截断到 3 行,才能保证导出图片与预览一致。

3.3 背景:纯色(color)或渐变(gradient)

背景支持 CSScolor与gradient两类取值:

  • 纯色:如#FF6633、rgba(0, 0, 0, 0.5);
  • 渐变:如linear-gradient(135deg, #ff8a00, #da1b60)、radial-gradient(...)。

表单层建议做成类型切换(单选「纯色 / 渐变」+ 对应参数输入),预览层直接用 CSSbackground属性渲染。导出 HTML/JSX 时该字符串可原样内联;导出 PNG 时若采用「DOM 截图」类方案(如 html-to-image、html2canvas),渐变会由库自动光栅化,无需手工解析。

3.4 点击行为:按链接跳转

点击 Banner 可以跳转到指定链接。原文特别强调该能力作用在**导出标记(разметка)**的场景:即导出的 HTML/JSX 中,Banner 应被包裹为可点击的元素,例如:

<a href="https://www.avito.ru/" target="_blank" rel="noopener noreferrer"> <div className="banner">{/* 渲染内容 */}</div> </a>

预览区内是否允许直接点击跳转属于可选交互,建议至少保证「导出标记」形态下链接可用。

四、数据模型设计:表单与 JSON 的映射

「表单可序列化为 JSON」是任务的核心约束,因此建议把表单状态建模为一份扁平、可逆、无冗余的配置对象。一个可行的参考结构如下:

{ "width": 320, "height": 200, "illustration": { "type": "url", "value": "https://example.com/promo.png" }, "text": { "lines": [ "Продавайте быстрее", "Новый сервис Авито", "Подробности по ссылке" ], "fontSize": 16, "color": "#FFFFFF" }, "background": { "type": "gradient", "value": "linear-gradient(135deg, #FF8A00, #DA1B60)" }, "link": "https://www.avito.ru/" }

设计要点:

  • illustration.type区分url与dataURI:导出与渲染时据此决定资源处理方式;
  • text.lines数组:对应「最多 3 行」的约束,便于导出时逐行排版;
  • background.type+value:把「纯色/渐变」的类型判断和具体 CSS 值分离,避免用字符串前缀做类型嗅探;
  • link独立成字段:预览与导出标记共用。

表单控件与该 JSON 一一绑定即可实现状态 ↔ JSON的双向转换:JSON.stringify(config)得到导出字符串,JSON.parse后可回填表单继续编辑。建议为序列化/反序列化编写单元测试(见第 7 节),这正是原文档「欢迎编写测试」最值得投入的切入点。

五、导出实现方案:三条管线的技术要点

5.1 PNG 导出

保存 Banner 为png有两条主流路线:

  1. DOM 截图库:使用html-to-image/html2canvas/dom-to-image一类库,对预览 DOM 做快照并返回 dataURL,再触发下载。优点是与预览视觉 100% 一致;缺点是受 CSS 特性支持与跨域图片限制影响;
  2. 手动 canvas 绘制:直接用 Canvas 2D API 按配置逐项绘制(背景渐变、插图、三行文本),然后canvas.toDataURL('image/png')。优点是可完全控制像素结果、天然规避 DOM 渲染差异;缺点是需自行实现文本截断与排版。

下载触发可统一封装:

function downloadPng(dataUrl, filename = 'banner.png') { const a = document.createElement('a'); a.href = dataUrl; a.download = filename; a.click(); }

若采用路线 1,务必确认所选库对background、dataURI插图与-webkit-line-clamp的渲染结果与浏览器原生预览一致(不同库对现代 CSS 的支持度差异明显,可以借助测试用例锁定回归)。

5.2 HTML / JSX 标记导出

导出 HTML 或 JSX 字符串并复制到剪贴板,其核心要求是导出的标记自包含、可直接粘贴复用:

  • HTML 版本:内联样式(style属性)优于外链样式表,确保脱离应用环境后样式不丢失;
  • JSX 版本:注意把class转为className、style中的属性名转为驼峰(如background-image→backgroundImage)、<a>的target/rel属性按 React 规范书写。

复制到剪贴板建议使用异步 Clipboard API,并处理浏览器权限与降级:

await navigator.clipboard.writeText(markup); // 降级方案:document.execCommand('copy') 兜底旧浏览器

「复制成功」需要给用户可见反馈(按钮文案变化或 toast),这是评审体验中容易被忽略的细节。

5.3 JSON 配置导出

JSON 导出最直接:JSON.stringify(config, null, 2)得到可读字符串,同样走剪贴板 API 复制。建议序列化前做一次「干净化」——去掉表单 UI 的临时状态(如错误提示、选中框),只保留纯配置字段,保证复制出去的 JSON 可被JSON.parse直接恢复。

六、技术选型与工程化建议

原文档明确「设计、framework 和库由你决定」,因此不存在「必须用 X」的约束。结合任务形态(表单 + 预览 + 剪贴板/下载),推荐但不限于:

维度建议
框架React / Vue / Svelte 均可;React 生态在 DOM 截图、测试工具方面资料最丰富
状态管理简单场景用组件内 state 或useState/reactive即可;表单字段多时可引入轻量表单库或自定义 hook
样式方案纯 CSS / CSS Modules / Tailwind / Styled-Components 任选,预览与导出样式需复用同一套规则
构建工具需确保开发服务器端口为3999(见验收标准)
类型系统可选 TypeScript,为 JSON 配置定义interface BannerConfig可显著降低序列化出错的概率

端口 3999 的落地方式随构建工具而异,例如:

  • Create React App:package.json中设置"start": "PORT=3999 react-scripts start"或依赖.env中的PORT=3999;
  • Vite:在vite.config的server.port配置为3999;
  • Webpack(devServer):devServer: { port: 3999 }。

七、验收标准与本地运行

原文档给出的验收条件必须逐条满足,这是「可交付」的最低门槛:

  1. 期限:任务需在2 周内完成;
  2. 可下载:最终代码发布到 GitHub(或等效托管),评审方可git clone;
  3. 可运行:克隆后执行npm install && npm start即可启动;
  4. 可访问:启动后浏览器访问localhost:3999。

因此提交前建议在干净环境(如全新 clone 的临时目录)完整走一遍git clone → npm install → npm start流程,并确认:

  • 首次npm install无报错、无缺失依赖;
  • npm start后端口确实为 3999(而非默认的 3000/5173);
  • 三个导出按钮在主流浏览器(Chrome/Firefox)中可用;
  • 表单任意改动后预览即时更新。

八、测试策略:让「欢迎写测试」落到实处

原文档对测试的态度是「欢迎」(Приветствуется написание тестов),建议按投入产出比优先覆盖以下三层:

  1. 序列化单元测试:给定表单状态,JSON.stringify后JSON.parse再回填,断言配置完整无损(含 dataURI 长字符串、渐变值、3 行文本边界);
  2. 导出快照测试:对固定配置生成 HTML/JSX 字符串,与快照比对,防止样式或结构被意外改动;
  3. 联动组件测试:模拟表单输入 → 断言预览区 DOM 更新;模拟点击导出按钮 → 断言剪贴板/下载行为被正确触发(可用jsdom+ Testing Library / Vitest)。

文本 3 行截断与渐变背景是最容易出现「预览/导出不一致」的区域,建议把它们单独抽成纯函数或渲染组件并配上边界用例(空文本、超长文本、非法渐变值)。

九、仓库背景与练习建议

本仓库 README.md 说明:该目录是面向求职练习的开放题库,收录约 400 个来自近 200 家公司的真实测试任务,且刻意不包含解决方案——「没有答案正是练习的意义」。这意味着本文给出的架构与实现思路属于通用技术路径,最终代码仍需你亲手完成并提交。

仓库中同一目录下还有 Avito 的其他前端实习任务可供横向对比练习,例如 frontend/avito-tech/ap-frontend-trainee-assignment.md(Avito People 团队,Hacker News 客户端)、frontend/avito-tech/sx-frontend-trainee-assignment.md(Seller Experience 团队)等,均可在 frontend/avito-tech/ 中查看,便于把握 Avito 各团队对前端实习生的能力考察侧重点。

十、交付自检清单

提交前逐项核对,覆盖原文档全部验收点:

  • 应用包含预览、表单、3 个导出按钮三个模块
  • 插图支持 URL 与 dataURI 两种来源
  • 文本最多显示 3 行,任意长度内容可正常截断
  • 背景支持纯色 color 与 gradient 渐变
  • 导出的 HTML/JSX 标记中 Banner 可点击跳转
  • 表单状态可序列化为 JSON,且 JSON 可恢复回表单
  • PNG / HTML 或 JSX / JSON 三种导出均可用
  • git clone后npm install && npm start可运行
  • 浏览器通过localhost:3999可访问
  • (加分)序列化、导出与联动行为有测试覆盖

完成上述清单,你就不仅交付了一个满足 Avito VAS 团队验收要求的 Banner 编辑器,也完整演练了「需求拆解 → 数据建模 → 多端导出 → 工程落地 → 测试收口」的前端实战链路。

  • 教程

【免费下载链接】ru-test-assignments

Тестовые задания для самостоятельного выполнения от разных it компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载
上一篇:Security-101 零信任安全模型详解:从「信任但验证」到「永不信任,始终验证」
下一篇:用 Workbrew 把 Homebrew 变成企业级包管理:Fleet 集成实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询