xiaobaisaf


Namexiaobaisaf JSON
Version 2.5.0 PyPI version JSON
download
home_pagehttps://gitee.com/xiaobaikeji/simlpe_automation_framework
Summarysimple_automation_framework(简称:SAF)使用最简单的模式就可以实现需要功能和测试效果,也是xiaobaiauto2的简化版SAF继承了selenium、requests/httpx、appium、loguru、xiaobaiauto2、飞书机器人、钉钉机器人、企业微信机器人(暂时不支持)、禅道提单API
upload_time2024-01-18 08:42:06
maintainer
docs_urlNone
authorxiaobaiTser
requires_python>3.8, <3.10
license
keywords saf automation xiaobai xiaobaiauto2 test framework
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # simlpe_automation_framework

### 介绍
    simple_automation_framework(简称:SAF)
    使用最简单的模式就可以实现需要功能和测试效果,也是xiaobaiauto2的简化版
    SAF继承了selenium、requests/httpx、appium、loguru、xiaobaiauto2、飞书机器人、钉钉机器人、企业微信机器人(暂时不支持)、禅道提单API
    

### 软件架构
    xiaobaiauto2的简化版

### 版本注意
    建议使用Python 3.9.* 版本
    建议selenium >=4.16.0 支持代码自动执行无需关注浏览器驱动问题,可以自行下载
    防止某些库出现不兼容问题,导致功能不可使用

### 安装教程
```commandline
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple   注:将pip源修改为国内源
pip install xiaobaisaf
```

### 使用说明
- 优先修改saf/data/config.py中飞书/钉钉的webhook
```python
# filename=config.py

class feishu(object):
    @staticmethod
    def webhook():
        return 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxx'

class dingding(object):
    @staticmethod
    def webhook():
        return 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx'
```

- conftest.py(保持此文件与用例文件在同目录下)
```python
# filename = conftest.py
from saf.utils.SendMsgUtils import robotSendMessage
import pytest

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
    """
    :param item:
    """
    outcome = yield
    report = outcome.get_result()
    if report.outcome == 'failed':
        # 调用机器人发送执行结果
        robotSendMessage(robot_name='feishu', msg=f'测试脚本:{report.nodeid.split("::")[0]}\n测试用例:{report.nodeid.split("::")[1]}\n测试结果:{report.outcome}')
        # robotSendMessage(robot_name='dingding', msg=f'测试脚本:{report.nodeid.split("::")[0]}\n测试用例:{report.nodeid.split("::")[1]}\n测试结果:{report.outcome}')
        # robotSendMessage(robot_name='feishu,dingding', msg=f'测试脚本:{report.nodeid.split("::")[0]}\n测试用例:{report.nodeid.split("::")[1]}\n测试结果:{report.outcome}')
```

- 用例文件
```python
# fielname = test_xiaobai_testcase.py

def setup_module():
    ''' 用例脚本执行之前需要准备的信息 '''
    ...

def teardown_module():
    ''' 用例脚本执行之后需要清除的信息 '''

def setup_function():
    ''' 初始化测试用例执行之前状态信息 '''
    ...

def teardown_function():
    ''' 清除测试用例执行之后所产生的信息 '''
    ...

def test_yewu_name_a():
    ''' 用例函数
        需要针对业务场景的测试步骤的实现
            1、UI测试就是定位需要操作的界面节点然后执行操作
            2、API测试就是执行相关接口实现接口的功能
        需要针对每次的结果添加断言进行判断处理
    '''

def test_yewu_name_b():
    ''' 用例函数
        需要针对业务场景的测试步骤的实现
            1、UI测试就是定位需要操作的界面节点然后执行操作
            2、API测试就是执行相关接口实现接口的功能
        需要针对每次的结果添加断言进行判断处理
    '''
```

```python
# filename = test_xiaobai_allure.py
# JDK与Allure已安装且配置好环境变量(若不知道可以查看公众号:小白科技之窗)
import pytest
import allure

@allure.feature('下单')
class Test_order():
    @allure.story('登录')
    def test_login(self):
        ''' 登录 '''
        with allure.step('输入账户'):
            assert True
        with allure.step('输入密码'):
            assert True
        with allure.step('点击登录'):
            assert True

    @allure.story('搜索商品')
    def test_search(self):
        ''' 搜索商品 '''
        with allure.step('搜索框输入:苹果'):
            assert True
        with allure.step('点击搜索按钮'):
            assert False
'''
# 执行脚本
pytest test_xiaobai_allure.py --alluredir=../data

# 打开报告
allure serve ../data
或者
allure generate -c -o ../report ../data
allure open ../report
'''
```

### saf>1.1 使用禅道API,测试失败自动提单
- 需要在禅道后台>>二次开发>>应用>>添加应用>>创建开启免密的应用 
- 需要将上一步所生成数据【代号】与【密钥】写入到`saf/data/config.py`中zenTao相关的参数位置

```python
# filename = saf/data/config.py

import hashlib
import time
class zenTao(object):
    '''
    参考禅道接口文档:
    https://www.zentao.net/book/zentaopmshelp/integration-287.html
    '''
    @staticmethod
    def baseURL():
        ''' 禅道的根路径 '''
        return 'http://192.168.0.240/zentao'
 
    @staticmethod
    def account():
        ''' 后台-》二次开发-》应用-》免密登录的账户名 '''
        return '开启密钥的账户名称,例如管理员:admin'
 
    @staticmethod
    def getCode():
        ''' 后台-》二次开发-》应用-》创建-》代号 '''
        return '复制生成应用的代号字符串'
  
    @staticmethod
    def getKey():
        ''' 后台-》二次开发-》应用-》创建-》密钥 '''
        return '复制生成应用的密钥字符串'
  
    @staticmethod
    def getTime():
        ''' 获取时间戳 ,默认即可,无需修改'''
        return int(time.time())
  
    @staticmethod
    def getToken():
        ''' 获取token: md5($code + $key + $time) ,默认即可,无需修改'''
        _md5 = hashlib.md5(f'{zenTao.getCode()}{zenTao.getKey()}{zenTao.getTime()}'.encode('utf-8'))
        return _md5.hexdigest()
```

