【JavaScript脚本宇宙】从Cypress到Nightwatch.js:全面解析前端自动化测试工具

深度剖析:各大前端测试框架的特点与优劣势

前言

本文将介绍六种流行的前端测试工具,包括Cypress、TestCafe、Selenium、Puppeteer、Playwright和Nightwatch.js。每种工具都有其独特的功能特点和优缺点,并在不同的使用场景中发挥作用。通过本文的介绍和案例分析,读者可以更好地了解这些工具,并选择最适合自己项目的解决方案。

欢迎订阅专栏:JavaScript脚本宇宙

文章目录

1. Cypress:一个现代的前端测试工具

1.1 简介

Cypress是一个现代的前端测试工具,它是一款基于JavaScript的自动化测试框架,具有简单、直观、易用等特点。Cypress可以帮助开发人员轻松地测试Web应用程序的前端功能,提高应用程序的质量和稳定性。

官方网站:cypress.io

1.2 功能特点

1.2.1 实时重新加载

Cypress的实时重新加载功能可以实时查看测试结果和代码更改,无需手动重新运行测试。这可以大大加快测试过程,提高开发效率。

代码示例:

it('should have a title', () => {
    cy.visit('https://example.com')
    cy.title().should('include', 'Example')
})
1.2.2 快速调试

Cypress提供了丰富的调试工具,例如命令日志、时间旅行、断点调试等,可以帮助开发人员快速定位和解决测试问题。

代码示例:

it('should have a title', () => {
    cy.visit('https://example.com')
    cy.title().should('include', 'Example')
})
1.2.3 全截图和视频录制

Cypress可以自动截取每个测试步骤的屏幕截图和记录视频,方便开发人员查看和分析测试过程。

代码示例:

it('should have a title', () => {
    cy.visit('https://example.com')
    cy.title().should('include', 'Example')
})

1.3 优缺点

1.3.1 优点
  • 简单易用:Cypress的语法简洁明了,易于上手。
  • 丰富的调试工具:Cypress提供了丰富的调试工具,可以帮助开发人员快速定位和解决测试问题。
  • 实时重新加载:Cypress的实时重新加载功能可以实时查看测试结果和代码更改。
  • 全截图和视频录制:Cypress可以自动截取每个测试步骤的屏幕截图和记录视频。
1.3.2 缺点
  • 学习曲线:对于初学者来说,可能需要一些时间来熟悉Cypress的语法和功能。
  • 依赖性问题:Cypress依赖于一些特定的库和模块,可能需要额外的配置和管理。

1.4 使用场景

Cypress 适用于各种前端测试场景,特别是以下几种:

  • 单页应用(SPA)的端到端测试
  • 多页面Web应用的集成测试
  • 表单验证和提交流程测试
  • 用户交互的自动化测试

1.5 安装与配置

在开始使用 Cypress 之前,你需要先安装它。可以通过 npm 或者 yarn 安装:

npm install cypress --save-dev

或者

yarn add cypress --dev

安装完成后,可以通过执行以下命令启动 Cypress:

npx cypress open

1.6 基本用法

创建一个简单的端到端测试用例:

// cypress/integration/sample_spec.js
describe('My First Test', () => {
  it('Visits the Kitchen Sink', () => {
    cy.visit('https://example.cypress.io')
    cy.contains('type').click()
    cy.url().should('include', '/commands/actions')
    cy.get('.action-email')
      .type('fake@email.com')
      .should('have.value', 'fake@email.com')
  })
})

1.7 实际案例

下面通过一个实际案例来演示如何使用 Cypress 进行复杂的端到端测试。

首先,假设我们有一个待测试的电商网站,我们希望验证用户能够成功登录并进行商品搜索。

// cypress/integration/login_and_search_spec.js
describe('E-commerce site tests', () => {
  before(() => {
    // 访问登录页面
    cy.visit('https://example-ecommerce.com/login')
  })

  it('Should login successfully', () => {
    // 输入用户名和密码
    cy.get('#username').type('testuser')
    cy.get('#password').type('password123')
    cy.get('button[type="submit"]').click()

    // 验证登录成功
    cy.url().should('include', '/dashboard')
    cy.contains('Welcome, testuser')
  })

  it('Should search for a product', () => {
    // 搜索商品
    cy.get('#search-bar').type('Laptop{enter}')

    // 验证搜索结果
    cy.url().should('include', '/search?q=Laptop')
    cy.contains('Results for "Laptop"')
  })
})

