GrowingIO Design 组件库搭建之单元测试

【React全家桶入门之十一】引入AntDesign组件库 我们的管理系统已经有了图书、用户的增删改查以及登录功能了,可谓是五脏俱全,就是丑了点~ 是不是已经有些厌倦我们系统里的白底黑字和灰色框框了?打起精神,本篇带你使用 AntDesign 组件库为我们的系统换上产品级的UI 阅读详情

前言

GrowingIO Design 是用 React 编写的组件库,本质上就是 React 组件,你可以用像测试其他 JavaScript 代码类似的方式测试 React 组件。现在有许多种测试 React 组件的方法。大体上可以被分为两类:

  • 渲染组件树:在一个简化的测试环境中渲染组件树并对它们的输出做断言检查。

  • 运行完整应用:在一个真实的浏览器环境中运行整个应用。

我们对于第一类称之为单元测试,本文主要专注于这种情况的测试策略;第二类称为端到端(end-to-end)测试,完整的端到端测试在防止对重要工作流的多次回归方面很有价值,对于组件的端到端测试会有专门一篇文章来介绍。

工具调研

对于测试工具的选择,主要从 2020 年的 State of JavaScript Survey 中列出的工具挑选。我们先从“使用度”和“满意度”两个角度来看测试生态圈的比较常用工具。

测试工具使用度对比

测试工具满意度对比

Jest、Storybook 在“使用度”和“满意度”上都获得了比较高的分数,新进入的 Testing Library 在“满意度”上也获得了高分。

注:

满意度:会再次使用 / (会再次使用 + 不会再次使用)

使用度:(将再次使用 + 将不再使用) / 总计

除了以上的几款工具,看看其他工具的用户百分比:

工具选择

先看看 React 官方网站(目前最新版本 v17.0.2)推荐的工具:

  • Jest 是一个 JavaScript 测试运行器。它允许你使用 jsdom 操作 DOM 。尽管 jsdom 只是对浏览器工作表现的一个近似模拟,对测试 React 组件来说它通常也已经够用了。Jest 有着十分优秀的迭代速度,同时还提供了若干强大的功能,比如它可以模拟 modules 和 timers 让你更精细的控制代码如何执行。

  • React Testing Library(简称:RTL)是一组能让你不依赖 React 组件具体实现对他们进行测试的辅助工具。它让重构工作变得轻而易举,还会推动你拥抱有关无障碍的最佳实践。虽然它不能让你省略子元素来浅(shallowly)渲染一个组件,但像 Jest 这样的测试运行器可以通过 mocking 让你做到。

​ 实际上在 v16.7.0 版本的网站上,他们还推荐了另一个工具:

  • Enzyme 是 React 的 JavaScript 测试实用程序,可以更轻松地测试 React 组件的输出。 你还可以操作、遍历和以某种方式模拟给定输出的运行时。Enzyme API 旨在通过模仿 jQuery API 来进行 DOM 操作和遍历,从而变得直观和灵活。

先说说 Jest,Jest = jsdom + Mocha + Sinon + Chai,从这里可以看出 Jest 的强大,而且它还是开箱即用的。

从 2018 年甚至更早,我们一直使用 Jest + Enzyme 来编写的单元测试,但是到 2020 年了,我们需要重新审视一下,选择一个目前来说合适的工具。后文主要拿 RTL 做对比后,先从历史说起。