- 用例同目录下创建`conftest.py`pytest的配置文件
```python
# filename = conftest.py

from saf.utils.BugUtils import addZenTaoBUG
import pytest
  
@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
  """
  :param item:
  """
  outcome = yield
  report = outcome.get_result()
  if report.outcome == 'failed':
      doc = item.function.__doc__
      doc = str(doc).replace('\n', '<br>')
      addZenTaoBUG(title=item.function.__name__,
                        steps=f'{doc}预期结果:passed<br>测试结果:{report.outcome}')
    
 ```
- 用例文件正常编写,正常运行即可

### saf>1.0 拷贝web自动化模板到D:\autoProject目录下
```bat
xiaobaicmd -t web -d D:\autoProject
xiaobaicmd --template web --dirname D:\autoProject
xiaobaicmd -t api -d D:\autoProject
xiaobaicmd --template api --dirname D:\autoProject
xiaobaicmd -t app -d D:\autoProject[暂时不支持]
```

### saf>1.3 新增pytest参数多种样例,`web`中包含
```python
# filename = test_xiaobai_case_v2.py
import pytest
from saf import full_load

''' 参数化 '''

data2 = {
    'test_login': {
        'keys': 'username, password, _assert',
        'values': [('xiaobai', '12345', 200), ('xiaohui', '1234567', 200)]
    }
}

data3 = full_load(open('..\\data\\testCase.yaml', 'r').read())

# 内部数据
@pytest.mark.parametrize('username, password, _assert', [('xiaobai', '12345', 200), ('xiaohui', '1234567', 200)])
def test_xiaobai_login1(username, password, _assert):
    # 业务实现代码
    assert _assert == 200

# 外部数据
@pytest.mark.parametrize(data2['test_login']['keys'], data2['test_login']['values'])
def test_xiaobai_login2(username, password, _assert):
    # 业务实现代码
    assert _assert == 200


# 外部文件数据
@pytest.mark.parametrize(data3['test_login']['keys'], [eval(v) for v in data3['test_login']['values']])
def test_xiaobai_login3(username, password, _assert):
    # 业务实现代码
    assert _assert == 200
```
```yaml
# filename = ..\\data\\testCase.yaml
---
test_login:
  keys: username,password,_assert
  values:
    - ('xiaobai', '12346', 200)
    - ('xiaohui', '123456', 200)
```

### saf>1.8 工具会自动在当前目录下生成target文件夹,target目录内容与web模板保持一致,页面对象代码在PageObjects目录下
```cmd
xiaobaicmd -u https://www.baidu.com 
xiaobaicmd --url https://www.baidu.com 
```

### saf>1.9  基于adb实现监控Android设备中APP操作时实时生成XPath表达式及坐标等数据
```cmd
xiaobaicmd -m gui             # 基于界面实时获取APP数据
xiaobaicmd --monitor gui      # 基于界面实时获取APP数据
xiaobaicmd -m cli             # 基于命令实时获取APP数据
xiaobaicmd --monitor cli      # 基于命令实时获取APP数据
```

### saf>2.0   基础adb实现Android设备的界面监控功能
```cmd
xiaobaicmd -e [1]   # 默认值为1,可省略;表示打开界面监控第一个设备的实时界面
xiaobaicmd --device 1
```

### saf>2.2   基础adb实现Android设备的电量监控功能
```cmd
xiaobaicmd -m power   # 界面监控设备的电量与内存使用率的实时界面
xiaobaicmd -m memory   # 界面监控设备的电量与内存使用率的实时界面
```

### saf>2.3.5 新增实时监控Android当前APP的CPU使用率及FPS数据
```cmd
xiaobaicmd -m gui
```

### saf>2.3.7 新增识别滑块验证码破解
```python
from saf.utils.CaptchaUtils import checkSlider
from saf import selenium_webdriver, By

driver = selenium_webdriver.Chrome()

driver.get("https://www.xiaobaisoftware.com")

# 其它操作...

# 定位目标图(小图)
target_element = driver.find_element(By.XPATH, value='')

# 定位背景图(大图)
background_element = driver.find_element(By.XPATH, value='')

# 定位滑块按钮
button_element = driver.find_element(By.XPATH, value='')

# 参数:浏览器驱动、目标元素、背景元素、滑块元素、失败重试(非必须,默认:False)、重试次数(非必须,默认:3)
checkSlider(driver, target_element, background_element, button_element, True, 5)
```

### saf>2.3.8 新增解析DNS并刷新DNS缓存,数据保存HOSTS
```cmd
# 执行脚本之前请修改系统hosts文件在当前用户下有可读可写的权限!
# windows的hosts文件路径:C:\Windows\System32\drivers\etc\hosts
# Mac OS的hosts文件路径 :/private/etc/hosts
# Linux的hosts文件路径  :/etc/hosts

# --domains 后面的域名使用逗号分离即可
xiaobaicmd --domains github.com,raw.githubusercontent.com,github.global.ssl.fastly.net,assets-cdn.github.com
```

### saf>=2.5.0 新增小白软件管理工具,目前支持(安装、卸载、替换不同版本的)JMeter
```cmd
#命令行输入命令运行即可
xiaobaimanager
```


### 环境检测[还未实现]
```bat
xiaobaicmd  --init

检测内容: 
1、python版本及第三方库
2、第三方工具及环境
```