通过以上代码,我们展示了如何使用 Cypress 编写端到端测试,验证用户能够成功登录并进行商品搜索。更多详细信息请参考 Cypress 官方文档.

2. TestCafe:一个用于端到端测试的JavaScript库

TestCafe是一个基于Node.js的自动化测试工具,主要应用于Web应用程序的端到端测试。它提供了丰富的API和简单的语法,使开发人员能够轻松编写出可靠、可维护的自动化测试用例。本文将为您介绍TestCafe的基本功能、优点和缺点,以及如何安装和配置TestCafe来执行测试用例。

2.1 简介

TestCafe是一个开源的自动化测试框架,适用于各种现代网络应用程序。它采用了独特的无浏览器驱动程序方法,使得测试用例的编写更加简单和直观。TestCafe支持多种操作系统,包括Windows、Mac和Linux,并且可以在任何主流Web浏览器上运行测试。

重要链接:

2.2 功能特点

以下是TestCafe的一些主要功能特点:

2.2.1 跨浏览器测试

TestCafe支持多种主流Web浏览器,包括Google Chrome、Mozilla Firefox和Microsoft Edge等。您可以在一个测试环境中针对多个浏览器执行测试,从而提高应用程序的兼容性。

2.2.2 无需WebDriver

与传统的自动化测试工具不同,TestCafe不需要依赖第三方的WebDriver库。这使得TestCafe更加轻量级且易于设置和维护。

2.2.3 内置等待机制

TestCafe内置了智能等待机制,可以自动检测并等待页面元素加载完毕后再进行操作。这使得开发人员无需担心异步操作导致的测试不稳定性问题。

2.3 优缺点

2.3.1 优点
  • 简单易学: TestCafe采用了简洁直观的语法,使开发人员能够快速上手并编写出高质量的自动化测试用例。
  • 跨平台支持: TestCafe可以在多种操作系统和Web浏览器上运行测试,使您能够在不同环境中验证应用程序的功能。
  • 无需WebDriver: TestCafe去除了对第三方库的依赖,简化了测试环境的搭建和管理过程。
  • 内置等待机制: TestCafe的智能等待机制减少了开发人员处理异步操作的工作量,提高了测试的稳定性和可靠性。
  • 丰富强大的API: TestCafe提供了丰富的API和内置实用程序,使开发人员能够轻松模拟用户交互并验证应用程序的行为。
2.3.2 缺点
  • 社区相对较小:相比一些老牌工具,TestCafe 的社区支持相对较少。
  • 插件生态:虽然功能强大,但可扩展性和第三方插件支持尚不如 Selenium 强大。

2.4 使用场景

TestCafe 适用于各种前端应用的端到端测试,特别是那些需要跨浏览器兼容性的项目。无论是单页应用 (SPA) 还是传统的多页应用,都可以通过 TestCafe 进行高效的自动化测试。

2.5 安装与配置

要安装 TestCafe,只需要使用 npm 或 yarn 命令:

npm install -g testcafe

或者

yarn global add testcafe

安装完成后,你可以直接在命令行运行 TestCafe 进行测试,例如:

testcafe chrome my-tests/**/*.js

2.6 基本用法

创建一个简单的测试文件 test.js

import { Selector } from 'testcafe';

fixture `基本用法示例`
    .page `http://example.com`;

test('填写表单并提交', async t => {
    await t
        .typeText('#developer-name', 'Jane Doe')
        .click('#submit-button')
        .expect(Selector('#result').innerText).eql('Thank you, Jane Doe!');
});

然后在命令行运行这个测试:

testcafe chrome test.js

2.7 实际案例

假设我们有一个登录界面,需要测试用户登录功能。创建一个名为 login-test.js 的文件,并编写如下代码:

import { Selector } from 'testcafe';

fixture `登录测试`
    .page `http://example.com/login`;