一点历史

  • 2016 年 3 月 2 日,Airbnb 官宣了 Enzyme——一个用来测试 React 组件的 JavaScript 库。在之前的三个月中,Enzyme 在 GitHub 上收获的 3000 个 Stars,50 个贡献者,其中有 45 个不是 Airbnb 的员工。

  • 2018 年 3 月 15 日,Kent C.Dodds 在社交网站上发布他想做一个更轻量的测试库来替代 Enzyme。同年 4 月 2 日,Kent C.Dodds 在自己的博客上官宣了 React Testing Library——一个更轻量的 React 测试库,集成了 react-dom 和 react-dom/test-utils 的工具函数,提倡更好的测试实践。

  • 2019 年 2 月,React 团队发布了期待已久的新版本 React(v16.8),该版本大幅改变了 API 并引入了 React Hooks。但是 Enzyme 并不支持单独测试 Hooks,而 RTL 可以通过单独库来支持。

  • 2020 年 2 月 28 日,Airbnb 宣布他们将 Enzyme 的所有权转移到了一个外部 GitHub 组织。虽然他们承诺继续支持 Enzyme,但他们也提到 RTL 在他们的项目中越来越受欢迎。

  • 2021 年,目前只有一名开发人员在维护 Enzyme——Jordan Harband。他是一位多产的开源贡献者,是 TC39 委员会的成员(他们定义 JavaScript),并且是一位真正的英雄,他独自维护着这款为全球数百万个测试套件提供支持的工具。

npm trends

上图是 Enzyme 和 RTL 在两年内下载量的趋势,大约在 2020 年 9月,RTL 的下载量实现反超,并在以后的一年里一骑绝尘。

现在看来,整个业界似乎已经转向 RTL 了。

Talk is cheap, Show me code

假设我们现在有 Toggle 这样的一个组件:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

Toggle 组件的测试用例至少包含以下两个:

  1. 当 Toggle 处于 ON 状态时,点击后变成 OFF 状态;

  2. 当 Toggle 处于 OFF 状态时,点击后变成 ON 状态;

使用 Enzyme 来实现,如下:

describe("Toggle", () => {
  let component;  
  beforeEach(() => {
    component = mount(<Toggle />);
  });

  it("can turn off when is on", () => {
    component.instance().handleClick();
    expect(component.state().isToggleOn).toEqual(false);
  });
  
  it("can turn on when is off", () => {
    component.setState({ isToggleOn: false });
    component.instance().handleClick();
    expect(component.state().isToggleOn).toEqual(true);
  });
});

使用 Testing Library 来实现,如下:

describe("Toggle", () => {
  it("can turn off/on", async () => {
    const { container } = render(<Toggle />);
    fireEvent.click(container);
    expect(container.innerHTML).toEqual("OFF");
 
    fireEvent.click(container);
    expect(container.innerHTML).toEqual("ON");
  });
});

小结

借助 RTL,你可以轻松地编写测试,这些测试充分代表了用户如何体验应用程序。比方说,当你用 RTL 编写测试时,你在测试你的应用程序,就像你是与应用程序界面交互的用户一样。

另一方面,当你用 Enzyme 写测试时,即使你也能达到与 RTL 相同的自信水平,以类似于真实用户的方式构建测试结构有点麻烦。

另外的一些实践

快照测试

快照测试是 Jest 的特性,来自 Jest 官网的介绍:

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.

你可以使用测试渲染器快速为 React 树生成可序列化的值,而不是渲染图形 UI,可能需要构建整个应用程序。看一个具体的例子:

import React from 'react';
import renderer from 'react-test-renderer';
import Link from '../Link.react';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="https://www.growingio.com">GrowingIO</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

Link 组件的实现查看:https://github.com/facebook/jest/blob/master/examples/snapshot/Link.react.js

运行 Jest 后,将会生成快照文件,类似这样:

exports[`renders correctly 1`] = `
<a
  className="normal"
  href="https://www.growingio.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  GrowingIO
</a>
`;

快照工件应与代码更改一起提交,并作为代码审核过程的一部分进行审核。

接下来看看 Jest 官网给出的三点最佳实践:

  1. Treat snapshots as code(将快照视为代码)

  2. Tests should be deterministic(测试应该是确定性的)

  3. Use descriptive snapshot names(使用描述性快照名称)

根据我们在 GrowingIO Design 中的实践,不需要为每个组件以及组件的每种状态都生成快照。有以下两点原因:

  • 大多数情况下,修改组件的 CSS 样式名,增加或者删除 Dom 元素,虽然改变了组件的结构但是组件样子并没有改变,这时候就得去更新快照,增加代码审核的工作量。

  • 快照测试通过几行代码就能实现,对代码行测试覆盖率有明显的提高,但是这种测试质量并不高。而且会增加测试命令执行的时间。

