Android自动化测试实战:Robotium_solo_demo

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这个示例项目展示了如何在Android Studio和Eclipse中分别设置和运行Robotium测试,以实现Android应用的深度功能验证。通过学习如何在不同开发环境中编写和执行自动化测试脚本,开发者可以掌握Robotium框架的使用,以及如何编写测试用例来验证应用功能。 Robotium_solo_demo

1. Robotium框架介绍

1.1 框架概述

Robotium是一个独立于Android SDK的开源自动化测试框架,主要用于Android应用程序的功能测试。它支持原生应用、Web应用和混合应用的测试,能够模拟用户的行为,执行点击、滑动、文本输入等操作。

1.2 主要功能和特点

Robotium的优势在于其简洁的API和对Android生命周期的深刻理解,能够自动处理Activity的启动和关闭。此外,它还提供了丰富的断言方法,帮助测试人员验证应用的行为。由于它在内部使用了Instrumentation,因此能够访问Android的Context和Activity,这使得Robotium可以进行非常底层的测试。

1.3 适用场景

Robotium特别适合用于黑盒测试,尤其当需要自动化地模拟用户与应用程序的交互时。它也常被用于回归测试,以确保新版本的发布没有破坏旧功能。尽管Robotium对于复杂的UI操作和性能测试表现良好,但其在并行测试方面的能力稍弱,这也使得它在大规模自动化测试中的应用受到了一定限制。

2. Android Studio中Robotium集成与使用

2.1 Android Studio环境搭建与配置

2.1.1 安装Android Studio

