
# Rains

<br>

这是一个开箱即用、稳定且高效的工程化全栈自动化测试框架。

该框架的核心思想是用 "统一标准" 搭建基于不同平台的自动化测试工程，所谓 "统一标准" 表现在工程的搭建、运行、部署以及测试用例的编写设计上。

目前主流的诸如 Selenium 、 Appium 、 ApiPost 等自动化测试框架，基本都是指向某一个平台进行自动化搭建，这意味着当您的项目需要针对多个平台进行自动化项目的搭建时，就无可避免的需要混合使用多个框架，而不同的框架在技术栈与工作流上先天存在较大差异，这极大增加了搭建成本，以及在项目的管理、维护、运行上都存在许多不稳定因素。

<br>

而 rains 为此而生。

rains 包含一个高性能的多进程任务执行器与多个指向不同平台的测试套件，它们都基于 "统一标准" 制定的接口实现，这意味在同一个项目中，您可以针对不同平台编写测试用例任务，并调用执行器或者通过 rains命令行工具 运行这些任务。

对于您而言，仅需要一些 Python 的基础知识，便可上手开始编写自动化脚本。

通过近乎一致的方式去编写不同平台的自动化脚本。

rains 抽象了平台与其技术栈实现之间的差异，同时隐藏了它们之间的细节与复杂性，这意味着更低的学习成本。

您可以将更多精力集中于用例本身的设计上。

<br>

**[注意] 当前版本只实现了 Web 、 Api 测试套件。**

<br>

---

# 安装环境

<br>

## 1. Python

* 必须安装的依赖。

推荐版本 3.10 +

通过官网下载:

    https://www.python.org/

<br>

## 2. 安装 rains 库

* 必须安装的依赖。

通过 pip 安装 rains 库:

    pip install rains

<br>

## 3. rains命令行工具

* 必须安装的依赖。

命令行工具有助于您快速构建工程，以及运行您的测试项目。

您可以通过以下两种方法获取:

1. 通过 gitee 下载项目 zip 压缩包:

    https://gitee.com/catcat7/rains/repository/archive/master.zip

2. 通过 git工具 拉取项目:

    git clone https://gitee.com/catcat7/rains.git

获取项目之后，需要将项目路径加入到系统环境变量中，以此获取 rains命令行工具。

您可以通过快捷键 win + r 呼出运行框，输入 "cmd" 打开 dos，再次输入 rains -v 验证 rains命令行工具 是否可用。

<br>

## 4. Web 自动化

* 根据实际需求可选择安装的依赖。

rains.kit.web 测试套件基于 Selenium(3.14.1) 二次开发实现，使用时需要安装以下依赖:

1. 浏览器

    Chrome :: https://www.google.cn/chrome

2. 浏览器驱动

    ChromeDriver :: https://registry.npmmirror.com/binary.html?path=chromedriver

**[注意] 需要注意的是浏览器驱动与浏览器的版本必须一致。**

**[注意] 需要将浏览器驱动路径放置于 rains 项目中，后者加入系统环境变量中。**

<br>

---

# 上手指南

<br>

## 1. 初始化工程

工程是多个测试项目的集合，初始化的目的在于创建项目运行所需要的依赖环境。

您可以通过下方命令将当前工作路径初始化为工程目录:

    rains -init

<br>

## 2. 创建项目

通过下方命令创建项目:

    rains -make project1

通过下方命令一次性创建多个项目:

    rains -make project1 project2 ...

**[注意] 目前的版本中项目的定义并没有其特殊性，它就是一个文件夹。**

<br>

## 3. 创建任务

目前支持的任务类型:

web : Web功能测试任务

api : Api功能测试任务

通过下方命令创建任务模板:

    rains -task web task1

通过下方命令一次性创建多个任务模板:

    rains -task web task1 task2

<br>

## 4. 执行任务

该示例中不会涉及任务结构的描述，可以先自行查看任务模板中的内容。

通过 "rains -task web task_web_demo" 创建 Web 任务模板。

Web 任务模板中有一个简单的百度示例，通过下方命令运行:

    rains -run task_web_demo

