接口自动化之assertpy断言
一、简介
assertpy
库是一个非常易读且功能强大的Python断言库,它提供了一种简洁的链式API,使得测试代码更加清晰和可读。以下是使用assertpy
进行接口自动化测试时的一些优势及详细代码示例:
from assertpy import assert_that
import requests
def test_complex_response():
# 发送请求并获取响应
response = requests.get('http://api.example.com/complex-endpoint')
data = response.json()
# 预期的数据结构示例
expected_data = {
'user': {
'id': 1,
'name': 'John Doe',
'email': 'john.doe@example.com'
},
'posts': [
{'title': 'Post 1', 'content': 'Content of post 1'},
{'title': 'Post 2', 'content': 'Content of post 2'}
]
}
# 使用assertpy进行断言
assert_that(data).is_equal_to(expected_data)
assertpy
都可以深度比较两个字典是否完全相等。assertpy
提供了更加面向对象和可读性强的语法,它的优势在于可以链式调用多个断言方法,从而让测试代码更为紧凑且易于阅读
二、安装使用
1、安装
pip install assertpy
2、易读性
由于其链式调用的特性,可以在一行内完成多个条件判断,提高代码的紧凑性和可读性。
from assertpy import assert_that
import requests
def test_api_response():
# 获取响应数据
response = requests.get('http://api.example.com/user/1')
data = response.json()
# 使用assertpy进行验证
assert_that(data).is_not_none().contains_key('user').extracting('user').is_instance_of(dict)
assert_that(data['user']).contains_entry('id', 1).contains_entry('name', 'John Doe')
3、丰富的断言方法
除了基本的等于、不等于之外,还有针对各种类型的数据进行复杂验证的方法。
def test_list_response():
response_data = [
{'id': 1, 'title': 'Post 1'},
{'id': 2, 'title': 'Post 2'},
]
# 验证列表长度并检查元素内容
assert_that(response_data).has_length(2)
assert_that(response_data).extracting('title').contains_exactly('Post 1', 'Post 2')
def test_string_response():
response_text = "Hello, World!"
# 验证字符串包含特定子串
assert_that(response_text).starts_with('Hello,').ends_with('World!')
# 检查字符串是否全大写或小写
assert_that(response_text).is_upper()
assert_that(response_text).is_lower()
4、自定义错误消息
可以通过.described_as()
方法添加自定义错误描述。
def test_custom_error_message():
user_id = 10
actual_name = 'Jane Doe'
expected_name = 'John Doe'
assert_that(actual_name).is_equal_to(expected_name).described_as(f'For user id {user_id}, expected name to be {expected_name} but got {actual_name}')
5、异常处理
可以方便地验证某个代码块是否会抛出预期的异常。
def test_expected_exception():
def divide_by_zero():
return 1 / 0
# 验证函数是否会抛出ZeroDivisionError
assert_that(divide_by_zero).raises(ZeroDivisionError).when_called()
三、assertpy与Hamcrest断言
1、Hamcrest优势
-
匹配器模式:Hamcrest采用了匹配器(Matcher)的设计模式,通过组合各种预定义的匹配器或者自定义匹配器来验证对象属性或复杂条件。这使得测试代码具有很强的灵活性和可读性。
示例:
Python
from hamcrest import assert_that, has_entry, equal_to response_data = {'id': 1, 'name': 'John Doe'} # 使用Hamcrest进行断言 assert_that(response_data, has_entry('id', equal_to(1)))
-
语义化:Hamcrest的断言更具语义性,比如
.contains_string()
,.is_in()
等方法可以清晰地表明测试意图。 -
广泛兼容:Hamcrest最初为Java开发,但有Python版本,且支持多种测试框架,如unittest、pytest等,易于与现有项目集成。
2、Hamcrest劣势
- 学习曲线:相比于简单的内置断言,Hamcrest需要了解并熟悉其特定的匹配器API,增加了学习成本。
- 链式调用不直观:虽然Hamcrest支持一定的链式调用,但相比assertpy等现代断言库,其链式结构并不明显,有时需要更复杂的语法构造复杂的断言。
3、Assertpy优势
- 简洁易用:assertpy提供了直观且易于理解的API,使用简单明了的链式调用来进行一系列断言。
- 面向对象风格:assertpy的API设计遵循了Python的面向对象原则,通过方法调用实现断言,符合Python程序员的习惯。
- 内建丰富:assertpy包含了一系列针对Python数据类型的直接断言方法,例如对列表、字典、字符串等类型的操作非常便捷。
4、Assertpy劣势
- 功能相对有限:相比于Hamcrest提供的丰富多样的匹配器,assertpy的功能集可能没有那么全面,对于非常复杂的条件匹配可能需要更多的代码。
- 扩展性略逊:尽管assertpy提供了一些基础的自定义断言机制,但在构建复杂匹配逻辑时,可能不如Hamcrest通过组合匹配器灵活。
综上所述,选择Hamcrest还是assertpy主要取决于项目的具体需求、团队习惯以及个人喜好。如果关注的是强大的断言能力和高度定制化,Hamcrest是一个好选择;而如果追求简洁、快速上手和日常开发中的便捷性,则assertpy可能会更加合适。