在开始使用Robotium进行自动化测试之前,首先需要一个稳定可靠的开发环境。对于Android应用开发者来说,Android Studio无疑是最佳选择。以下是安装Android Studio的步骤:

  1. 下载最新版本的Android Studio:访问[Android开发者官网](***下载Android Studio的安装文件。
  2. 安装Android Studio:根据操作系统的不同,执行下载的安装文件,并按照向导指引完成安装。
  3. 启动Android Studio并进行初始配置:首次启动时,Android Studio会引导你完成一些初始设置,包括下载额外的组件和工具,如Android SDK等。
  4. 安装Android模拟器:你可以使用Android Studio内置的AVD Manager创建和管理模拟器,以测试你的应用。

2.1.2 配置Robotium依赖库

配置Robotium依赖库是实现Robotium测试的关键一步。请按照以下步骤添加Robotium依赖到你的Android Studio项目:

  1. 打开Android Studio项目,并进入项目的 build.gradle 文件。
  2. dependencies 部分添加Robotium依赖项:

    gradle dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.sensorsdata.android.test:SensorsAnalyticsTest:最新版本号' } 3. 同步项目以下载并安装Robotium库。 4. 在项目的 AndroidManifest.xml 文件中添加必要的权限:

    xml <uses-permission android:name="android.permission.INTERNET" />

  3. 启用测试支持库:

    gradle android { ... defaultConfig { ... testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } }

完成以上步骤后,你的Android Studio环境已准备好用于Robotium的集成与测试。

2.2 Robotium在Android Studio中的基本使用

2.2.1 创建Robotium测试项目

在Android Studio中创建一个Robotium测试项目涉及以下步骤:

  1. 在Android Studio中选择“File” > “New” > “New Project”来创建一个新的项目。
  2. 选择一个适合的模板,例如“Empty Activity”。
  3. 填写项目名称、包名、保存位置和目标API级别等信息。
  4. 点击“Finish”按钮完成创建。

创建好项目后,你需要创建一个测试模块:

  1. 在项目视图中右键点击“app”模块。
  2. 选择“New” > “Module”。
  3. 选择“Android Library”并点击“Next”。
  4. 为测试模块命名,并选择合适的保存位置。
  5. 点击“Finish”创建测试模块。

2.2.2 编写简单的Robotium测试用例

编写简单的Robotium测试用例包括以下步骤:

  1. 在测试模块的 src 目录下创建一个新的测试类。
  2. 使用 @RunWith(SoloTestRunner.class) 注解标记测试类。
  3. 使用 @Test 注解定义测试方法。

下面是一个简单的Robotium测试用例示例:

@RunWith(SoloTestRunner.class)
public class MyTestCase {
    Solo solo;

    @Before
    public void setUp() throws Exception {
        solo = new Solo(InstrumentationRegistry.getInstrumentation(), getInstrumentation().getTargetContext());
    }

    @Test
    public void testWelcomeScreen() {
        // 确保应用已启动并且在欢迎屏幕上
        solo.assertCurrentActivity("Expected Activity", WelcomeActivity.class);
        // 点击登录按钮
        solo.clickOnButton("Login");
        // 验证是否跳转到登录界面
        solo.assertCurrentActivity("Expected Activity", LoginActivity.class);
    }

    @After
    public void tearDown() throws Exception {
        solo.finishOpenedActivities();
    }
}

这段代码展示了如何使用Robotium进行简单的UI测试,验证应用是否能够正确跳转到预期的界面。

2.3 高级特性与技巧

2.3.1 使用Instrumentation进行深度测试

Instrumentation 是Android提供的一种运行时工具,它可以在应用运行时注入特定代码,以便进行监控或操作。与Robotium配合使用,可以实现对Android应用的深度测试。

要使用 Instrumentation 结合Robotium,你可以在测试类中添加 Instrumentation 的实例。以下是修改过的测试类,展示如何集成 Instrumentation

@RunWith(AndroidJUnit4.class)
public class MyInstrumentedTestCase {
    private Instrumentation mInstrumentation;

    @Before
    public void setUp() {
        mInstrumentation = new Instrumentation();
        // 通过Instrumentation添加额外的测试功能
    }

    @Test
    public void testInstrumentationUsage() {
        // 使用Instrumentation与Robotium的方法执行深度测试
    }

    @After
    public void tearDown() {
        // 清理操作
    }
}

2.3.2 结合Mockito进行单元测试

单元测试是软件测试的一个基本组成部分,它可以对应用中的最小可测试部分进行验证。使用Mockito与Robotium结合,可以更有效地进行单元测试。

在单元测试中,Mockito允许我们创建和配置mock对象,以代替真实的对象。这对于测试中需要依赖特定行为或状态的对象非常有用。

以下是一个使用Mockito进行单元测试的简单示例:

@RunWith(MockitoJUnitRunner.class)
public class MyUnitTest {
    private MockSomeClass mockObject;

    @Before
    public void setUp() {
        mockObject = Mockito.mock(MockSomeClass.class);
        // 配置mock对象的行为
    }

    @Test
    public void testMockitoUsage() {
        // 使用mock对象执行测试
    }
}

通过将Robotium与Mockito结合使用,可以创建更复杂的测试场景,提高测试的覆盖范围和质量。

请注意,上文详细地介绍了在Android Studio中如何进行Robotium的集成与基本使用,同时涉及了一些高级特性和技巧,为想要深入使用Robotium的读者提供了实际的操作案例和代码逻辑分析。

3. Eclipse中Robotium集成与使用

3.1 Eclipse环境搭建与配置

3.1.1 安装Eclipse ADT插件

为了在Eclipse IDE中开发Android应用,首先需要安装Android Development Tools (ADT) 插件。通过这个插件,开发者能够得到更加强大和便捷的工具,专门用于Android应用的构建和调试。安装ADT插件的步骤如下:

  1. 打开Eclipse。
  2. 进入“Help”菜单,选择“Install New Software”。
  3. 点击右上角的“Add”按钮。
  4. 在弹出的对话框中,填写ADT插件的名称,例如“ADT Plugin”,并输入ADT插件的安装URL:***。
  5. 点击“OK”,等待Eclipse从该位置获取可用软件列表。
  6. 在列表中找到“Developer Tools”,选中它并点击“Next”。
  7. 跟随安装向导完成安装,并重启Eclipse。

安装完毕后,Eclipse会支持Android项目。可以通过“File > New > Android Application Project”来创建一个新的Android项目。

3.1.2 导入Robotium库到Eclipse

Robotium库可以通过Eclipse的“Import”功能导入到项目中。按照以下步骤操作:

  1. 在Eclipse中,选择“File > Import”。
  2. 在弹出的对话框中,选择“General > Existing Projects into Workspace”,然后点击“Next”。
  3. 选择包含Robotium jar文件的文件夹,点击“OK”。
  4. 选择“Copy projects into workspace”(如果需要)和“Refresh folders”选项。
  5. 点击“Finish”完成导入。

导入完成后,Robotium库即可在Eclipse中使用。你可以通过“Properties > Java Build Path > Libraries”查看已经添加的Robotium库。

3.2 Robotium在Eclipse中的基本使用

3.2.1 创建Robotium测试项目

在Eclipse中创建一个Robotium测试项目,需按照以下步骤:

  1. 在Eclipse的Package Explorer视图中,右击你的工作空间并选择“New > Other...”。
  2. 在弹出的New Wizard窗口中,选择“Android Project”然后点击“Next”。
  3. 输入项目名称,选择构建目标(Android版本),并填写其他必要信息。
  4. 选择创建一个Activity,比如命名为“TestActivity”。
  5. 完成创建后,在项目中右击并选择“New > Package”,创建一个新的包用于存放测试代码,例如命名为“testsuits”。
  6. 再次右击新建的包并选择“New > Class”,创建一个测试类,比如命名为“SimpleTest”。

这样,你就成功创建了一个基于Robotium的测试项目。

3.2.2 编写基础的Robotium测试脚本

编写Robotium测试脚本需要一定的Android和Robotium知识。以下是一个基础的Robotium测试脚本示例:

package testsuits;

import android.test.ActivityInstrumentationTestCase2;
import com.jayway.android.robotium.solo.Solo;
import mypack.TestActivity;

public class SimpleTest extends ActivityInstrumentationTestCase2<TestActivity> {

    private Solo solo;

    public SimpleTest() {
        super(TestActivity.class);
    }

    protected void setUp() throws Exception {
        super.setUp();
        solo = new Solo(getInstrumentation(), getActivity());
    }

    public void testBasicFunctionality() {
        // 确保测试Activity已启动
        assertTrue("TestActivity is not started", solo.waitForActivity(TestActivity.class));

        // 使用文本进行查找
        solo.enterText(0, "Hello Robotium!");
        solo.sleep(2000); // 等待一些操作完成

        // 确认文本已输入
        String text = solo.getText(0);
        assertEquals("Text is not entered correctly", "Hello Robotium!", text);
    }

    protected void tearDown() throws Exception {
        solo.finishOpenedActivities();
        super.tearDown();
    }
}

在上述代码中, ActivityInstrumentationTestCase2 是Android单元测试的一部分,提供了与UI测试相关的辅助方法。 Solo 类是Robotium提供的,用于操作UI控件。

3.3 高级应用与实践

3.3.1 利用Hamcrest进行断言验证

在测试脚本中,使用断言是验证程序行为是否符合预期的重要手段。Hamcrest是一个强大的库,它提供了一套匹配器(matchers)用于构建灵活且可读性高的测试断言。

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;

// ...

public void testHAMcrestAssertion() {
    assertThat("The string is not correct.", solo.getText(0), is("Hello Robotium!"));
    // 或者使用
    assertEquals("The string is not correct.", "Hello Robotium!", solo.getText(0));
}

在上述代码中,我们使用了Hamcrest的 is 匹配器来检查UI组件的文本内容。

3.3.2 结合Eclipse的调试工具进行测试调试

在开发和测试过程中,调试是一个不可或缺的环节。Eclipse提供了强大的调试工具来帮助开发者定位问题。使用Eclipse进行Robotium测试脚本的调试,可以按照以下步骤:

  1. 在测试代码中需要暂停执行的地方添加断点,比如 testBasicFunctionality 方法中。
  2. 启动Eclipse调试模式:点击工具栏中的“Debug”图标。
  3. 选择要调试的测试项目,并开始调试。
  4. 当测试执行到断点时,Eclipse会暂停,你可以检查当前的变量值,单步执行代码,或使用监视窗口来查看表达式的结果。

![Eclipse断点调试](***

如图所示,Eclipse在断点处暂停了测试执行。你可以使用调试视图来查看当前线程的调用堆栈和变量的值,以及执行下一步操作。这样的调试能力对于快速定位和解决测试脚本中的问题非常有帮助。

4. Android应用自动化测试基础

4.1 自动化测试的基本概念

自动化测试的定义

自动化测试是利用计算机软件工具,通过编写测试脚本或使用特定的测试框架来执行测试用例,以实现测试的自动化。在Android应用开发中,自动化测试通常用于替代或辅助手工测试,以提高测试效率和覆盖率。

自动化测试的优势与局限性

自动化测试相对于手工测试而言,具有以下优势:

  • 提高效率 :自动化测试可以快速执行大量的测试用例,无需人工干预,大大提高了测试效率。
  • 提升准确性 :自动化测试可以减少人为操作错误,提高测试的准确性。
  • 提高覆盖率 :自动化可以执行那些手工测试难以实现的复杂或重复性测试用例。
  • 持续测试 :自动化测试可以在应用开发的每个阶段进行,支持持续集成和持续部署。

然而,自动化测试也有其局限性:

  • 初期投入大 :创建自动化测试用例和脚本需要时间和资源,尤其是对于大型项目。
  • 维护成本 :测试脚本需要随着应用程序的变化而更新,这可能带来一定的维护成本。
  • 不能完全替代手工测试 :自动化测试不能发现那些需要人类直觉和创造力才能发现的缺陷,因此它不能完全替代手工测试。

4.2 Android自动化测试框架对比

Robotium与Espresso的对比

Robotium和Espresso是Android平台上最流行的两个自动化测试框架。它们在功能和使用上都有所不同,选择合适的框架对于测试的成功至关重要。

Robotium是一个开源的Android自动化测试框架,它可以轻松地编写功能、系统和验收测试。Robotium的一个显著优势是它可以测试多个Android应用组件,如Activity、Dialog、Menu和Toast等。另外,Robotium不需要源代码的修改,使得它非常适合于黑盒测试。然而,Robotium目前不支持最新的Android API,且它的运行速度相对较慢。

相对而言,Espresso是Google官方推出的测试框架,提供了更为简洁的API,更容易编写测试代码。Espresso特别适合测试单一应用,它通过同步机制等待特定条件成立时才执行操作,这使得测试用例更加稳定。但Espresso需要应用的源代码,因此它更适合白盒测试。

选择合适的自动化测试框架

选择自动化测试框架时,需要考虑以下几个方面:

  • 项目需求 :是否需要黑盒测试,还是白盒测试?应用的哪些部分需要重点测试?
  • 开发环境 :项目是否使用最新版Android Studio?是否能适应新的Android API?
  • 测试资源 :团队是否有足够资源来学习和维护新的测试框架?
  • 未来规划 :项目是否计划长期维护?框架是否能得到持续支持?

综上所述,如果项目需要快速实现自动化测试并且没有源代码访问权限,Robotium是一个不错的选择。而对于需要紧密集成、并且更注重测试稳定性的项目,Espresso则可能是更合适的选择。

// 示例代码块:简单的Espresso测试用例
// 注意:执行前需要在Android Studio中配置Espresso依赖库

import androidx.test.espresso.Espresso;
import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;

public class ExampleEspressoTest {
    @Rule
    public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void clickOnButton() {
        // 检查是否看到了一个按钮
        Espresso.onView(ViewMatchers.withId(R.id.my_button)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
        // 模拟点击按钮
        Espresso.onView(ViewMatchers.withId(R.id.my_button)).perform(ViewActions.click());
        // 确认点击后的视图状态
        Espresso.onView(ViewMatchers.withId(R.id.my_textview)).check(ViewAssertions.matches(ViewMatchers.withText("Clicked!")));
    }
}

在上面的代码示例中,我们使用Espresso测试框架执行了一个简单的测试:检查一个按钮是否可见,模拟点击这个按钮,然后验证点击事件后的文本视图是否显示正确的文本内容。Espresso通过 ActivityTestRule 启动一个Activity进行测试,并提供了一套流畅的API来编写测试用例。

选择框架的过程需要基于实际项目需求和资源进行权衡,没有绝对的“最佳”选择,只有最适合当前项目状况的方案。

5. UI自动化测试实施

5.1 UI自动化测试的原理与方法

5.1.1 UI自动化测试的原理

UI自动化测试依赖于自动化测试工具来模拟用户与应用程序的交互过程,其核心目标是验证用户界面的正确性和稳定性。在移动应用中,UI自动化测试通常涉及对各种界面元素(如按钮、文本框、菜单等)的操作,确保这些元素在用户操作时能表现出预期的反应。Robotium等工具可以通过模拟点击、滑动等手势,自动执行用户界面测试用例。

5.1.2 UI自动化测试的关键点

在实施UI自动化测试时,关键点主要包括以下几个方面:

  • 测试用例设计 :确保测试用例能够覆盖应用的各个界面和功能,遵循等价类划分、边界值分析等测试设计技术。
  • 测试数据准备 :合理设计测试数据,以满足测试用例的需求,可以提高测试的覆盖率和有效性。
  • UI元素定位 :准确地定位UI元素是UI自动化测试的基石。测试框架通常提供多种定位机制,如ID、文本内容、坐标等。
  • 测试脚本维护 :随着应用的更新迭代,UI元素可能会发生变化,因此测试脚本的维护和更新也是关键点之一。

5.2 Robotium在UI测试中的应用

5.2.1 定位UI元素的策略

Robotium提供了丰富的API用于定位UI元素,以下是一些常用的定位策略:

  • solo.findById(id) :通过控件的ID定位。
  • solo.findByText(text) :通过控件显示的文本定位。
  • solo.findByXPath(xpath) :通过XPath定位。
  • solo.findByDescription(description) :通过控件描述定位。

5.2.2 UI测试用例的设计与编写

在编写Robotium测试用例时,应注意以下几点:

  • 清晰的测试目标 :每个测试用例都应该有一个明确的测试目标。
  • 合理的测试步骤 :测试步骤应模拟用户的实际操作流程。
  • 健壮的异常处理 :测试用例应能够处理异常情况,例如网络延迟、数据错误等。
  • 测试结果的断言 :使用断言验证测试结果是否符合预期。
solo.clickOnText("登录");
// 输入用户名和密码
solo.enterText(0, "user");
solo.enterText(1, "pass");
solo.clickOnButton("登录");
// 断言登录成功
solo.waitForText("欢迎", 1, 2000);

以上代码块中展示了Robotium在Android应用中进行UI测试的一个简单示例。首先点击登录按钮,然后分别输入用户名和密码,并再次点击登录按钮。最后,验证界面上是否出现“欢迎”信息,来确认登录成功。

5.3 测试案例与测试数据

5.3.1 设计可复用的测试案例

设计可复用的测试案例可以提高测试效率,减少重复代码。以下是一些设计可复用测试案例的建议:

  • 模块化测试方法 :将重复的测试步骤封装成独立的方法,以便在多个测试用例中调用。
  • 参数化测试数据 :通过参数化测试数据,可以简化测试用例的维护工作。
  • 使用测试套件 :通过测试套件组织测试案例,使得测试更加有序。

5.3.2 测试数据的管理与使用

测试数据是执行测试用例时所必需的数据集合。合理管理测试数据,可以提高测试的准确性和效率。在Robotium中,可以将测试数据存储在不同的地方:

  • 硬编码在测试代码中 :适用于简单的测试数据。
  • 外部文件(如XML, JSON, CSV) :适用于需要频繁变更的测试数据。
  • 数据库 :适用于大量测试数据的存储和管理。
// 从CSV文件中读取测试数据
String path = solo.getCurrentActivity().getFilesDir() + "/test_data.csv";
BufferedReader br = new BufferedReader(new FileReader(path));
String line = br.readLine();
while(line != null) {
    String[] testData = line.split(",");
    String userName = testData[0];
    String password = testData[1];
    // 使用 userName 和 password 进行测试
    // ...
    line = br.readLine();
}

以上代码块展示了如何从CSV文件中读取测试数据,用于登录场景的测试。通过将测试数据存储在外部文件中,可以灵活地调整和管理测试数据,而不必修改测试代码本身。

6. 测试案例应用的深度功能验证

在第五章中,我们探讨了如何在UI自动化测试中应用测试案例和管理测试数据。随着测试的深入,我们不仅需要关注UI层面的元素,还要验证应用程序的深度功能,确保应用的关键业务流程在自动化测试中得到充分验证。

6.1 深度功能测试的方法

深度功能测试是自动化测试中的高级阶段,它涉及到验证应用程序的后端逻辑和关键业务流程。其目的是确保应用不仅仅在表面上看起来正确,而且在内部逻辑上也能正确地处理数据和响应用户交互。

6.1.1 识别深度测试场景

识别深度测试场景需要对应用程序的功能有深入的理解。对于业务逻辑比较复杂的应用程序,开发者和测试工程师需要协作,共同确定测试的边界条件、异常流程以及可能的边缘情况。

  • 边界条件测试 :确保应用程序可以正确处理最小值、最大值等边界条件。例如,测试银行应用的存款功能时,输入金额为负数或超过存款上限的值。
  • 异常流程测试 :验证应用程序对于非标准操作的响应。比如输入错误的密码连续一定次数后,系统是否能锁定账户。
  • 边缘情况测试 :应用程序在特定条件下可能会出现的问题。例如,网络信号弱时,应用是否能正确处理数据上传和下载。

6.1.2 深度测试用例的编写技巧

在编写深度测试用例时,应重点考虑测试用例的覆盖性和可维护性:

  • 覆盖性 :确保测试用例能够覆盖所有的业务场景和业务逻辑,同时包括异常流程和边界条件。
  • 可维护性 :测试用例应当易于阅读和修改,以便随着应用程序的更新,可以快速地添加或修改测试用例。

6.2 测试案例的优化与维护

随着自动化测试案例数量的增长,如何保持测试案例的有效性和高效性成为了挑战。优化测试案例,提高测试效率是测试工作中的重要环节。

6.2.1 优化测试案例提高测试效率

优化测试案例可以从以下几个方面进行:

  • 重用测试代码 :对于常见的操作或流程,比如登录流程,可以抽取成一个公共的测试函数,供其他测试用例重用。
  • 参数化测试 :使用参数化的方式编写测试用例,可以使得一个测试脚本能够执行多种数据组合的测试,从而提高测试覆盖。
  • 分层测试策略 :将测试用例分为单元测试、集成测试和端到端测试等层级,每个层级关注不同的测试范围和细节。

6.2.2 测试案例的版本控制与维护

良好的版本控制和文档管理是测试案例维护的关键:

  • 版本控制 :利用版本控制系统管理测试脚本,确保每次修改都可追踪、可回溯。
  • 文档记录 :详细记录测试用例的设计思路、预期结果和实际结果,便于未来的维护和回顾。

6.3 测试结果的分析与报告

测试的最后阶段是分析测试结果,并编写测试报告。一个详细的测试报告可以帮助开发团队快速定位问题,并了解测试过程和结果。

6.3.1 分析测试结果

测试结果的分析应该包括:

  • 结果对比 :将实际结果与预期结果进行对比,找出差异并分析原因。
  • 问题定位 :通过分析测试数据,快速定位应用程序中可能存在的缺陷。
  • 趋势分析 :通过多轮测试的结果对比,分析应用程序的稳定性或性能的变化趋势。

6.3.2 编写测试报告

测试报告应包括以下内容:

  • 测试概览 :报告的开头应提供测试的总体情况,包括测试用例的数量、通过率和失败的用例。
  • 详细分析 :对于失败的测试案例,提供详细的失败原因分析和截图证据。
  • 改进建议 :根据测试结果,提出针对性的改进建议和优化方案。

测试报告不仅要提供测试结果的直接描述,还应该能够帮助项目组理解测试背后的数据和信息,指导后续的开发和优化工作。

在下一章节中,我们将介绍如何进行测试结果的持续集成与监控,确保自动化测试与开发流程的紧密结合。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:这个示例项目展示了如何在Android Studio和Eclipse中分别设置和运行Robotium测试,以实现Android应用的深度功能验证。通过学习如何在不同开发环境中编写和执行自动化测试脚本,开发者可以掌握Robotium框架的使用,以及如何编写测试用例来验证应用功能。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值