安装 参考 : https://pipenv.pypa.io/en/latest/ 安装使用 pipenv 进行环境管理和版本管理
1 2 3 4 5 6 $ pip install pipenv $ pipenv install --pypi-mirror https://mirrors.aliyun.com/pypi/simple/ --skip-lock ... Installing dependencies from Pipfile.lock (c5e5dd)... To activate this project's virtualenv, run pipenv shell. Alternatively, run a command inside the virtualenv with pipenv run.
设置 pycharm 的运行环境Preferences | Project: {project-name} | Python Interpreter
, 设置 Python Interpreter
为刚刚安装的虚拟环境的目录
文件目录和规范 文件树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 . ├── Pipfile # 环境文件 ├── README.md # Readme ├── __init__.py ├── assets # 资源文件 ├── poppy # 框架方法定义 │ ├── api_url.py │ ├── fake.py │ ├── params.py │ └── system │ ├── __init__.py │ ├── captcha.py │ └── user_login.py ├── reports # 报告 ├── run.py # 支持环境的运行 ├── test.py # 测试运行 ├── test.py.sample └── tests # 测试文件 ├── 1-base # 基础 │ ├── __init__.py │ └── test_sign.py # 基础 - 验证签名 ........
tests 文件命名规范 文件命名 文件名称参考 tests/1-base/test_sign.py
说明:
1 2 3 tests/ 1-base/ # 1 可以约定执行顺序外并无其他用途 test_sign.py # 文件名需要以 test_ 作为前缀, 来作为自动化执行的遍历(框架约定)
class 命名 例如上面的 tests/1-base/test_sign.py
, class 类名应当为 TestBaseSign
class 名称组合示例
1 2 3 4 tests/1-base/test_sign.py TestBaseSign Base : 文件夹名称的驼峰模式 Sign : 文件名称的驼峰模式(去除test)
方法命名 方法需要以 test_
作为函数前缀
1 2 3 4 5 6 7 8 9 10 11 12 13 class TestBaseSign (seldom.TestCase): """ 测试用例查询 """ def test_secret (self ): """ 项目不使用签名也可以进行访问 """ self.post(PySystem.authLogin, data={ "_py_secret" : cache.get('_py_secret' ) }) self.assertStatusCode(200 )
编写请求 因为请求继承自 requests
, 所以传递的参数遵循 requests
约定Developer Interface — Requests 2.28.1 documentation
编写 http 请求 1 2 3 4 5 self.get("http://httpbin.org/get" , params=payload) self.get("http://httpbin.org/post" , data=payload)
编写 request 请求 对于当前版本来讲, get 请求可能返回乱码, 所以可以用 requests
替代
1 2 3 4 5 6 7 def test_pc (self, _, url ): """ 测试 Pc """ resp = requests.get(Seldom.base_url + url)) self.assertTrue(resp.status_code, 200 )
因为 requests 返回的内容和 seldom 框架不一致, 需要用 requests 提供的方法进行校验
1 2 3 4 5 6 7 8 9 10 11 >>> r = requests.get('https://api.github.com/user' , auth=('user' , 'pass' ))>>> r.status_code 200 >>> r.headers['content-type' ]'application/json; charset=utf8' >>> r.encoding'utf-8' >>> r.text'{"type":"User"...' >>> r.json(){'private_gists' : 419 , 'total_private_repos' : 77 , ...}
运行 运行单个测试 虽然 seldom 继承了 unittest
, 但是直接在 ide 中运行单元测试则会丢失 seldom 的使用便捷性, 所以不允许使用 ide 进行代码运行 复制 test.py.sample
并重命名为 test.py
, 可以调整 seldom.main 的参数来运行单个例子: 使用方法参考: 快速开始 | seldom文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 if __name__ == "__main__" : cache.clear() cache.set ({ '_device_id' : '11223344' , '_device_type' : 'webapp' , }) seldom.main( case ="tests.1-base.test_sign.TestBaseSign" , base_url="http://poppy.duoli.com" , title="Poppy 接口测试" , tester="多厘" , language="zh-CN" , description="基本的接口测试" )
运行方式
运行环境测试 在开发过程中, 我们不可避免的会对不同的环境进行完整测试, 这里用到了 seldom 的 平台化支持 | seldom文档 我们可以在注释中添加 [prod]
或者 [dev, test]
来区分运行环境
1 2 3 4 class TestSeoProdOther (seldom.TestCase): """ [prod]测试其他蜘蛛的访问 """
运行
1 $ python run.py --env dev
断言 断言继承与 unittest, 这里做一个简单的说明
seldom.case(框架断言) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 assertAlertText assertElement assertInPath assertInTitle assertInUrl assertJSON 断言接口返回的某部分数据 assertNotElement assertNotText assertPath 是基于 jmespath 实现的断言 assertSchema assertStatusCode assertText assertTitle assertUrl
unittest
方法
检查对象
引入版本
assertEqual(a,b)
a == b
assertNotEqual(a,b)
a != b
assertTrue(x)
bool(x) is True
assertFalse(x)
bool(x) is False
assertIs(a,b)
a is b
3.1
assertIsNot(a,b)
a is not b
3.1
assertIsNone(x)
x is None
3.1
assertIsNotNone(x)
x is not None
3.1
assertIn(a,b)
a in b
3.1
assertNotIn(a,b)
a not in b
3.1
assertIsInstance(a,b)
isinstance(a, b)
3.2
assertNotIsInstance(a,b)
not isinstance(a, b)
3.2
方法
用作比较
引入版本
assertRaises(exc,fun,*args,**kwds)
fun(*args, **kwds) 引发了 exc
assertRaisesRegex(exc,r,fun,*args,**kwds)
fun(*args, **kwds) 引发了 exc 并且消息可与正则表达式 r 相匹配
3.1
assertWarns(warn,fun,*args,**kwds)
fun(*args, **kwds) 引发了 warn
3.2
assertWarnsRegex(warn,r,fun,*args,**kwds)
fun(*args, **kwds) 引发了 warn 并且消息可与正则表达式 r 相匹配
3.2
assertLogs(logger,level)
with 代码块在 logger 上使用了最小的 level 级别写入日志
3.4
assertNoLogs(logger,level)
with 代码块没有在
3.10
方法
用作比较
引入版本
assertAlmostEqual(a,b)
round(a-b, 7) == 0
assertNotAlmostEqual(a,b)
round(a-b, 7) != 0
assertGreater(a,b)
a > b
3.1
assertGreaterEqual(a,b)
a >= b
3.1
assertLess(a,b)
a < b
3.1
assertLessEqual(a,b)
a <= b
3.1
assertRegex(s,r)
r.search(s)
3.1
assertNotRegex(s,r)
not r.search(s)
3.2
assertCountEqual(a,b)
a 和 b 具有同样数量的相同元素,无论其顺序如何。
3.2
相关框架
语雀镜像 : 测试框架 Seldom ,点此 提问