Storybook

在《GrowingIO Design 组件库搭建之组件开发》一文中提到组件的文档工具,使用 Storybook 来编写组件 Demo,这些 Demo 可在单元测试工具中重复使用。每个 Demo 在不依赖 Storybook 的情况下都是 “可渲染的”。这意味着任何的测试框架也将能够渲染 Demo。

以下是如何在 RTL 中使用它的示例:

import React from 'react';
import { render, screen } from '@testing-library/react';
import { Primary } from './Button.stories';

it('renders the button in the primary state', () => {
  render(<Primary {...Primary.args} />);
  expect(screen.getByRole('button')).toHaveTextContent('Primary');
});

总结

最看重的一点是 RTL 专注于测试用户体验——毕竟,这才是真正重要的。我们的客户不会看到我们的组件有什么 props,或者它们是数组还是对象,客户只关心它是否正常工作——并且会帮助你在未来交付价值。

React 的未来在于基于函数的组件、React Hooks、异步渲染,而这些特性今天最好搭配 RTL 使用。纵观 Enzyme 过去三年的发展历程,它似乎不太可能赶上所有这些特性,同时还能解决其他那么多问题。

更值得一提的是,使用 RTL 有助于提高组件库的无障碍性(Accessibility,简称 a11y)。对于组件库无障碍性,后面会用一篇文章来详细介绍。

参考

  1. GrowingIO Design:https://github.com/growingio/gio-design

  2. State of JavaScript Survey:https://2020.stateofjs.com/zh-Hans/technologies/testing/

  3. Testing Overview:https://reactjs.org/docs/testing.html

  4. Test Utilities:https://5c54aa429e16c80007af3cd2--reactjs.netlify.app/docs/test-utils.html#overview

  5. Enzyme:https://enzymejs.github.io/enzyme/

  6. Enzyme: JavaScript Testing Utilties for React:https://medium.com/airbnb-engineering/enzyme-javascript-testing-utilities-for-react-a417e5e5090f

  7. Enzyme‘s next Phase:https://medium.com/airbnb-engineering/phase-ii-enzyme-d9efa717e297

  8. Jordan HarBand:https://github.com/ljharb

  9. Snapshot Testing:https://jestjs.io/docs/snapshot-testing

  10. Storybook Unit Testing:https://storybook.js.org/docs/react/workflows/unit-testing

  11. 无障碍:https://developer.mozilla.org/zh-CN/docs/Web/Accessibility

​

构建微信小程序的TDesign组件库实战 TDesign的组件库提供了一套丰富的扩展接口和API,使得开发者可以根据自己的需求扩展组件的功能。同时,TDesign还支持通过插槽(Slot)进行组件内部内容的个性化定制。为了方便开发者创建具有个性化的自定义组件,TDesign提供了一套完整的组件开发指南和示例。开发者可以参考这些文档快速上手,根据业务需求开发出满足特定功能的组件。// 示例代码:创建一个简单的自定义组件},methods: {})在上述示例中,我们定义了一个自定义组件,其中properties。 阅读详情

相关推荐

gdesign-ecs:基于实体组件的引擎(尝试)

框架 基于实体组件的引擎(尝试)

design包8种控件

注意:app命名空间的属性出不来,在color的xml文件上添加 <color name="main_color">#ffffff</color>一、Snackbar:比较像Toast,setAction有点击事件 Snackbar.make(coordinator,"Snackbar",Snackbar.LENGTH_SHORT) .setAction(

liang_autumn_wind的博客 720

某手sig3-ios算法 Chomper黑盒调用

本文主要是介绍Chomper的算法模拟执行,Chomper目前已经已经是能比较完整的模拟ios可执行文件执行的模拟器,在这块有非常大的优势。以前安卓端有强势的unidbg,现在iOS也有Chomper了,后续等待作者持续更新,完善Chomper。强势推荐一波-> Chomper地址: https://github.com/sledgeh4w/chomper。我这块也已经使用Chomper完成雅迪系列、某手的算法调用。后续也会有更多扩展。

