api-automation-test/ApiAutomationTest/app/cores/assertion.py

121 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# coding=utf-8
from typing import Tuple, Optional, Iterable
import re
import lxml.etree
class _Assert:
def __init__(self, expected: str, actual: str, negater: bool, failure_msg: str=None):
"""
:param expected: 期望值
:param actual: 实际值
:param negater: 是否取反
:param failure_msg: 错误信息 (暂未支持自定义错误信息)
"""
self.expected = expected
self.actual = actual
self.failure_msg = failure_msg
self.negater = negater
def result(self) -> bool:
"""断言结果判断"""
pass
def custom_failure_msg(self):
"""错误信息"""
pass
def exec(self) -> Tuple[bool, Optional[str]]:
if self.result() ^ self.negater: # 异或
return True, None
else:
if hasattr(self, 'custom_failure_msg'):
return False, self.custom_failure_msg()
else:
return False, self.failure_msg
class AssertEqual(_Assert):
def result(self):
return self.expected == self.actual
def custom_failure_msg(self):
if not self.negater:
return '实际值与期望值不相等: [期望值: %s][实际值: %s]' % (self.expected, self.actual)
if self.negater:
return '实际值与期望值相等: [期望值: %s][实际值: %s]' % (self.expected, self.actual)
class AssertSubString(_Assert):
def result(self):
return self.expected in self.actual
def custom_failure_msg(self):
if not self.negater:
return '实际值未包含指定期望值: [期望值: %s][实际值: %s]' % (self.expected, self.actual)
if self.negater:
return '实际值包含指定期望值: [期望值: %s][实际值: %s]' % (self.expected, self.actual)
class AssertContains(_Assert):
def result(self):
res = re.findall(pattern=self.expected, string=self.actual)
return len(res) > 0
def custom_failure_msg(self):
if not self.negater:
return '实际值中未匹配到正则: [正则: %s][实际值: %s]' % (self.expected, self.actual)
if self.negater:
return '实际值中匹配到正则: [正则: %s][实际值: %s]' % (self.expected, self.actual)
class AssertMatches(_Assert):
def result(self):
res = re.fullmatch(pattern=self.expected, string=self.actual)
return bool(res)
def custom_failure_msg(self):
if not self.negater:
return '实际值完整未匹配到正则: [正则: %s][实际值: %s]' % (self.expected, self.actual)
if self.negater:
return '实际值完整匹配到正则: [正则: %s][实际值: %s]' % (self.expected, self.actual)
class AssertXPath(_Assert):
xpath_separator = '|xpathSeparator|'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.xpath = self.expected.split(self.xpath_separator)[0]
self.text = self.expected.split(self.xpath_separator)[-1]
self.match_element_count = 0 # xpath匹配到元素数量
def result(self):
html = lxml.etree.HTML(self.actual)
elements = html.xpath(self.xpath)
if not isinstance(elements, Iterable):
return False
self.match_element_count = len(elements)
if len(elements) > 1:
return False
elif len(elements) == 1:
element = elements[0]
if isinstance(element, str):
return True if self.text == element else False
else:
return True if self.text == element.text else False
else:
return False
def custom_failure_msg(self):
if not self.negater:
if self.match_element_count > 1:
return '指定的XPath路径 %s 匹配到了 %s 个元素请调整XPath表达式使其只匹配到一个被测元素' % (self.xpath, self.match_element_count)
if self.match_element_count == 0:
return '指定的XPath路径 %s 未匹配到任何元素' % self.xpath
return '未在指定的XPath路径 %s 下找到文本内容 %s' % (self.xpath, self.text)
if self.negater:
return '在指定的XPath路径 %s 下找到文本内容 %s' % (self.xpath, self.text)