**Python 版本 API**

### BaseCase

BaseCase是所有测试Case的基类，继承该基类需要自己实现run方法。

#### run(context)

Case逻辑入口。

> 参数
>
> | 参数    | 必选 | 类型            | 说明                                        |
> | ------- | ---- | --------------- | ------------------------------------------- |
> | context | 是   | CaseContext对象 | 仅需要继承，执行时会自动传入CaseContext对象 |

#### start()

创建BaseCase实例对象后，调用对象的start方法运行Case。

### CaseContext

CaseContext对象会通过run方法传入，是测试框架的核心工具类。

#### find\_path(path)

通过Path搜索目标节点。

> 参数
>
> | 参数 | 必选 | 类型   | 说明                   |
> | ---- | ---- | ------ | ---------------------- |
> | path | 是   | String | 目标节点对应的Path路径 |
>
> 返回
>
> NodeSelector实例对象

#### find\_img(img\_path)

通过图片搜索元素。		

> 参数
>
> | 参数     | 必选 | 类型   | 说明                           |
> | -------- | ---- | ------ | ------------------------------ |
> | img_path | 是   | String | 目标图片对项目根目录的相对路径 |
>
> 返回
>
> ImgSelector实例对象

#### select(kwargs)

通过条件选择后代节点，从根节点开始。

> 参数
>
> | 参数   | 必选 | 类型          | 说明                               |
> | ------ | ---- | ------------- | ---------------------------------- |
> | kwargs | 是   | dict/function | 选择节点的条件，可传入匿名函数判断 |
>
> kwargs例子：
>
> ```python
> ns = c.select({"k1":"v1","k2":"v2"})
> #传入匿名函数，匿名函数的唯一参数为实际节点n对象，其包含节点内的各种属性。可以在匿名函数中对节点属性做条件判断，然后返回true/false来表示节点是否符合要求。
> ns = c.select(lambada n : n.get("className","") == "k1")
> ```
>
> 返回
>
> NodeSelector实例对象	

#### child(kwargs)

通过条件选择子节点，从根节点开始。

> 参数
>
> | 参数   | 必选 | 类型          | 说明                               |
> | ------ | ---- | ------------- | ---------------------------------- |
> | kwargs | 是   | dict/function | 选择节点的条件，可传入匿名函数判断 |
>
> kwargs例子：
>
> ```python
> ns = c.child({"k1":"v1","k2":"v2"})
> #传入匿名函数，匿名函数的唯一参数为实际节点n对象，其包含节点内的各种属性。可以在匿名函数中对节点属性做条件判断，然后返回true/false来表示节点是否符合要求。
> ns = c.child(lambada n : n.get("className","") == "k1")
> ```
>
> 返回
>
> NodeSelector实例对象		

#### tap(x, y, is\_per = true)

点击目标坐标。

> 参数
>
> | 参数   | 必选 | 类型  | 说明                           |
> | ------ | ---- | ----- | ------------------------------ |
> | x      | 是   | float | 横坐标                         |
> | y      | 是   | float | 纵坐标                         |
> | is_per | 否   | bool  | 传入坐标是否为百分比，默认true |
>
> 例子：
>
> ```python
> # 如果is_per为true，则传入x，y为0到1之间的浮点数，代表百分比坐标
> c.tap(0.5, 0.5, true)
> c.tap(180.5, 360.5, false)
> ```
>
> 返回
>
> 无	

#### swipe(x1, y1, x2, y2, is\_per = true)

由起点坐标到终点坐标滑动。

> 参数
>
> | 参数   | 必选 | 类型  | 说明                           |
> | ------ | ---- | ----- | ------------------------------ |
> | x1     | 是   | float | 起点横坐标                     |
> | y1     | 是   | float | 起点纵坐标                     |
> | x2     | 是   | float | 终点横坐标                     |
> | y2     | 是   | float | 终点纵坐标                     |
> | is_per | 否   | bool  | 传入坐标是否为百分比，默认true |
>
> 例子：
>
> ```python
> # 如果is_per为true，则传入x，y为0到1之间的浮点数，代表百分比坐标
> c.swipe(0.5, 0.5, 0.6, 0.6, true)
> c.swipe(180, 360, 240, 360 , false)
> ```
>
> 返回
>
> 无		

#### sleep(ms)

等待。

> 参数
>
> | 参数 | 必选 | 类型 | 说明       |
> | ---- | ---- | ---- | ---------- |
> | ms   | 是   | int  | 等待毫秒数 |
>
> 例子：
>
> ```python
> # 等待2s
> c.sleep(2000)
> ```
>
> 返回
>
> 无

#### wait\_for\_node(path, interval = 1000, num = 3)

等待节点出现，间隔默认为1000ms，检验3次。