test('用户可以成功登录', async t => {
    await t
        .typeText('#username', 'testuser')
        .typeText('#password', 'password123')
        .click('#login-button')
        .expect(Selector('#welcome-message').innerText).eql('Welcome, testuser!');
});

在命令行中运行测试:

testcafe chrome login-test.js

上述代码将模拟用户输入用户名和密码,并验证登录后的欢迎消息是否正确显示。

更多详细信息和高级用法,请参考 TestCafe 官方文档

3. Selenium:广泛使用的开源自动化测试框架

Selenium是一个用于Web应用程序测试和验证的开源工具。它允许测试人员使用多种编程语言自动化浏览器交互,包括导航、点击、输入和验证等操作。以下是有关Selenium的一些详细信息。

3.1 简介

Selenium是一个功能强大的自动化测试框架,旨在简化Web应用程序的测试过程。它提供了一组API和工具,使开发人员能够以编程方式控制浏览器并执行测试用例。该框架基于四个主要组件:Selenium RC(Remote Control)、WebDriver、Grid和IDE(Integrated Development Environment)。Selenium支持多种编程语言,包括Java、Python、C#和Ruby等。

3.2 功能特点

3.2.1 语言支持

Selenium支持多种编程语言,包括Java、Python、C#和Ruby等。这意味着开发人员可以使用他们熟悉的编程语言编写自动化测试脚本。

3.2.2 多浏览器支持

Selenium可以自动化多种不同版本的主流浏览器,包括Chrome、Firefox、Edge、Safari和Internet Explorer等。这使得开发人员可以确保他们的应用程序在不同浏览器中的行为一致。

3.2.3 分布式测试

Selenium允许运行并行测试以加快测试执行速度。它可以在多个机器上同时运行测试,从而使大规模测试成为可能。通过使用Selenium Grid,开发人员可以轻松地实现分布式测试。

3.3 优缺点

3.3.1 优点
  • 跨平台兼容性:Selenium可以在多个操作系统上运行,包括Windows、Linux和macOS等。
  • 多语言支持:Selenium支持多种编程语言,包括Java、Python、C#和Ruby等。
  • 多浏览器支持:Selenium可以自动化多种不同版本的主流浏览器,包括Chrome、Firefox、Edge、Safari和Internet Explorer等。
  • 分布式测试:Selenium允许运行并行测试以加快测试执行速度。它可以在多个机器上同时运行测试,从而使大规模测试成为可能。
  • 可扩展性:Selenium具有高度可扩展性,可以很容易地与其他工具和技术集成,例如持续集成服务器和测试管理工具。
3.3.2 缺点
  • 学习曲线陡峭:对于初学者来说,掌握Selenium可能需要一些时间和精力。但是,有许多在线资源和技术社区可以提供帮助。
  • 配置复杂性:对于某些复杂场景,配置和管理Selenium可能会变得有些复杂。但是,这可以通过遵循最佳实践和使用经过验证的配置来实现。
  • 不适用于所有情况:在某些情况下,例如在高负载或实时环境中进行测试时,Selenium可能不是最佳选择。在这种情况下,其他工具和技术可能更合适。

3.4 使用场景

Selenium 适用于以下场景:

  • Web 应用程序的功能测试
  • 回归测试
  • 跨浏览器兼容性测试
  • 自动化表单填写以及数据抓取

3.5 安装与配置

在Node.js环境下安装和配置Selenium:

  1. 安装 Node.js 和 npm。
  2. 创建一个新的项目文件夹并初始化 npm:
    mkdir selenium-test
    cd selenium-test
    npm init -y
    
  3. 安装 selenium-webdriver 包:
    npm install selenium-webdriver
    
  4. 根据需要安装对应的浏览器驱动,例如 ChromeDriver:
    npm install chromedriver
    

3.6 基本用法

下面是一个完整的JavaScript实例代码,展示了如何使用 Selenium 在 Google 搜索 “Selenium”:

const {Builder, By, Key, until} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('path');

// 配置 ChromeDriver
const service = new chrome.ServiceBuilder(path.join(__dirname, 'node_modules', 'chromedriver', 'lib', 'chromedriver', 'chromedriver.exe')).build();
chrome.setDefaultService(service);