成小新的博客 2156

【Ant-Design-Vue】2、基础组件介绍

按钮是用户与应用程序交互的主要方式之一。Ant-Design-Vue 提供了多种按钮类型和样式,以适应不同的使用场景。

weixin_52938153的博客 1619

电源工程师必看:平均电流模式BUCK双环控制详解(从传递函数到Psim仿真)

本文详细解析了平均电流模式BUCK变换器的双环控制策略,从传递函数推导到Psim仿真实现。针对电源工程师关注的环路设计和稳定性问题,深入比较了电压模式、峰值电流模式和平均电流模式的优缺点,并提供了12V/3A BUCK变换器的完整设计案例,帮助工程师掌握平均电流控制这一中高功率应用的首选方案。

weixin_42696271的博客 398

MemSeg:一种差异和共性来检测图像表面缺陷的半监督方法

本文认为人为创建类内差异和保持类内共性可以帮助模型实现更好的缺陷检测能力,从而更好地区分非正常图像。如图一所示。差异(differences):MemSeg引入人工模拟的异常图像在训练阶段使模型能够区分正常和异常的图像,减轻了半监督学习只能用正常样本进行训练的不足,然后在推理阶段可以直接输入图像无需做任何后处理。共性(commonalities):MemSeg引入了一个记忆池来记录正常样本的通用模式,在训练和推理阶段,比较输入图像和记忆池中的样本之间的差异,为异常区域的定位提供有用的信息。

斯人若彩虹,遇上方知有! 4841

ant design组件使用01

dropdown里面是menu组件,,menu组件有自带的阴影样式,,,

qq_36022463的博客 301

Ego Planner规划算法(下)——Ego Planner程序框架

本系列文章用于学习记录Ego-Planner规划算法的相关内容,本系列文章是在在Fast Planner规划算法系列文章的基础上,展开对Ego Planner的相关介绍,主要包括Ego Planner算法流程和程序框架两部分,主要学习资料是深蓝学院的移动机器人运动规划课程

慕羽★的博客 7259

有关AntDesign的简单学习

1.AntDesign简介 AntDesign ,简称 antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。 AntDesign的特点: ???? 提炼自企业级中后台产品的交互语言和视觉风格。 ???? 开箱即用的高质量 React 组件。 ???? 使用 TypeScript 开发,提供完整的类型定义文件。 ⚙️ 全链路开发和设计工具体系。 ???? 数十个国际化语言支持。 ???? 深入每个细节的主题定制能力。 全链路开发和设计指的是什么? 全链

gercke的博客 3724

Orin 调试GMSL camera 96712手册重点

96712基础理解

乐于分享 9191

索尼IMX316 标定_ToF模块相机校准

很多东西一开始给出去的并不是最优的方案,而是在客户端支持中,以及在持续不断的芯片验证中,发现还可以这么做,还能够再提升Sensor的性能,所以说这是一个持续的过程。曾经听说过一个故事,在某厂里ST产品一直作为第一供应商多年,然后近段时间即将被新兴公司的ToF产品所打败,性能报告已经出来,但是ST并没有更新产品,而是在原有产品更新了固件以及标定流程,此时产品的性能又是超越其他供应商的产品。相机矩阵不考虑镜头失真,因为理想的针孔相机没有镜头。为了准确地代表一个真实的相机,相机模型包括径向和切向的镜头畸变。

dream it possible 1154

微信小程序入门学习02-TDesign中的自定义组件

接着官方模板引入了一个自定义组件这里的pull-down-list就是自定义组件,首先是要在我们的index.json文件里引入使用usingCompnents属性来标注我们使用了哪些组件,然后属性名表示我们组件的名称,属性值配置了自定义组件具体的路径…/表示相对路径,这样就找到了根目录下的组件一个自定义组件包含index.js、index.json、index.wxml、index.wxss在index.json中声明这是一个自定义组件在index.js里声明了组件有哪些属性,有哪些方法。

