脚本需求:
遍历检查一组数据是否符合条件 ,抛出不符合条件数据。
错误实践:
for i,Information in enumerate(List_AMls):
self.assertEqual(self.List_AMls,0,msg = "{}信息错误".format(Information))
执行脚本,当某一个数据不符合条件后,直接抛出了异常,之后的数据就验证不到了!
原因分析:
首先出现这个问题,在于对assertEqual方法实现原理不清晰导致的。好吧,如果你也遇到这种问题,请跟着笔者的错误脚本走下去吧~
想知道一个方法实现的什么功能?那还不简单,看代码!
ctrl+鼠标左键:点击asserEqual,可以看到这个代码对应的内容
def assertEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ...
好吧,这个是真的没看懂,看代码,算了,好好的看文档吧。https://docs.python.org/3/library/unittest.html Unittest单元测试框架说明
asserEqual,被归类在了Debug方法之一,用于检查并报告故障。所以,推测方法的功能:符合条件的通过,不符合条件的报错!报的和其他系统错误相同。
原因总结:assertEqual,判断内容如果不符合条件,就会抛出异常。如果不处理,Unittest就直接把这条用例视为执行失败了。但是,这不是我们想要的呀!
想要什么:
升职、加薪、迎娶白富美、出任CEO。。。。 串场了,我们要的不是这些物质!!!我们只做纯粹的测试工程师
我们想要能够识别出一些列数据,每一条是否符合条件,最终在结论里输出不符合条件的数据!
但是现在,有一个不同,就抛异常了,for循环就不执行了,后续的执行不下去了!
bug已经定位到了。笔者在之后的尝试中,总结了两种方法:
方法1:判断直接在基础方法中进行,在unittest中,将结果进行比对
方法2:做异常处理,使用try....except。捕捉出现的异常,做特殊处理。【这个方法被pass了,原因1:捕捉异常需要对异常做存储,还要继续处理未处理的数据,实现代价比较大;原因2:由于本地框架的构思,unittest作为最后的判断步骤,只对结果做验证,对数据的处理,尽量都放到方法中做。】
我感觉吧,如果只写到这,看完了心里肯定要吐笔者一口,所以,最后直接把实现的源码放下面了哈~
方法1:源码
第一部分:基础方法中识别问题,并记录在列表中
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-05-15 13:22
# function/test.py
# 业务功能脚本(用例脚本可调用此处的功能脚本)
from UI_T3c_V1.encapsulation.encapsulation import UIHandle
from UI_T3c_V1.config.config_YYQR import Application_List,YYDZ
from UI_T3c_V1.config.config_YYQR import browser_config
from selenium.common.exceptions import NoSuchElementException
from time import sleep
import re
# import pymysql
# 设置一个全局变量,验证点击进入到登录页面次数
class UI_Eureka_Get_Data():
def __init__(self):
# 数据字典,用于保存页面中抓取数据
self.dict_Data = {}
# 应用错误表
self.Error_List_Application = [0]
# 状态错误表
self.Error_List_Status = [0]
# 应用数错误表
self.Error_List_Availability_Zones = [0]
# AMIS错误表
self.Error_List_AMIs = [0]
def get_data(self):
"""
从地址中获取所有字段内容:Application【应用名称】、Amls【】、Availability_Zones【可用环境数】、Atatus【状态】
将数据保存到Table_dict 字典中
:return:返回生成的字典信息
"""
driver = browser_config['chrome']()
uihandle = UIHandle(driver)
# 输入url地址
uihandle.get(YYDZ)
sleep(2)
# 从列表中获取数据
table = driver.find_element_by_xpath('//*[@id="instances"]')
for count in range(1,len(Application_List)+10):
try: # 判断是否能够定位到应用元素,如果定位不到,说明列表已经完成遍历,跳出循环
Applation = table.find_element_by_xpath('//*[@id="instances"]/tbody/tr[%s]/td[1]/b'%count).text # 获取应用名
except NoSuchElementException:
break
AMls = table.find_element_by_xpath('//*[@id="instances"]/tbody/tr[%s]/td[2]/b' % count).text # 获取AMIS内容
try: # 默认查找up状态的字段,查找不到说明状态非up,则需要调用其他状态的格式位置
Status = table.find_element_by_xpath('//*[@id="instances"]/tbody/tr[%s]/td[4]/b'%count).text # 获取状态值
count_parren = table.find_element_by_xpath('//*[@id="instances"]/tbody/tr[%s]/td[4]'%count).text
# print(Status)
Availability_Zones = re.search('\d',count_parren).group() # 正则表达式过滤出数字
self.dict_Data[Applation] = [AMls, Status, Availability_Zones] # 生成内容插入字典,第一位AMIS ,第二位,状态,第三位:应用数量
except NoSuchElementException:
# print(count)
count_parren = table.find_element_by_xpath('//*[@id="instances"]/tbody/tr[%s]/td[4]'% count).text
Status = re.search('\w+',count_parren).group()
Availability_Zones = re.search('\d', count_parren).group()
self.dict_Data[Applation] = [AMls, Status, Availability_Zones]
driver.quit() # 关闭浏览器
# print(self.dict_Data)
def Data_Analysis(self):
"""
分析从Eureka环境中获取的数据,针对数据内容,分析是否符合要求
分析逻辑:
1. 根据提供列表的名称进行比对,确认应用是否存在
2. 应用状态是否都为up
3. 可用应用数量是否为1
以上3条,某一条没有验证通过,则向Error_list【错误列表】中插入一条数据
:return:
"""
Dict_Eureka = self.dict_Data
# 从配置读取应用,在列表中排查应用是否存在,如果不存在则返回字段内容
for count, Application in enumerate(Application_List):
if(Dict_Eureka.get(Application, "False") == "False"):
self.Error_List_Application[0] += 1
self.Error_List_Application.append("{}应用不存在,请联系对应团队".format(Application))
else:
# 判断应用状态是否为N/A
if(Dict_Eureka[Application][0] != "n/a"):
self.Error_List_AMIs[0] += 1
self.Error_List_AMIs.append("{}应用的AMIs值错误,错误值为{},请联系对应团队".format(Application,Dict_Eureka[Application][0]))
# 判断应用状态是否为UP
if(Dict_Eureka[Application][1] != "UP"):
self.Error_List_Status[0] += 1
self.Error_List_Status.append("{}应用的状态值错误,错误状态为{},请联系对应团队".format(Application, Dict_Eureka[Application][1]))
# 判断启动应用数量是否为1
if(Dict_Eureka[Application][2] != "1"):
self.Error_List_Availability_Zones[0] += 1
self.Error_List_Availability_Zones.append("{}应用存在{}个启动服务,请确认是否存在不可用服务".format(Application,Dict_Eureka[Application][2]))
# print(self.Error_List_AMIs)
# print(self.Error_List_Status)
# print(self.Error_List_Availability_Zones)
# return self.Error_List_Application,self.Error_List_AMIs,self.Error_List_Status,self.Error_List_Availability_Zones
def Main_Methos(self):
self.get_data()
self.Data_Analysis()
# 程序测试脚本,验证功能通过后,需要注释掉
# if __name__ == "__main__":
# list = UI_Eureka_Get_Data().Data_Analysis()
# for data in list:
# print(data)
第二部分:unittest框架直接通过比对列表数据项,判断是否存在异常,如果存在则打印
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019-06-15 13:05
import unittest
from UI_T3c_V1.function.UI_Eureka import *
from UI_T3c_V1.config.config_YYQR import Application_List
# 用例
class UI_Eureka(unittest.TestCase):
'''验证Eureka启动后,应用是否存在异常情况'''
@classmethod
def setUpClass(self):
self.Test = UI_Eureka_Get_Data()
self.Test.Main_Methos()
self.Error_List_Application = self.Test.Error_List_Application
self.Error_List_AMls = self.Test.Error_List_AMIs
self.Error_List_Status = self.Test.Error_List_Status
self.Error_List_Application_Zones = self.Test.Error_List_Availability_Zones
def test_3_Check_Application(self):
"""
Eureka验证--是否存在未启动应用
:return:
"""
if self.Error_List_Application[0] != 0 :
for i,Error in enumerate(self.Error_List_Application):
if i == 0 : continue
print(Error)
self.assertEqual(self.Error_List_Application[0],0,msg = "Eureka应用检查未全部通过,存在{}个未启动服务,信息如上".format(self.Error_List_Application[0]))
def test_4_Check_AMls(self):
"""
Eureka验证--AMls是否都为n/a
"""
if self.Error_List_AMls[0] != 0:
for i,Error in enumerate(self.Error_List_AMls):
if i == 0 : continue
print(Error)
self.assertEqual(self.Error_List_AMls[0],0,msg = "AMIS检查未全部通过,存在{}条错误数据,信息如上".format(self.Error_List_AMls[0]))
def test_5_Check_Status(self):
"""
Eureka验证--应用状态是否都为UP
"""
if self.Error_List_Status[0] != 0:
for i,Error in enumerate(self.Error_List_Status):
if i == 0: continue
print(Error)
self.assertEqual(self.Error_List_Status[0],0,msg = "状态检查未全部通过,存在{}条可疑数据,信息如上".format(self.Error_List_Status[0]))
def test_6_Check_Application_Zones(self):
"""
Eureka验证--应用数量验证是否都为1
"""
if self.Error_List_Application_Zones[0] != 0:
for i,Error in enumerate(self.Error_List_Application_Zones):
if i == 0 : continue
print(Error)
self.assertEqual(self.Error_List_Application_Zones[0], 0, msg="应用数量检查未全部通过,存在{}条可疑数据,信息如上".format(self.Error_List_Application_Zones[0]))
def tearDown(self):
pass
if __name__ == "__main__":
unittest.main()