> 参数
>
> | 参数     | 必选 | 类型   | 说明             |
> | -------- | ---- | ------ | ---------------- |
> | path     | 是   | string | 节点选择Path     |
> | interval | 否   | int    | 每次检查间隔时间 |
> | num      | 否   | int    | 检查次数         |
>
> 例子：
>
> ```python
> #等待a节点出现，超时时间为3s
> a = "{a}>{b}>{c[index=3]}"
> c.wait_for_node(a, 1000, 3)
> ```
>
> 返回
>
> NodeSelector实例对象

#### snapshot()

截屏。

> 参数
>
> 无
>
> 例子：
>
> ```Python
> //imgPath为截图文件的绝对路径
> imgPath = c.snapshot()
> ```
>
> 返回
>
> 截图文件的绝对路径	

#### run_record_case(path, run_time_limit=600)

回放录制文件。

> 参数
>
> | 参数           | 必选 | 类型   | 说明               |
> | :------------- | :--- | :----- | :----------------- |
> | path           | 是   | string | 录制数据的相对路径 |
> | run_time_limit | 否   | int    | 回放录制的超时时间 |
>
> 例子：
>
> ```python
> c.run_record_case("./record_data.json")
> ```
>
> 返回
>
> 无	

#### set_label(lable)

设置标签

>参数
>
> | 参数           | 必选 | 类型   | 说明               |
> | :------------- | :--- | :----- | :----------------- |
> | label           | 是   | string | 标签名称 |
> 例子：
>
> ```python
> c.set_label("start_game")
> ```
>
> 返回
>
> 无	

#### clear_label(lable)

清除标签

>参数
>
> | 参数           | 必选 | 类型   | 说明               |
> | :------------- | :--- | :----- | :----------------- |
> | label           | 是   | string | 标签名称 |
> 例子：
>
> ```python
> c.clear_label("start_game")
> ```
>
> 返回
>
> 无	

### NodeSelector

NodeSelector对象是选择节点得到的结果对象，可触发包含节点的事件，同时可以以其自身为基础进行进一步筛选。

如果没有搜索到对应节点，会返回一个内容为空的NodeSelector对象，即包含节点数为0，is_empty()返回true。	

#### tap()

点击节点。如果包含节点为空或多个的节点，调用tap会出现错误。

> 参数
>
> 无
>
> 例子：
>
> ```python
> ns.tap()
> ```
>
> 返回
>
> 无	

#### swipe(x, y, is_per = true)

以该节点为起点，目标坐标为终点滑动。如果包含节点为空或有多个的节点，调用会出现错误。

> 参数
>
> | 参数   | 必选 | 类型  | 说明                           |
> | ------ | ---- | ----- | ------------------------------ |
> | x      | 是   | float | 终点横坐标                     |
> | y      | 是   | float | 终点纵坐标                     |
> | is_per | 否   | bool  | 传入坐标是否为百分比，默认true |
>
> 例子：
>
> ```python
> # 如果is_per为true，则传入x，y为0到1之间的浮点数，代表百分比坐标
> ns.swipe(0.5, 0.5)
> ns.swipe(180.5, 360.5, false)
> ```
>
> 返回
>
> 无		

#### select(kwargs)

通过条件选择后代节点。

> 参数
>
> | 参数   | 必选 | 类型          | 说明                               |
> | ------ | ---- | ------------- | ---------------------------------- |
> | kwargs | 是   | dict/function | 选择节点的条件，可传入匿名函数判断 |
>
> kwargs例子：
>
> ```python
> ns = ns.select({"k1":"v1","k2":"v2"})
> #传入匿名函数，匿名函数的唯一参数为实际节点n对象，其包含节点内的各种属性。可以在匿名函数中对节点属性做条件判断，然后返回true/false来表示节点是否符合要求。
> ns = ns.select(lambada n : n.get("className","") == "k1")
> ```
>
> 返回
>
> NodeSelector实例对象

#### child(kwargs)

通过条件选择子节点。

> 参数
>
> | 参数   | 必选 | 类型          | 说明                               |
> | ------ | ---- | ------------- | ---------------------------------- |
> | kwargs | 是   | dict/function | 选择节点的条件，可传入匿名函数判断 |
>
> 例子：
>
> ```python
> ns = ns.child({"k1":"v1","k2":"v2"})
> #传入匿名函数，匿名函数的唯一参数为实际节点n对象，其包含节点内的各种属性。可以在匿名函数中对节点属性做条件判断，然后返回true/false来表示节点是否符合要求。
> ns = ns.child(lambada n : n.get("className","") == "k1")
> ```
>
> 返回
>
> NodeSelector实例对象

#### is\_empty()

当前NodeSelector对象包含的节点数是否为0，即是包含节点。

> 参数
>
> 无
>
> 例子：
>
> ```python
> if(!ns.is_empty()){
>  pass
> }
> ```
>
> 返回
>
> bool	