低代码布道师的博客 3686

多物理场耦合仿真-主题032-电磁-流体耦合

电磁-流体耦合,即磁流体动力学(MHD, Magnetohydrodynamics),是研究导电流体在电磁场中运动规律的学科,涉及电磁场与流体力学的深度耦合。本主题系统阐述磁流体动力学的基本理论、控制方程和数值方法。首先介绍MHD的基本概念和物理基础,包括导电流体的性质、电磁场基本方程;然后详细推导MHD控制方程组,包括连续性方程、动量方程、能量方程和电磁场方程;接着讨论MHD流动的特征参数,如Hartmann数、磁雷诺数、相互作用参数等;最后通过六个典型工程案例展示MHD分析的实际应用,包括电磁泵、磁流体

2401_87715305的博客 424

GrowingIO Design 组件库搭建之 CI/CD

前言 在《GrowingIO SaaS 产品 CI/CD 实践》一文中,介绍了持续集成(Continuous Intergration,简称 CI)、持续交付(Continuous Delivery,简称 CD)和持续部署(Continuous Deployment,简称 CD)三个概念,以及在 GrowingIO SaaS 产品中的实践。 文中还强调一个典型的 CI/CD 流程建设至少需要具备以下功能的工具: 代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库

GrowingIO 基于 BitMap 的海量数据分析 466

【存算一体架构实战】四、突破编译壁垒:手把手实现AI模型到存算硬件的自动映射

摘要:存算一体硬件的性能优势难以充分释放,核心瓶颈在于传统编译器无法高效适配"计算-存储融合"的新型架构。本文系统剖析传统编译流程在存算硬件上的三大痛点:数据布局不匹配导致90%带宽浪费、算子映射效率低使硬件利用率不足30%、缺乏专用优化_pass导致延迟居高不下。通过构建MLIR-PIM编译框架,实现从AI模型到存算硬件的全自动化映射,核心流程包括:TensorFlow模型→MLIR Dialect转换→存算优化_pass→硬件指令生成。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 242

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Web基础研发体系:一线工程师的效能操作系统

Web基础研发体系是支撑现代前端工程化落地的核心基础设施,其本质并非技术栈堆砌,而是围绕数据可控性与逻辑可分析性构建的统一运行时底座。它通过State Tree实现状态可序列化、可回放、可协同,借助声明式数据流(如Saga管道)解耦业务逻辑与副作用,将设计稿转代码、无埋点监控、权限集成等能力标准化为可插拔工具链。该体系显著降低跨角色协作摩擦,提升需求交付效率与线上稳定性,适用于中大型Web团队从资源池向能力中心演进的全过程。本文聚焦其操作系统级设计思想与关键落地实践。

381

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Gemma4与阿里编程模型:开源基座与垂直垂类的双轨演进

大语言模型正从通用能力竞赛转向基座-垂类协同演进的新阶段。开源基座模型如Gemma4通过动态稀疏注意力、分段式RoPE和跨模态token对齐,在32B参数量级实现高性价比推理;而垂直领域模型(如阿里DevFlow)则以AST驱动生成、Git历史建模和工作流原生设计,显著提升代码生成在真实开发场景中的可用性与合规性。这种‘强基座+深垂类’范式,不仅重构了模型评估标准(从基准刷分到工作流嵌入),更直接支撑企业级AI编程助手的私有化落地、CI/CD集成与金融级安全审计。本文聚焦Gemma4架构创新与阿里编程模型的

weixin_34072637的博客 454

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Ant Design弹窗组件详解:模态框、抽屉与通知系统实现

在现代Web应用开发中,用户交互反馈是提升体验的关键环节。Ant Design提供了三种核心弹窗组件——Modal(模态框)、Drawer(抽屉)和Notification(通知提醒),分别适用于不同场景的交互需求。本文将详细解析这三类组件的应用场景、核心功能及最佳实践,帮助开发者快速掌握企业级弹窗系统的实现方案。 ## 模态框(Modal):聚焦核心任务的交互窗口 Modal组件作为最常用的...