### 参与贡献
[selenium官网文档](https://www.selenium.dev/documentation/, "selenium官网文档")

[requests官网文档](https://requests.readthedocs.io/en/latest/, "requests官网文档")

[appium官网](http://appium.io/, "appium官网")

[loguru官方文档](https://loguru.readthedocs.io/en/stable/overview.html, "loguru官方文档")

[xiaobaiauto2帮助文档](https://pypi.org/project/xiaobaiauto2/, "xiaobaiauto2帮助文档")

[Allure帮助文档](https://docs.qameta.io/allure, "Allure帮助文档")

[飞书机器人获取WebHook](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN?lang=zh-CN, "飞书机器人获取WebHook")

[钉钉机器人获取WebHook](https://open.dingtalk.com/document/group/custom-robot-access, "钉钉机器人获取WebHook")

[163邮箱配置](http://help.163.com/09/1223/14/5R7P3QI100753VB8.html, "163邮箱配置")

[QQ邮箱配置](https://service.mail.qq.com/cgi-bin/help?subtype=1&id=28&no=369, "QQ邮箱配置")

### 更新日志

| version | info                            |
|---------|---------------------------------|
| 1.0     | 基本实现web自动化模板功能                  |
| 1.1     | 修复已知BUG                         |
| 1.2     | 新增allure报告库及封装禅道提单接口            |
| 1.3     | 新增jira提单接口                      |
| 1.4     | 新增pytest参数化样例                   |
| 1.5     | 优化pytest样例内容                    |
| 1.6     | 修复已知BUG                         |
| 1.7     | 新增基础环境检测功能                      |
| 1.8     | 新增API自动化模板                      |
| 1.9     | 新增xiaobaicmd -u命令               |
| 2.0     | 新增xiaobaicmd -m命令               |
| 2.1     | 新增xiaobaicmd --device命令         |
| 2.2     | 修复已知BUG                         |
| 2.3     | 新增实时监控Android设备耗电量              |
| 2.3.1   | 修复已知BUG                         |
| 2.3.2   | 修复已知BUG                         |
| 2.3.3   | 新增实时监控Android当前APP的内存使用率        |
| 2.3.4   | 新增xiaobaicmd -m gui效果展示         |
| 2.3.5   | 新增xiaobaicmd -u 转PO代码时xpath的表达式 |
| 2.3.6   | 新增实时监控Android当前APP的CPU使用率及FPS数据 |
| 2.3.7   | 新增识别滑块验证码破解                     |
| 2.3.8   | 优化识别滑块验证码破解                     |
| 2.3.9   | 新增解析DNS并刷新DNS缓存,数据保存HOSTS       |
| 2.4     | 修复已知BUG                         |
| 2.4.1   | 优化DNS解析效果                       |
| 2.4.2   | 优化自动生成代码                        |
| 2.4.3   | 优化                              |
| 2.4.3.1 | 优化                              |
| 2.4.3.2 | 优化                              |
| 2.5.0   | 添加xiaobaimanager命令              |



            

Raw data

            {
    "_id": null,
    "home_page": "https://gitee.com/xiaobaikeji/simlpe_automation_framework",
    "name": "xiaobaisaf",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">3.8, <3.10",
    "maintainer_email": "",
    "keywords": "saf automation xiaobai xiaobaiauto2 test framework",
    "author": "xiaobaiTser",
    "author_email": "807447312@qq.com",
    "download_url": "https://files.pythonhosted.org/packages/73/54/a96dc29b2b71954d7e821d843f0924921965bdff12894ee004ee46257f25/xiaobaisaf-2.5.0.tar.gz",
    "platform": null,
    "description": "# simlpe_automation_framework\n\n### \u4ecb\u7ecd\n    simple_automation_framework(\u7b80\u79f0\uff1aSAF)\n    \u4f7f\u7528\u6700\u7b80\u5355\u7684\u6a21\u5f0f\u5c31\u53ef\u4ee5\u5b9e\u73b0\u9700\u8981\u529f\u80fd\u548c\u6d4b\u8bd5\u6548\u679c\uff0c\u4e5f\u662fxiaobaiauto2\u7684\u7b80\u5316\u7248\n    SAF\u7ee7\u627f\u4e86selenium\u3001requests/httpx\u3001appium\u3001loguru\u3001xiaobaiauto2\u3001\u98de\u4e66\u673a\u5668\u4eba\u3001\u9489\u9489\u673a\u5668\u4eba\u3001\u4f01\u4e1a\u5fae\u4fe1\u673a\u5668\u4eba\uff08\u6682\u65f6\u4e0d\u652f\u6301\uff09\u3001\u7985\u9053\u63d0\u5355API\n    \n\n### \u8f6f\u4ef6\u67b6\u6784\n    xiaobaiauto2\u7684\u7b80\u5316\u7248\n\n### \u7248\u672c\u6ce8\u610f\n    \u5efa\u8bae\u4f7f\u7528Python 3.9.* \u7248\u672c\n    \u5efa\u8baeselenium >=4.16.0 \u652f\u6301\u4ee3\u7801\u81ea\u52a8\u6267\u884c\u65e0\u9700\u5173\u6ce8\u6d4f\u89c8\u5668\u9a71\u52a8\u95ee\u9898\uff0c\u53ef\u4ee5\u81ea\u884c\u4e0b\u8f7d\n    \u9632\u6b62\u67d0\u4e9b\u5e93\u51fa\u73b0\u4e0d\u517c\u5bb9\u95ee\u9898\uff0c\u5bfc\u81f4\u529f\u80fd\u4e0d\u53ef\u4f7f\u7528\n\n### \u5b89\u88c5\u6559\u7a0b\n```commandline\npip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple   \u6ce8\uff1a\u5c06pip\u6e90\u4fee\u6539\u4e3a\u56fd\u5185\u6e90\npip install xiaobaisaf\n```\n\n### \u4f7f\u7528\u8bf4\u660e\n- \u4f18\u5148\u4fee\u6539saf/data/config.py\u4e2d\u98de\u4e66/\u9489\u9489\u7684webhook\n```python\n# filename=config.py\n\nclass feishu(object):\n    @staticmethod\n    def webhook():\n        return 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxx'\n\nclass dingding(object):\n    @staticmethod\n    def webhook():\n        return 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx'\n```\n\n- conftest.py\uff08\u4fdd\u6301\u6b64\u6587\u4ef6\u4e0e\u7528\u4f8b\u6587\u4ef6\u5728\u540c\u76ee\u5f55\u4e0b\uff09\n```python\n# filename = conftest.py\nfrom saf.utils.SendMsgUtils import robotSendMessage\nimport pytest\n\n@pytest.mark.hookwrapper\ndef pytest_runtest_makereport(item):\n    \"\"\"\n    :param item:\n    \"\"\"\n    outcome = yield\n    report = outcome.get_result()\n    if report.outcome == 'failed':\n        # \u8c03\u7528\u673a\u5668\u4eba\u53d1\u9001\u6267\u884c\u7ed3\u679c\n        robotSendMessage(robot_name='feishu', msg=f'\u6d4b\u8bd5\u811a\u672c\uff1a{report.nodeid.split(\"::\")[0]}\\n\u6d4b\u8bd5\u7528\u4f8b\uff1a{report.nodeid.split(\"::\")[1]}\\n\u6d4b\u8bd5\u7ed3\u679c\uff1a{report.outcome}')\n        # robotSendMessage(robot_name='dingding', msg=f'\u6d4b\u8bd5\u811a\u672c\uff1a{report.nodeid.split(\"::\")[0]}\\n\u6d4b\u8bd5\u7528\u4f8b\uff1a{report.nodeid.split(\"::\")[1]}\\n\u6d4b\u8bd5\u7ed3\u679c\uff1a{report.outcome}')\n        # robotSendMessage(robot_name='feishu,dingding', msg=f'\u6d4b\u8bd5\u811a\u672c\uff1a{report.nodeid.split(\"::\")[0]}\\n\u6d4b\u8bd5\u7528\u4f8b\uff1a{report.nodeid.split(\"::\")[1]}\\n\u6d4b\u8bd5\u7ed3\u679c\uff1a{report.outcome}')\n```\n\n- \u7528\u4f8b\u6587\u4ef6\n```python\n# fielname = test_xiaobai_testcase.py\n\ndef setup_module():\n    ''' \u7528\u4f8b\u811a\u672c\u6267\u884c\u4e4b\u524d\u9700\u8981\u51c6\u5907\u7684\u4fe1\u606f '''\n    ...\n\ndef teardown_module():\n    ''' \u7528\u4f8b\u811a\u672c\u6267\u884c\u4e4b\u540e\u9700\u8981\u6e05\u9664\u7684\u4fe1\u606f '''\n\ndef setup_function():\n    ''' \u521d\u59cb\u5316\u6d4b\u8bd5\u7528\u4f8b\u6267\u884c\u4e4b\u524d\u72b6\u6001\u4fe1\u606f '''\n    ...\n\ndef teardown_function():\n    ''' \u6e05\u9664\u6d4b\u8bd5\u7528\u4f8b\u6267\u884c\u4e4b\u540e\u6240\u4ea7\u751f\u7684\u4fe1\u606f '''\n    ...\n\ndef test_yewu_name_a():\n    ''' \u7528\u4f8b\u51fd\u6570\n        \u9700\u8981\u9488\u5bf9\u4e1a\u52a1\u573a\u666f\u7684\u6d4b\u8bd5\u6b65\u9aa4\u7684\u5b9e\u73b0\n            1\u3001UI\u6d4b\u8bd5\u5c31\u662f\u5b9a\u4f4d\u9700\u8981\u64cd\u4f5c\u7684\u754c\u9762\u8282\u70b9\u7136\u540e\u6267\u884c\u64cd\u4f5c\n            2\u3001API\u6d4b\u8bd5\u5c31\u662f\u6267\u884c\u76f8\u5173\u63a5\u53e3\u5b9e\u73b0\u63a5\u53e3\u7684\u529f\u80fd\n        \u9700\u8981\u9488\u5bf9\u6bcf\u6b21\u7684\u7ed3\u679c\u6dfb\u52a0\u65ad\u8a00\u8fdb\u884c\u5224\u65ad\u5904\u7406\n    '''\n\ndef test_yewu_name_b():\n    ''' \u7528\u4f8b\u51fd\u6570\n        \u9700\u8981\u9488\u5bf9\u4e1a\u52a1\u573a\u666f\u7684\u6d4b\u8bd5\u6b65\u9aa4\u7684\u5b9e\u73b0\n            1\u3001UI\u6d4b\u8bd5\u5c31\u662f\u5b9a\u4f4d\u9700\u8981\u64cd\u4f5c\u7684\u754c\u9762\u8282\u70b9\u7136\u540e\u6267\u884c\u64cd\u4f5c\n            2\u3001API\u6d4b\u8bd5\u5c31\u662f\u6267\u884c\u76f8\u5173\u63a5\u53e3\u5b9e\u73b0\u63a5\u53e3\u7684\u529f\u80fd\n        \u9700\u8981\u9488\u5bf9\u6bcf\u6b21\u7684\u7ed3\u679c\u6dfb\u52a0\u65ad\u8a00\u8fdb\u884c\u5224\u65ad\u5904\u7406\n    '''\n```\n\n```python\n# filename = test_xiaobai_allure.py\n# JDK\u4e0eAllure\u5df2\u5b89\u88c5\u4e14\u914d\u7f6e\u597d\u73af\u5883\u53d8\u91cf\uff08\u82e5\u4e0d\u77e5\u9053\u53ef\u4ee5\u67e5\u770b\u516c\u4f17\u53f7\uff1a\u5c0f\u767d\u79d1\u6280\u4e4b\u7a97\uff09\nimport pytest\nimport allure\n\n@allure.feature('\u4e0b\u5355')\nclass Test_order():\n    @allure.story('\u767b\u5f55')\n    def test_login(self):\n        ''' \u767b\u5f55 '''\n        with allure.step('\u8f93\u5165\u8d26\u6237'):\n            assert True\n        with allure.step('\u8f93\u5165\u5bc6\u7801'):\n            assert True\n        with allure.step('\u70b9\u51fb\u767b\u5f55'):\n            assert True\n\n    @allure.story('\u641c\u7d22\u5546\u54c1')\n    def test_search(self):\n        ''' \u641c\u7d22\u5546\u54c1 '''\n        with allure.step('\u641c\u7d22\u6846\u8f93\u5165\uff1a\u82f9\u679c'):\n            assert True\n        with allure.step('\u70b9\u51fb\u641c\u7d22\u6309\u94ae'):\n            assert False\n'''\n# \u6267\u884c\u811a\u672c\npytest test_xiaobai_allure.py --alluredir=../data\n\n# \u6253\u5f00\u62a5\u544a\nallure serve ../data\n\u6216\u8005\nallure generate -c -o ../report ../data\nallure open ../report\n'''\n```\n\n### saf>1.1 \u4f7f\u7528\u7985\u9053API\uff0c\u6d4b\u8bd5\u5931\u8d25\u81ea\u52a8\u63d0\u5355\n- \u9700\u8981\u5728\u7985\u9053\u540e\u53f0>>\u4e8c\u6b21\u5f00\u53d1>>\u5e94\u7528>>\u6dfb\u52a0\u5e94\u7528>>\u521b\u5efa\u5f00\u542f\u514d\u5bc6\u7684\u5e94\u7528 \n- \u9700\u8981\u5c06\u4e0a\u4e00\u6b65\u6240\u751f\u6210\u6570\u636e\u3010\u4ee3\u53f7\u3011\u4e0e\u3010\u5bc6\u94a5\u3011\u5199\u5165\u5230`saf/data/config.py`\u4e2dzenTao\u76f8\u5173\u7684\u53c2\u6570\u4f4d\u7f6e\n\n```python\n# filename = saf/data/config.py\n\nimport hashlib\nimport time\nclass zenTao(object):\n    '''\n    \u53c2\u8003\u7985\u9053\u63a5\u53e3\u6587\u6863\uff1a\n    https://www.zentao.net/book/zentaopmshelp/integration-287.html\n    '''\n    @staticmethod\n    def baseURL():\n        ''' \u7985\u9053\u7684\u6839\u8def\u5f84 '''\n        return 'http://192.168.0.240/zentao'\n \n    @staticmethod\n    def account():\n        ''' \u540e\u53f0-\u300b\u4e8c\u6b21\u5f00\u53d1-\u300b\u5e94\u7528-\u300b\u514d\u5bc6\u767b\u5f55\u7684\u8d26\u6237\u540d '''\n        return '\u5f00\u542f\u5bc6\u94a5\u7684\u8d26\u6237\u540d\u79f0\uff0c\u4f8b\u5982\u7ba1\u7406\u5458\uff1aadmin'\n \n    @staticmethod\n    def getCode():\n        ''' \u540e\u53f0-\u300b\u4e8c\u6b21\u5f00\u53d1-\u300b\u5e94\u7528-\u300b\u521b\u5efa-\u300b\u4ee3\u53f7 '''\n        return '\u590d\u5236\u751f\u6210\u5e94\u7528\u7684\u4ee3\u53f7\u5b57\u7b26\u4e32'\n  \n    @staticmethod\n    def getKey():\n        ''' \u540e\u53f0-\u300b\u4e8c\u6b21\u5f00\u53d1-\u300b\u5e94\u7528-\u300b\u521b\u5efa-\u300b\u5bc6\u94a5 '''\n        return '\u590d\u5236\u751f\u6210\u5e94\u7528\u7684\u5bc6\u94a5\u5b57\u7b26\u4e32'\n  \n    @staticmethod\n    def getTime():\n        ''' \u83b7\u53d6\u65f6\u95f4\u6233 \uff0c\u9ed8\u8ba4\u5373\u53ef\uff0c\u65e0\u9700\u4fee\u6539'''\n        return int(time.time())\n  \n    @staticmethod\n    def getToken():\n        ''' \u83b7\u53d6token\uff1a md5($code + $key + $time) \uff0c\u9ed8\u8ba4\u5373\u53ef\uff0c\u65e0\u9700\u4fee\u6539'''\n        _md5 = hashlib.md5(f'{zenTao.getCode()}{zenTao.getKey()}{zenTao.getTime()}'.encode('utf-8'))\n        return _md5.hexdigest()\n```\n\n- \u7528\u4f8b\u540c\u76ee\u5f55\u4e0b\u521b\u5efa`conftest.py`pytest\u7684\u914d\u7f6e\u6587\u4ef6\n```python\n# filename = conftest.py\n\nfrom saf.utils.BugUtils import addZenTaoBUG\nimport pytest\n  \n@pytest.mark.hookwrapper\ndef pytest_runtest_makereport(item, call):\n  \"\"\"\n  :param item:\n  \"\"\"\n  outcome = yield\n  report = outcome.get_result()\n  if report.outcome == 'failed':\n      doc = item.function.__doc__\n      doc = str(doc).replace('\\n', '<br>')\n      addZenTaoBUG(title=item.function.__name__,\n                        steps=f'{doc}\u9884\u671f\u7ed3\u679c\uff1apassed<br>\u6d4b\u8bd5\u7ed3\u679c\uff1a{report.outcome}')\n    \n ```\n- \u7528\u4f8b\u6587\u4ef6\u6b63\u5e38\u7f16\u5199\uff0c\u6b63\u5e38\u8fd0\u884c\u5373\u53ef\n\n### saf>1.0 \u62f7\u8d1dweb\u81ea\u52a8\u5316\u6a21\u677f\u5230D:\\autoProject\u76ee\u5f55\u4e0b\n```bat\nxiaobaicmd -t web -d D:\\autoProject\nxiaobaicmd --template web --dirname D:\\autoProject\nxiaobaicmd -t api -d D:\\autoProject\nxiaobaicmd --template api --dirname D:\\autoProject\nxiaobaicmd -t app -d D:\\autoProject[\u6682\u65f6\u4e0d\u652f\u6301]\n```\n\n### saf>1.3 \u65b0\u589epytest\u53c2\u6570\u591a\u79cd\u6837\u4f8b\uff0c`web`\u4e2d\u5305\u542b\n```python\n# filename = test_xiaobai_case_v2.py\nimport pytest\nfrom saf import full_load\n\n''' \u53c2\u6570\u5316 '''\n\ndata2 = {\n    'test_login': {\n        'keys': 'username, password, _assert',\n        'values': [('xiaobai', '12345', 200), ('xiaohui', '1234567', 200)]\n    }\n}\n\ndata3 = full_load(open('..\\\\data\\\\testCase.yaml', 'r').read())\n\n# \u5185\u90e8\u6570\u636e\n@pytest.mark.parametrize('username, password, _assert', [('xiaobai', '12345', 200), ('xiaohui', '1234567', 200)])\ndef test_xiaobai_login1(username, password, _assert):\n    # \u4e1a\u52a1\u5b9e\u73b0\u4ee3\u7801\n    assert _assert == 200\n\n# \u5916\u90e8\u6570\u636e\n@pytest.mark.parametrize(data2['test_login']['keys'], data2['test_login']['values'])\ndef test_xiaobai_login2(username, password, _assert):\n    # \u4e1a\u52a1\u5b9e\u73b0\u4ee3\u7801\n    assert _assert == 200\n\n\n# \u5916\u90e8\u6587\u4ef6\u6570\u636e\n@pytest.mark.parametrize(data3['test_login']['keys'], [eval(v) for v in data3['test_login']['values']])\ndef test_xiaobai_login3(username, password, _assert):\n    # \u4e1a\u52a1\u5b9e\u73b0\u4ee3\u7801\n    assert _assert == 200\n```\n```yaml\n# filename = ..\\\\data\\\\testCase.yaml\n---\ntest_login:\n  keys: username,password,_assert\n  values:\n    - ('xiaobai', '12346', 200)\n    - ('xiaohui', '123456', 200)\n```\n\n### saf>1.8 \u5de5\u5177\u4f1a\u81ea\u52a8\u5728\u5f53\u524d\u76ee\u5f55\u4e0b\u751f\u6210target\u6587\u4ef6\u5939\uff0ctarget\u76ee\u5f55\u5185\u5bb9\u4e0eweb\u6a21\u677f\u4fdd\u6301\u4e00\u81f4\uff0c\u9875\u9762\u5bf9\u8c61\u4ee3\u7801\u5728PageObjects\u76ee\u5f55\u4e0b\n```cmd\nxiaobaicmd -u https://www.baidu.com \nxiaobaicmd --url https://www.baidu.com \n```\n\n### saf>1.9  \u57fa\u4e8eadb\u5b9e\u73b0\u76d1\u63a7Android\u8bbe\u5907\u4e2dAPP\u64cd\u4f5c\u65f6\u5b9e\u65f6\u751f\u6210XPath\u8868\u8fbe\u5f0f\u53ca\u5750\u6807\u7b49\u6570\u636e\n```cmd\nxiaobaicmd -m gui             # \u57fa\u4e8e\u754c\u9762\u5b9e\u65f6\u83b7\u53d6APP\u6570\u636e\nxiaobaicmd --monitor gui      # \u57fa\u4e8e\u754c\u9762\u5b9e\u65f6\u83b7\u53d6APP\u6570\u636e\nxiaobaicmd -m cli             # \u57fa\u4e8e\u547d\u4ee4\u5b9e\u65f6\u83b7\u53d6APP\u6570\u636e\nxiaobaicmd --monitor cli      # \u57fa\u4e8e\u547d\u4ee4\u5b9e\u65f6\u83b7\u53d6APP\u6570\u636e\n```\n\n### saf>2.0   \u57fa\u7840adb\u5b9e\u73b0Android\u8bbe\u5907\u7684\u754c\u9762\u76d1\u63a7\u529f\u80fd\n```cmd\nxiaobaicmd -e [1]   # \u9ed8\u8ba4\u503c\u4e3a1\uff0c\u53ef\u7701\u7565\uff1b\u8868\u793a\u6253\u5f00\u754c\u9762\u76d1\u63a7\u7b2c\u4e00\u4e2a\u8bbe\u5907\u7684\u5b9e\u65f6\u754c\u9762\nxiaobaicmd --device 1\n```\n\n### saf>2.2   \u57fa\u7840adb\u5b9e\u73b0Android\u8bbe\u5907\u7684\u7535\u91cf\u76d1\u63a7\u529f\u80fd\n```cmd\nxiaobaicmd -m power   # \u754c\u9762\u76d1\u63a7\u8bbe\u5907\u7684\u7535\u91cf\u4e0e\u5185\u5b58\u4f7f\u7528\u7387\u7684\u5b9e\u65f6\u754c\u9762\nxiaobaicmd -m memory   # \u754c\u9762\u76d1\u63a7\u8bbe\u5907\u7684\u7535\u91cf\u4e0e\u5185\u5b58\u4f7f\u7528\u7387\u7684\u5b9e\u65f6\u754c\u9762\n```\n\n### saf>2.3.5 \u65b0\u589e\u5b9e\u65f6\u76d1\u63a7Android\u5f53\u524dAPP\u7684CPU\u4f7f\u7528\u7387\u53caFPS\u6570\u636e\n```cmd\nxiaobaicmd -m gui\n```\n\n### saf>2.3.7 \u65b0\u589e\u8bc6\u522b\u6ed1\u5757\u9a8c\u8bc1\u7801\u7834\u89e3\n```python\nfrom saf.utils.CaptchaUtils import checkSlider\nfrom saf import selenium_webdriver, By\n\ndriver = selenium_webdriver.Chrome()\n\ndriver.get(\"https://www.xiaobaisoftware.com\")\n\n# \u5176\u5b83\u64cd\u4f5c...\n\n# \u5b9a\u4f4d\u76ee\u6807\u56fe\uff08\u5c0f\u56fe\uff09\ntarget_element = driver.find_element(By.XPATH, value='')\n\n# \u5b9a\u4f4d\u80cc\u666f\u56fe\uff08\u5927\u56fe\uff09\nbackground_element = driver.find_element(By.XPATH, value='')\n\n# \u5b9a\u4f4d\u6ed1\u5757\u6309\u94ae\nbutton_element = driver.find_element(By.XPATH, value='')\n\n# \u53c2\u6570\uff1a\u6d4f\u89c8\u5668\u9a71\u52a8\u3001\u76ee\u6807\u5143\u7d20\u3001\u80cc\u666f\u5143\u7d20\u3001\u6ed1\u5757\u5143\u7d20\u3001\u5931\u8d25\u91cd\u8bd5\uff08\u975e\u5fc5\u987b\uff0c\u9ed8\u8ba4\uff1aFalse\uff09\u3001\u91cd\u8bd5\u6b21\u6570\uff08\u975e\u5fc5\u987b\uff0c\u9ed8\u8ba4\uff1a3\uff09\ncheckSlider(driver, target_element, background_element, button_element, True, 5)\n```\n\n### saf>2.3.8 \u65b0\u589e\u89e3\u6790DNS\u5e76\u5237\u65b0DNS\u7f13\u5b58\uff0c\u6570\u636e\u4fdd\u5b58HOSTS\n```cmd\n# \u6267\u884c\u811a\u672c\u4e4b\u524d\u8bf7\u4fee\u6539\u7cfb\u7edfhosts\u6587\u4ef6\u5728\u5f53\u524d\u7528\u6237\u4e0b\u6709\u53ef\u8bfb\u53ef\u5199\u7684\u6743\u9650\uff01\n# windows\u7684hosts\u6587\u4ef6\u8def\u5f84\uff1aC:\\Windows\\System32\\drivers\\etc\\hosts\n# Mac OS\u7684hosts\u6587\u4ef6\u8def\u5f84 \uff1a/private/etc/hosts\n# Linux\u7684hosts\u6587\u4ef6\u8def\u5f84  \uff1a/etc/hosts\n\n# --domains \u540e\u9762\u7684\u57df\u540d\u4f7f\u7528\u9017\u53f7\u5206\u79bb\u5373\u53ef\nxiaobaicmd --domains github.com,raw.githubusercontent.com,github.global.ssl.fastly.net,assets-cdn.github.com\n```\n\n### saf>=2.5.0 \u65b0\u589e\u5c0f\u767d\u8f6f\u4ef6\u7ba1\u7406\u5de5\u5177\uff0c\u76ee\u524d\u652f\u6301\uff08\u5b89\u88c5\u3001\u5378\u8f7d\u3001\u66ff\u6362\u4e0d\u540c\u7248\u672c\u7684\uff09JMeter\n```cmd\n#\u547d\u4ee4\u884c\u8f93\u5165\u547d\u4ee4\u8fd0\u884c\u5373\u53ef\nxiaobaimanager\n```\n\n\n### \u73af\u5883\u68c0\u6d4b[\u8fd8\u672a\u5b9e\u73b0]\n```bat\nxiaobaicmd  --init\n\n\u68c0\u6d4b\u5185\u5bb9: \n1\u3001python\u7248\u672c\u53ca\u7b2c\u4e09\u65b9\u5e93\n2\u3001\u7b2c\u4e09\u65b9\u5de5\u5177\u53ca\u73af\u5883\n```\n\n### \u53c2\u4e0e\u8d21\u732e\n[selenium\u5b98\u7f51\u6587\u6863](https://www.selenium.dev/documentation/, \"selenium\u5b98\u7f51\u6587\u6863\")\n\n[requests\u5b98\u7f51\u6587\u6863](https://requests.readthedocs.io/en/latest/, \"requests\u5b98\u7f51\u6587\u6863\")\n\n[appium\u5b98\u7f51](http://appium.io/, \"appium\u5b98\u7f51\")\n\n[loguru\u5b98\u65b9\u6587\u6863](https://loguru.readthedocs.io/en/stable/overview.html, \"loguru\u5b98\u65b9\u6587\u6863\")\n\n[xiaobaiauto2\u5e2e\u52a9\u6587\u6863](https://pypi.org/project/xiaobaiauto2/, \"xiaobaiauto2\u5e2e\u52a9\u6587\u6863\")\n\n[Allure\u5e2e\u52a9\u6587\u6863](https://docs.qameta.io/allure, \"Allure\u5e2e\u52a9\u6587\u6863\")\n\n[\u98de\u4e66\u673a\u5668\u4eba\u83b7\u53d6WebHook](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN?lang=zh-CN, \"\u98de\u4e66\u673a\u5668\u4eba\u83b7\u53d6WebHook\")\n\n[\u9489\u9489\u673a\u5668\u4eba\u83b7\u53d6WebHook](https://open.dingtalk.com/document/group/custom-robot-access, \"\u9489\u9489\u673a\u5668\u4eba\u83b7\u53d6WebHook\")\n\n[163\u90ae\u7bb1\u914d\u7f6e](http://help.163.com/09/1223/14/5R7P3QI100753VB8.html, \"163\u90ae\u7bb1\u914d\u7f6e\")\n\n[QQ\u90ae\u7bb1\u914d\u7f6e](https://service.mail.qq.com/cgi-bin/help?subtype=1&id=28&no=369, \"QQ\u90ae\u7bb1\u914d\u7f6e\")\n\n### \u66f4\u65b0\u65e5\u5fd7\n\n| version | info                            |\n|---------|---------------------------------|\n| 1.0     | \u57fa\u672c\u5b9e\u73b0web\u81ea\u52a8\u5316\u6a21\u677f\u529f\u80fd                  |\n| 1.1     | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 1.2     | \u65b0\u589eallure\u62a5\u544a\u5e93\u53ca\u5c01\u88c5\u7985\u9053\u63d0\u5355\u63a5\u53e3            |\n| 1.3     | \u65b0\u589ejira\u63d0\u5355\u63a5\u53e3                      |\n| 1.4     | \u65b0\u589epytest\u53c2\u6570\u5316\u6837\u4f8b                   |\n| 1.5     | \u4f18\u5316pytest\u6837\u4f8b\u5185\u5bb9                    |\n| 1.6     | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 1.7     | \u65b0\u589e\u57fa\u7840\u73af\u5883\u68c0\u6d4b\u529f\u80fd                      |\n| 1.8     | \u65b0\u589eAPI\u81ea\u52a8\u5316\u6a21\u677f                      |\n| 1.9     | \u65b0\u589exiaobaicmd -u\u547d\u4ee4               |\n| 2.0     | \u65b0\u589exiaobaicmd -m\u547d\u4ee4               |\n| 2.1     | \u65b0\u589exiaobaicmd --device\u547d\u4ee4         |\n| 2.2     | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 2.3     | \u65b0\u589e\u5b9e\u65f6\u76d1\u63a7Android\u8bbe\u5907\u8017\u7535\u91cf              |\n| 2.3.1   | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 2.3.2   | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 2.3.3   | \u65b0\u589e\u5b9e\u65f6\u76d1\u63a7Android\u5f53\u524dAPP\u7684\u5185\u5b58\u4f7f\u7528\u7387        |\n| 2.3.4   | \u65b0\u589exiaobaicmd -m gui\u6548\u679c\u5c55\u793a         |\n| 2.3.5   | \u65b0\u589exiaobaicmd -u \u8f6cPO\u4ee3\u7801\u65f6xpath\u7684\u8868\u8fbe\u5f0f |\n| 2.3.6   | \u65b0\u589e\u5b9e\u65f6\u76d1\u63a7Android\u5f53\u524dAPP\u7684CPU\u4f7f\u7528\u7387\u53caFPS\u6570\u636e |\n| 2.3.7   | \u65b0\u589e\u8bc6\u522b\u6ed1\u5757\u9a8c\u8bc1\u7801\u7834\u89e3                     |\n| 2.3.8   | \u4f18\u5316\u8bc6\u522b\u6ed1\u5757\u9a8c\u8bc1\u7801\u7834\u89e3                     |\n| 2.3.9   | \u65b0\u589e\u89e3\u6790DNS\u5e76\u5237\u65b0DNS\u7f13\u5b58\uff0c\u6570\u636e\u4fdd\u5b58HOSTS       |\n| 2.4     | \u4fee\u590d\u5df2\u77e5BUG                         |\n| 2.4.1   | \u4f18\u5316DNS\u89e3\u6790\u6548\u679c                       |\n| 2.4.2   | \u4f18\u5316\u81ea\u52a8\u751f\u6210\u4ee3\u7801                        |\n| 2.4.3   | \u4f18\u5316                              |\n| 2.4.3.1 | \u4f18\u5316                              |\n| 2.4.3.2 | \u4f18\u5316                              |\n| 2.5.0   | \u6dfb\u52a0xiaobaimanager\u547d\u4ee4              |\n\n\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "simple_automation_framework(\u7b80\u79f0\uff1aSAF)\u4f7f\u7528\u6700\u7b80\u5355\u7684\u6a21\u5f0f\u5c31\u53ef\u4ee5\u5b9e\u73b0\u9700\u8981\u529f\u80fd\u548c\u6d4b\u8bd5\u6548\u679c\uff0c\u4e5f\u662fxiaobaiauto2\u7684\u7b80\u5316\u7248SAF\u7ee7\u627f\u4e86selenium\u3001requests/httpx\u3001appium\u3001loguru\u3001xiaobaiauto2\u3001\u98de\u4e66\u673a\u5668\u4eba\u3001\u9489\u9489\u673a\u5668\u4eba\u3001\u4f01\u4e1a\u5fae\u4fe1\u673a\u5668\u4eba\uff08\u6682\u65f6\u4e0d\u652f\u6301\uff09\u3001\u7985\u9053\u63d0\u5355API",
    "version": "2.5.0",
    "project_urls": {
        "Homepage": "https://gitee.com/xiaobaikeji/simlpe_automation_framework"
    },
    "split_keywords": [
        "saf",
        "automation",
        "xiaobai",
        "xiaobaiauto2",
        "test",
        "framework"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6719f11a64228b8a62e4c29962d79c4646bbe6ffe6297c930e16cae300f79e10",
                "md5": "3e4c8f9f4624a8da72c0f5f3d96d0c54",
                "sha256": "1d395cb94e10890c7cb77e62c99e311095067bd0ccbb54dc4cd560e17a728386"
            },
            "downloads": -1,
            "filename": "xiaobaisaf-2.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3e4c8f9f4624a8da72c0f5f3d96d0c54",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">3.8, <3.10",
            "size": 93130,
            "upload_time": "2024-01-18T08:42:00",
            "upload_time_iso_8601": "2024-01-18T08:42:00.330687Z",
            "url": "https://files.pythonhosted.org/packages/67/19/f11a64228b8a62e4c29962d79c4646bbe6ffe6297c930e16cae300f79e10/xiaobaisaf-2.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7354a96dc29b2b71954d7e821d843f0924921965bdff12894ee004ee46257f25",
                "md5": "e30e20fa061c78e526b5a30382e89903",
                "sha256": "71e77dda3e4a7665a71474dcaba6ee7139361086594a8f9a5472b71c72b7e9bc"
            },
            "downloads": -1,
            "filename": "xiaobaisaf-2.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "e30e20fa061c78e526b5a30382e89903",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">3.8, <3.10",
            "size": 73304,
            "upload_time": "2024-01-18T08:42:06",
            "upload_time_iso_8601": "2024-01-18T08:42:06.366738Z",
            "url": "https://files.pythonhosted.org/packages/73/54/a96dc29b2b71954d7e821d843f0924921965bdff12894ee004ee46257f25/xiaobaisaf-2.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-18 08:42:06",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "xiaobaisaf"
}
        
Elapsed time: 0.19426s