#### len()

返回当前ns对象包含的节点数。

> 参数
>
> 无
>
> 例子：
>
> ```python
> num = ns.len()
> ```
>
> 返回
>
> int	

### ImgSelector

ImgSelector 对象是图片匹配的结果对象。

如果没有搜索到对应图像，会返回一个内容为空的ImgSelector对象，is_empty()返回true。


#### tap()

点击图像，如果对空is对象调用会产生error。

> 参数
>
> 无
>
> 例子：
>
> ```python
> is.tap()
> ```
>
> 返回
>
> 无	

#### swipe(x, y, is_per = true)

以该节点为起点，目标坐标为终点滑动。如果对空is对象调用会产生error。

> 参数
>
> | 参数   | 必选 | 类型  | 说明                           |
> | ------ | ---- | ----- | ------------------------------ |
> | x      | 是   | float | 终点横坐标                     |
> | y      | 是   | float | 终点纵坐标                     |
> | is_per | 否   | bool  | 传入坐标是否为百分比，默认true |
>
> 例子：
>
> ```python
> # 如果is_per为true，则传入x，y为0到1之间的浮点数，代表百分比坐标
> is.swipe(0.5, 0.5)
> is.swipe(180.5, 360.5, false)
> ```
>
> 返回
>
> 无	

#### is\_empty()

当前ImgSelector对象是否为空。

> 参数
>
> 无
>
> 例子：
>
> ```python
> if(!is.is_empty()){
>  pass
> }
> ```
>
> 返回
>
> bool	

### Asserts

```
Asserts 包含测试Case节点相关的断言方法
```

#### assert\_nodeselector\_exists(ns)

断言当前ns存在，如果不存在会产生error，终止测试。使用前需要import Asserts。

> 参数
>
> | 参数 | 必选 | 类型         | 说明           |
> | ---- | ---- | ------------ | -------------- |
> | ns   | 是   | NodeSelector | 断言存在的节点 |
>
> 例子：
>
> ```python
> from mini_game_test_case_py.lib import Asserts
> ns = c.find_path("{{a}>{b}>{c[index=3]}}")
> Asserts.assert_nodeselector_exists(ns)
> ```
>
> 返回
>
> 无

#### assert\_nodeselector\_not\_exists(ns)

断言当前ns不存在，如果存在会产生error，终止测试。使用前需要import Asserts。

> 参数
>
> | 参数 | 必选 | 类型         | 说明             |
> | ---- | ---- | ------------ | ---------------- |
> | ns   | 是   | NodeSelector | 断言不存在的节点 |
>
> 例子：
>
> ```python
> from mini_game_test_case_py.lib import Asserts
> ns = c.find_path("{{a}>{b}>{c[index=3]}}")
> Asserts.assert_nodeselector_not_exists(ns)
> ```
>
> 返回
>
> 无

#### assert\_imgselector\_exists(is)

断言当前img_selector存在，如果不存在会产生error，终止测试。使用前需要import Asserts。

> 参数
>
> | 参数 | 必选 | 类型        | 说明           |
> | ---- | ---- | ----------- | -------------- |
> | img_selector   | 是   | ImgSelector | 断言存在的节点 |
>
> 例子：
>
> ```python
> from mini_game_test_case_py.lib import Asserts
> img_selector = c.find_img("image path")
> Asserts.assert_imgselector_exists(img_selector)
> ```
>
> 返回
>
> 无

#### assert\_imgselector\_not\_exists(is)

断言当前img_selector不存在，如果存在会产生error，终止测试。使用前需要import Asserts。

> 参数
>
> | 参数 | 必选 | 类型        | 说明           |
> | ---- | ---- | ----------- | -------------- |
> | img_selector   | 是   | ImgSelector | 断言存在的节点 |
>
> 例子：
>
> ```python
> from mini_game_test_case_py.lib import Asserts
> img_selector = c.find_img("image path")
> Asserts.assert_nodeselector_not_exists(img_selector)
> ```
>
> 返回
>
> 无

### Logger

Logger模块为用户提供了格式化的log输出。

```python
from mini_game_test_case_py.lib import Logger
Logger.info("test")
Logger.warn("test")
Logger.error("test")
```

### MiniGameTestTools

MiniGameTestTools对象会初始化运行环境，支持全局CaseContext获取，释放。可结合pyunit框架支持测试用例集，具体使用方法参考[示例](/minigame/dev/minigame-testtool/test_suite)。

```python
from mini_game_test_case_py.case.MiniGameTestTools import MiniGameTestTools
#初始化
test_tool = MiniGameTestTools(if_guard=True)
test_context = test_tool.context

#查找节点
tmp = test_context.find_path("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}")
...

#清理环境，释放资源
test_tool.stop()
```