gitblog_00070的博客 673

手把手教你掌握Design新控件(二)

继上篇 手把手教你掌握Design新控件,没有讲完了,下面继续5、 NavigationView 导航视图NavigationView 导航视图,一般与DrawerLayout(抽屉布局)联合使用。 它为应用程序提供标准的导航菜单, 菜单内容可以通过一个xml菜单文件来填充 <android.support.design.widget.NavigationView

爱开发 739

常用二次封装Ant-design组件(2)--- DatePicker

实现的思路就是把原来的DatePicker这个组件去掉,只保留日期popup面板来进行依附(还好antd能单独对日历面板自定义),但是有个注意点是在使用RangePicker的时候就不能用同样的方法去实现了,不能再将display设置为none,rangePicker在使用的时候面板会对形态获取焦点,获取不到无法填入值是不能进行范围选择的,我这里是用了取巧的方法,样式代码放在下面了。隐藏的那三个方式都不大行,反正只要看不见不影响操作就行,

菠萝萝的博客 1368

GrowingIO Design 组件库搭建之组件开发

前言 在《GrowingIO Design 组件库搭建之开发工具》一文中介绍了搭建组件库的原因和使用的开发工具,这篇文章就来介绍组件库的主角:组件。先从组件的定义说起。 组件的定义 组件是标准化的、可互换的 UI 模块。它们封装了 UI 部分的外观和功能。想想乐高积木。乐高积木可用于建造从城堡到宇宙飞船的所有东西,组件可以拆开并用于创建新功能。 组件通过将状态与应用程序业务逻辑隔离来实现互换性。这样,你可以将复杂的屏幕分解成简单的组件。每个组件都有定义明确的 API 和可被 Mock 的系列状态。这允许组件

GrowingIO 基于 BitMap 的海量数据分析 301

Ant Design组件使用合集(不断更新)

一、Table组件的使用 Table组件中onCell的使用 需求1:描述内容过长时将超出部分隐藏并显示省略号,鼠标悬停查看全部信息 { title: '数据描述', dataIndex: 'desc', onCell: () => { return { //:注意用return style: {//注意:设置行内样式style maxWidth: 50, overflow: 'hidden',

weixin_51719919的博客 3566

手把手教你掌握Design新控件(一)

对于Material Design 控件已经不是新鲜的控件了。 早在2015年,谷歌在推出Android5.0的同时推出了全新的设计Material Design,谷歌为了给我们提供更加规范的MD设计风格的控件,推出了Design支持包,Design常用的控件有下面8个:TextInputLayout 文本输入布局 Snackbar TabLayout 选项卡布局 FloatingActionB

爱开发 1492

Ant Design 组件

Ant Design - 一套企业级 UI 设计语言和 React 组件库

小刘的博客 371

Design各控件的搭配使用

PS:使用design包需要在design项目中导入appcompat包 使用到的控件包括: CoordinatorLayout AppBarLayout----->AppBarLayout.OnOffsetChangedListener的使用 CollapsingToolbarLayout Toolbar RecyclerView CardView----->关于使用 CardView 开发过

gundumw100的专栏 655

GrowingIO服务端开发面试、以及对测试开发、趣头条的一点个人看法。仅供参考

1.简历是一位老哥推荐的,都是网易在实习的,他也知道我后来转Scala了,刚好这家公司是全Scala公司,所以就问了有没有兴趣,此时我在趣头条实习,干的是测试开发,所以也想试试。 我大概是去年2017.11年开始逛牛客的,我基本只刷选择题,主要是计算机网络和Java基础。PS:即使后来基本没有被问到(仅网易实习生面试的时候被问到),当然了我是有基础的,刷题属于是复习。我在2017.7月之前就已经...

梦境迷离 2050
上一篇: iOS App注入SDK调试
下一篇: 数据结构和算法在流程画布中的实际应用
GrowingIO_
博客等级 码龄8年 56粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值