rains -run 的参数可以是一个任务，也可以是一个项目，允许传递多个参数:

    rains -run task_web_demo project1 ...

<br>

---

# 任务描述

<br>

## 1. 任务文件结构

任务文件是若干个任务类的集合，而任务类是若干个用例的集合。

在命名任务文件、任务类、以及用例函数时需要注意:

    1. 任务文件命名需要以 task 为前缀，例如 "task_demo"。
    2. 任务类命名需要以 Task 为前缀，例如 "TaskDemo"。
    3. 用例函数需要以 case 为前缀，例如 "case_1"。

Web任务模板代码组成部分:

```python

# 导入 Web任务基类
from rains.kit.web import WebTask


# 继承 Web任务基类
class TaskDemo1(WebTask):
    """
    [ TaskDemo1 ]

    // 这是任务类的注释内容，值得注意的是任务执行后，该注释也会被储存至测试数据库中。

    """

    # Plant 对象是由 WebTask 继承而来, 它封装了所有的Web浏览器功能实现。
    self.plant: WebPlant

    # 下方以 set_ 开头的函数是 "任务设置器"。
    # 任务设置器的作用可以参考其注释。

    # ------------------------------
    def set_task_init(self):
        """
        [ 设置任务初始化 ]

        * 该接口将在 [ 任务 ] 开始时执行, 全程只会执行一次.

        """
        ...

    # ------------------------------
    def set_task_quit(self):
        """
        [ 设置任务注销 ]

        * 该接口将在 [ 任务 ] 结束后执行, 全程只会执行一次.

        """
        ...

    # ------------------------------
    def set_case_init(self):
        """
        [ 设置用例初始化 ]

        * 该接口将在每次 [ 用例 ] 开始时执行.

        """
        ...

    # ------------------------------
    def set_case_quit(self):
        """
        [ 设置用例注销 ]

        * 该接口将在每次 [ 用例 ] 结束后执行.

        """
        ...

    # 下方以 case 开头的函数是 "测试用例"。

    # ------------------------------
    def case_1(self):
        """
        [ 用例1 ]

        // 这是用例函数的注释内容，用例被执行后，该注释也会被储存至测试数据库中。

        """
        ...

    # ------------------------------
    def case_2(self):
        ...


# ----------------------------------
class TaskDemo2(WebTask):
    """
    [ TaskDemo2 ]

    """
    ...

```

<br>

## 2. 编写测试用例

任务基类中声明了一个对象: self.plant，它封装了所有的功能实现。

详细功能请查看 wiki 文档 :: https://gitee.com/catcat7/rains/wikis/Kit/Web/web_plant

该示例中，我们需要完成一个简单的示例 —— 通过百度搜索关键词"自动化测试"。

首先通过命令行工具创建任务模板:

    rains -task web task_demo

编辑该任务模板，在任务类的最后新增用例函数 "case_1_baidu_search":

```python

def case_1_baidu_search(self):
    """ [ 百度搜索"自动化测试" ] """
    ...
    
```

现在，在编写实际的业务代码之前，我们得先获取业务需要的页面元素定位方式。

该实例不涉及页面元素定位方式的获取方法，可以通过百度自行搜索。

self.plant.element 方法用于构建页面元素控件:

```python

# 百度搜索框
self.search_input = self.plant.element(
    page='百度',
    name='搜索框',
    by_key='id',
    by_value='kw'
)

# 百度百度一下
self.ok_button = self.plant.element(
    page='百度',
    name='百度一下',
    by_key=BY.ID,    # BY 对象中定义了所有八种定位方式名称。
    by_value='su'
)

```

元素定位构建相关的代码可以放在任务设置器函数 "set_task_init" 中。

接下来补全用例函数 "case_1_baidu_search":

```python

def case_1_baidu_search(self):
    """ [ 百度搜索"自动化测试" ] """

    # 页面访问URL
    self.plant.view.page.goto('http://www.baidu.com/')

    # 百度搜索框输入内容
    self.search_input.input.send('rains')

    # 点击百度一下
    self.ok_button.mouse.tap()
    
```

最后通过 rains命令行工具执行任务: "rains -run task_demo"