(async function example() {
    let driver = await new Builder().forBrowser('chrome').build();
    try {
        // 打开 Google 首页
        await driver.get('http://www.google.com');
        
        // 输入搜索关键字并提交
        await driver.findElement(By.name('q')).sendKeys('Selenium', Key.RETURN);
        
        // 等待页面标题包含 "Selenium"
        await driver.wait(until.titleContains('Selenium'), 1000);
        
        // 输出当前页面标题
        console.log(await driver.getTitle());
    } catch (error) {
        console.error(error);
    } finally {
        // 关闭浏览器
        await driver.quit();
    }
})();

3.7 实际案例

假设我们需要对一个登录页面进行自动化测试,以下是一个完整的JavaScript示例代码:

const {Builder, By, Key, until} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('path');

// 配置 ChromeDriver
const service = new chrome.ServiceBuilder(path.join(__dirname, 'node_modules', 'chromedriver', 'lib', 'chromedriver', 'chromedriver.exe')).build();
chrome.setDefaultService(service);

(async function loginTest() {
    let driver = await new Builder().forBrowser('chrome').build();
    try {
        // 打开登录页面
        await driver.get('http://example.com/login');
        
        // 填写用户名和密码
        await driver.findElement(By.id('username')).sendKeys('testuser');
        await driver.findElement(By.id('password')).sendKeys('mypassword', Key.RETURN);
        
        // 等待页面跳转并检查是否登录成功
        await driver.wait(until.urlContains('dashboard'), 5000);
        
        // 输出当前URL
        console.log(await driver.getCurrentUrl());
    } catch (error) {
        console.error(error);
    } finally {
        // 关闭浏览器
        await driver.quit();
    }
})();

更多细节请参考 Selenium官网

4. Puppeteer:一个基于Node.js的高层次API,用于控制Chrome或Chromium浏览器


4.1 简介

Puppeteer是一个由Google开发和维护的Node.js库,用于自动化控制Chrome或Chromium浏览器。它提供了一个高层次的API来操作浏览器,模拟用户交互并执行端到端测试。通过使用无头浏览器模式,可以在没有图形界面的情况下运行测试,从而节省资源并提高效率。


4.2 功能特点

4.2.1 无头浏览器模式

Puppeteer支持无头浏览器模式,这意味着可以在没有图形界面的情况下运行自动化脚本。这种模式非常适合在CI/CD环境中运行自动化测试,因为它不需要用户交互并且可以在服务器上运行。

4.2.2 页面自动化

Puppeteer提供了丰富的API来自动化页面操作,包括导航、点击、输入和等待等。这些API可以帮助模拟用户行为,例如填写表单、点击按钮和验证页面内容等。

4.2.3 PDF生成

Puppeteer还具有生成PDF文件的功能,可以将网页内容转换为PDF格式。这对于自动化报告生成或电子发票等用例非常有用。


4.3 优缺点

4.3.1 优点
  • 提供丰富的API来自动化页面操作和执行端到端测试。
  • 支持无头浏览器模式,可以在没有图形界面的情况下运行测试。
  • 易于安装和配置,可与现有的Node.js项目集成。
  • 具有活跃的开发社区和良好的文档支持。
4.3.2 缺点
  • 需要在系统上安装Chrome或Chromium浏览器才能运行。
  • 对于一些复杂的自动化任务可能需要编写更多的代码来实现。
  • 可能不稳定或不适用于某些特定的浏览器版本或操作系统。

4.4 使用场景

以下是一些可以使用Puppeteer的常见场景:

  • 端到端测试:使用Puppeteer可以轻松地自动化Web应用程序的端到端测试,以确保其在不同场景下都能正常工作。
  • Web scraping:通过模拟真实的用户交互和导航,Puppeteer可以方便地从网站中提取数据和信息。
  • 自动化报告生成:使用Puppeteer可以将网页内容转换为PDF格式,从而自动生成各种类型的报告。
  • UI自动化:如果需要自动化与用户界面相关的任务,例如填写表单、点击按钮等,则可以使用Puppeteer来简化这一过程。

4.5 安装与配置

要开始使用Puppeteer,首先需要确保已安装Node.js(v10.13.0或更高版本)并在系统中可用。然后,可以使用以下命令通过npm安装Puppeteer:

npm install --save-dev puppeteer

安装完成后,就可以在代码中导入Puppeteer并开始编写自动化脚本了。请注意,在Windows和Mac OS上,可能需要将一些系统依赖项安装在全局范围内:

npm install -g node-gyp && node-gyp rebuild # Install and build dependencies (Windows only)

4.6 基本用法

以下是一个简单的示例,展示了如何使用Puppeteer打开一个网页并生成一个截图:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'example.png' });

  await browser.close();
})();

更多详细内容请参考Puppeteer官方文档.

4.7 实际案例

4.7.1 自动化表单填写

下面是一个实际案例,展示了如何使用Puppeteer自动填写一个表单并提交:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example-form.com');

  // 填写表单
  await page.type('#name', 'John Doe');
  await page.type('#email', 'johndoe@example.com');
  await page.click('#submit');

  // 等待导航完成
  await page.waitForNavigation();

  // 截图保存结果页面
  await page.screenshot({ path: 'form-submission.png' });

  await browser.close();
})();
4.7.2 生成PDF文件

另一个实际案例,展示了如何将网页内容生成一个PDF文件:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  
  // 生成 PDF 文件
  await page.pdf({ path: 'example.pdf', format: 'A4' });

  await browser.close();
})();

引用官网链接查看更多详细示例,请访问 Puppeteer官方文档.

5. Playwright:用于Web应用程序跨浏览器自动化的库

5.1 简介

Playwright是一个由微软开发的支持多浏览器的自动化测试框架。它可以自动执行各种任务,如填写表单、点击按钮和检查页面内容。Playwright支持多种操作系统,包括Windows、Mac和Linux。

5.2 功能特点

5.2.1 多浏览器支持

Playwright支持多种浏览器,包括Chrome、Firefox、Safari和Edge。这意味着你可以使用相同的代码在不同的浏览器上运行测试。

5.2.2 丰富的API

Playwright提供了丰富的API,可以进行各种操作,如导航到网页、填充表单、点击按钮和检查页面内容。此外,Playwright还支持异步编程,可以使用async/await语法编写测试用例。

5.2.3 截图与视频功能

Playwright提供了截图和视频功能,可以在测试过程中捕获页面的快照或录制视频。这对于调试和记录测试过程非常有帮助。

5.3 优缺点

5.3.1 优点
  • 多浏览器支持,可以在同一代码中运行不同浏览器的测试。
  • 丰富的API,可以进行各种操作。
  • 异步编程支持,可以使用async/await语法编写测试用例。
  • 截图和视频功能,可以捕获页面的快照或录制视频。
5.3.2 缺点
  • 配置相对复杂,需要一定的学习成本。
  • 对网络依赖较大,需要稳定的网络环境。
  • 部分高级功能需要额外的配置和设置。

5.4 使用场景

Playwright适用于各种场景,包括但不限于:

  • Web应用程序自动化测试。
  • UI自动化测试。
  • 集成测试。
  • 回归测试。
  • 爬虫和数据收集。

5.5 安装与配置

要使用Playwright,你需要先安装Node.js。然后,你可以使用npm或yarn来安装Playwright:

npm install -D playwright

或者:

yarn add -D playwright

安装完成后,你可以在JavaScript文件中导入Playwright:

const { webkit } = require('playwright');

这里我们导入了webkit浏览器作为示例。你也可以替换为其他浏览器。

5.6 基本用法

下面是一个简单的示例,演示如何使用Playwright打开一个网页并检查页面标题:

const { webkit } = require('playwright');

(async () => {
  const browser = await webkit.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://www.example.com');
  const title = await page.title();
  console.log(title); // Example output: 'Example Domain'
  await browser.close();
})();

6. Nightwatch.js:一个简单易用的Node.js端到端测试解决方案

6.1 简介

Nightwatch.js是一个基于Node.js的端到端测试框架,它旨在提供一种简单易用的方式来编写自动化浏览器测试。与Selenium WebDriver等其他测试框架相比,Nightwatch.js具有更简洁的语法和更高的生产力。

6.2 功能特点

6.2.1 单一脚本配置

Nightwatch.js采用单一脚本配置方式,将所有测试用例、页面对象和辅助函数都放在一个文件中,方便管理和维护。这种配置方式可以大大减少编写测试代码的工作量和复杂性。

6.2.2 支持多种断言库

Nightwatch.js支持多种流行的断言库,如Chai、AssertJS和Expect.js。这意味着你可以根据自己的喜好和项目需求选择最适合的断言库来编写测试用例。

6.2.3 Selenium集成

作为一款端到端测试框架,Nightwatch.js与Selenium WebDriver无缝集成,可以轻松地控制和管理各种浏览器。通过使用Selenium WebDriver API,你可以完成各种常见的操作,如点击、输入、选择和验证等。

6.3 优缺点

6.3.1 优点
  • 简单易用:Nightwatch.js的语法简洁而直观,易于上手和学习。
  • 高生产力:采用单一脚本配置方式,减少了编写测试代码的工作量和复杂性。
  • 可扩展性强:支持多种断言库和插件,可以根据需求进行定制和扩展。
  • Selenium集成:与Selenium WebDriver无缝集成,可以控制和管理各种浏览器。
6.3.2 缺点
  • 文档不够详细:虽然官方文档已经提供了一些基本的指南和示例,但对于一些高级功能和配置选项的说明还不够详细。
  • 缺乏社区支持:相对于其他测试框架,Nightwatch.js的社区相对较小,可能会导致资料和资源有限。
  • 兼容性问题:由于是基于Node.js开发的,可能存在一些兼容性问题,特别是对于老旧或不常用的浏览器版本。

6.4 使用场景

Nightwatch.js适用于各种类型的Web应用程序,包括但不限于:

  • 前端开发:可用于测试用户界面、交互逻辑和页面渲染等方面。
  • 后端开发:可用于测试API接口、数据库操作和服务器响应等方面。
  • 集成测试:可用于测试多个模块或服务的集成是否正常工作。
  • 回归测试:可用于验证代码更改后的功能是否正常,并及时发现回归问题。

6.5 安装与配置

首先,需要安装 Nightwatch.js 和相关依赖项:

npm install nightwatch selenium-server chromedriver

然后,创建 nightwatch.conf.js 配置文件:

module.exports = {
  src_folders: ['tests'],
  webdriver: {
    start_process: true,
    server_path: require('chromedriver').path,
    port: 9515,
  },
  test_settings: {
    default: {
      desiredCapabilities: {
        browserName: 'chrome',
      },
    },
  },
};

6.6 基本用法

创建一个示例测试文件 tests/googleTest.js

module.exports = {
  'Demo test Google': function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .keys(browser.Keys.ENTER)
      .waitForElementVisible('#search', 5000)
      .assert.containsText('#search', 'Nightwatch.js')
      .end();
  }
};

运行测试:

npx nightwatch tests/googleTest.js

6.7 实际案例

假设我们有一个登录页面,我们需要验证用户是否能够成功登录。

创建 tests/loginTest.js 文件:

module.exports = {
  'Login test': function (browser) {
    browser
      .url('http://localhost:3000/login')
      .waitForElementVisible('body', 1000)
      .setValue('input[name=username]', 'testuser')
      .setValue('input[name=password]', 'password123')
      .click('button[type=submit]')
      .waitForElementVisible('.dashboard', 5000)
      .assert.urlContains('/dashboard')
      .end();
  }
};

运行测试:

npx nightwatch tests/loginTest.js

通过以上步骤,我们可以看到如何利用 Nightwatch.js 快速创建和执行端到端测试。更多详细信息可以参考官方文档:Nightwatch.js 官方文档

总结

在现代前端开发中,自动化测试是保障项目质量和效率的重要手段。Cypress、TestCafe、Selenium、Puppeteer、Playwright和Nightwatch.js是六种常用的前端测试工具,它们各有特点,适用于不同的使用场景。通过本文的介绍和比较,读者可以根据自己的需求选择合适的工具,并进行有效的自动化测试。

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friklogff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值