什么了解suite集合实现
def run(self, result):
for index, test in enumerate(self):
if result.shouldStop:
break
test(result) #就这一句----test为什么还可以传值,那时候也很少看源码只知道用。。。最近在写平台--感觉不了解内部原理-有点僵硬-所以决定干unittest源码
if self._cleanup:
self._removeTestAtIndex(index)
return result
def run(self, result):
for index, test in enumerate(self):
if result.shouldStop:
break
test(result) #就这一句----test为什么还可以传值,那时候也很少看源码只知道用。。。最近在写平台--感觉不了解内部原理-有点僵硬-所以决定干unittest源码
if self._cleanup:
self._removeTestAtIndex(index)
return re在撸它之前得先了解一个内置函数__repr__
class C(object):
def test_1(self):
pass
def test_2(self):
pass
def test_3(self):
pass
if __name__ == "__main__":
print(test_C) #<class '__main__.test_C'> class是一个类--以及所在模块和类名
print(test_C()) #<__main__.test_C object at 0x000000000213C7B8> 所在模块.类名 对象 内存地址 class C(object):
def __repr__(self): #加上这么一句
return "<%s at '假装是一个内存地址'>" %("%s.%s"%(self.__class__.__module__,self.__class__.__qualname__))
def test_1(self):
pass
def test_2(self):
pass
def test_3(self):
pass
if __name__ == "__main__":
print(test_C) #<class '__main__.test_C'> class是一个类--以及所在模块和类名
print(test_C()) #<__main__.test_C at '假装是一个内存地址'> 这个对象名称就编程我们自定义的了 #然后看了这个例子我们明白了---__repr__这个方法这里就是修改对象的展示格式的。。。。
然后在看这个
unitest它是怎么找到用例的--然后生成一个TestSuite集合,现在大部分人都是用discover--尽管不是discover几乎也是这条线路
找用例全流程discover会把【目录】放到环境变量-方便后面_get_modul_from_namet通过文件名称找模块--实际上就是之前把目录加入到环境变量了,然后传文件的全路径走_get_name_from_path-执行一个os.path.relpath方法从之前的目录开始找本次传的文件的相对路径 也就是返回一个文件名--然后_get_modul_from_namet __import__(文件名)动态导入之后-然后返回一个 sys.moduls[”文件名“] 一个【文件对象】
然后这里又调用loadTestsfromModul方法--它执行dir(modul) 找到下面所有的属性 -然后判断他是不是一个类并且属于case.TestCase的子类(就是有没有继承unittest.TestCase)-然后遍历通过getattr(modul,className) 返回一个【类对象】---然后继续又找loadTestsFromTestCase--找方法对象--当初我就被这个方法里面的 map--这个map很关键--在这里用 --建议看下源码--返回然后一个suite集合
class TestCase():
def __init__(self,name="test"):
self.name=name
def __repr__(self):
return "<%s testMethod=%s>" % ("%s,%s"%(self.__class__.__module__, self.__class__.__qualname__), self.name)
def __str__(self):
return "%s (%s)" % (self.name, ("%s.%s"%(self.__class__.__module__, self.__class__.__qualname__)))
class test_C(TestCase):
def test_1(self):
pass
def test_2(self):
pass
def test_3(self):
pass
class BaseTestSuite(object): #假装这是unittest的BaseTestSuite
def __init__(self,tests=()):
# self.b=1
self.tests=[]
self.add(tests)
def __repr__(self):
return "<%s tests=%s>"%(self.__class__,self.tests)
def add(self,tests):
for a in tests:
self.tests.append(a)
class TestSuite(BaseTestSuite): #那么这个就是假装TestSuite
pass
#这个场景贼真实吧-。-
#第一步模拟场景 加环境变量
import os,sys,django os.environ.setdefault("DJANGO_SETTINGS_MODULE","besettest.settings")
django.setup()#如果不是django就不用管这两句 path=r"E:\PyFiles\Besettest\besettest\apps\case" #unitba.py的目录 我们传的目录
sys.path.insert(0,os.path.abspath(r"E:\PyFiles\DjangoBesettest\apps\case")) #加入变量--这一步其实是在discover中完成的
__import__('unitba')
modul=sys.modules[unitba] #这一步是dicvoer调用——>_find_tests——>_find_tests_path——>_get_modul_from_name
suite=unitba.TestSuite #上面已经动态导入了直接用就好
print(modul) #<module 'unitba' from 'E:\\PyFiles\\Besettest\\besettest\\apps\\case\\unitba.py'>
#那这里已经返回了文件对象
for testClassName in dir(modul): #那遍历出来的就是文件对象下面的 属性了
obj=getattr(modul,testClassName) #从modul中取类对象-
if isinstance(obj, type) : #判断他是否是一个类
def isTestMethod(attrname, testCaseClass=obj,p=testMethodPrefix):
return attrname.startswith(p) and callable(getattr(testCaseClass, attrname)) #callable检查是否可调用 getattr(testCaseClass, attrname)
testClassObjs=list(filter(isTestMethod, dir(obj))) #这个filter应该会用吧。。。
MethodObj= list(map(obj, testCase) ) #将方法名传入类对象---这里下面解释为什么可以这样用---只需要记住-这里的testCase是getattr返回的属性值就是个类名 类名(参数) 就实例化了
print(MethodObj) #[<unitba.test_C at '假装是一个内存地址'>, <unitba.test_C at '假装是一个内存地址'>, <unitba.test_C at '假装是一个内存地址'>] #一直到这里--都只是在单纯的找用例对象-那现在改一下用例类-按照unittest的suite格式改 模块名.类名 testMethod=方法名
# unittest格式<case.testss.A tests=[<testss.test_C testMethod=test_1>, <testss.test_C testMethod=test_2>, <testss.test_C testMethod=test_3>]> class test_C(object):
def __init__(self,name="test"): #手动传一个方法名-这里稍微有点绕--没基础的可能有点难理解-我尽量解释。。。。展示先写死
self.name=name
def __repr__(self):
return "<%s.%s testMethod=%s>" % (self.__class__.__module__, self.__class__.__qualname__, self.name)
def test_1(self):
pass
def test_2(self):
pass
def test_3(self):
pass
###然后在执行tests.py
print(MethodObj) #[<unitba,test_C testMethod=test_1>, <unitba,test_C testMethod=test_2>, <unitba,test_C testMethod=test_3>]是不是和里面的数据一样了 ###然后继续执行---
###suite=unitba.TestSuite 上面有定义一个这个东西 suite()就是一个实例化对象了这个能理解吧
###TestSuite继承BaseTestSuite --所以是可以传值的
###name suite(MethodObj)
#suite name接收的值-就是一个这么东西----实际上unittes不是向我这样处理的--但是原理是一样--他传的是一个map对象--我是在前面一步把map对象转换成列表了--而他是通过list(name)转换的
#注意一点----MethodObj里面的对象都是实例对象-实例化的时候传的参数是下面每个方法的名称--然后一个TestsCase类实例化了很个实例对象 他就是这么一个东西
#得到<<class 'case.unitba.TestSuite'> tests=[<unitba,test_C testMethod=test_1>, <unitba,test_C testMethod=test_2>, <unitba,test_C testMethod=test_3>]>
#对比<case.testss.A tests=[<testss.test_C testMethod=test_1>, <testss.test_C testMethod=test_2>, <testss.test_C testMethod=test_3>]>
是不是一样--你可以继续加东西--我这里不完全一样是因为我没有把参数加到和unittetst加到一样
MethodObj= list(map(obj, testCase) )
#这里为什么可以这样用,看下面这个方法就可以理解了---因为obj之前是用一个getattr取出来的值obj=getattr(modul,testClassName) 所以他是可以接受参数的-可以当做一个function用-
class test1():
def add(self,a,b):
return a+b
a=test1()
b=getattr(a,"add") #这个是返回了add的内存地址 加上括号和里面的参数就直接执行了。。
print(b(1,2)) class test2(): #这个也是suite集合生成用的东西
def __call__(self, *args, **kwargs):
return self.add(*args, **kwargs)
def add(self,a,b):
return a+b
a=test2()
print(a(1,2))
class test2():
def __init__(self,tests=None):
self._tests=[]
self.run(tests)
def __repr__(self):
return "<%s tests=%s>" % ("%s.%s"%(self.__class__.__module__,self.__class__.__class__.__qualname__), list(self)) #这里用list(self)
def __iter__(self): #让这个类变成一个可迭代的对象,并且让self._tests变成一个迭代器----那他有什么作用---就是这个对象只能用一次如下
return iter(self._tests) #返回该可迭代对象的的实例 def run(self,tests):
for a in tests:
self._tests.append(a) class test1():
def __init__(self,resul):
self.resul=resul
def __repr__(self):
return "<%s testMethod=%s>" %("%s.%s"%(self.__class__.__module__,self.__class__.__class__.__qualname__), self.resul)
# def __str__(self):
# return self.resul
def test_1(self):
return self.resul,1
def test_2(self):
return self.resul
test2=test2
name=["test1","test2","test3"]
MethodsName=list(filter(lambda x:x.startswith("test"),dir(test1)))
print(MethodsName)#这里打印出来是方法的名字
print(test2(map(test1,MethodsName))) #map(test1,MethodsName))--test("参数") 这个得到结果就是相当于传了不同的方法名--定义了多个实例对象-然后传给test2--得到一个test2的实例对象 #['test_1', 'test_2']
#<__main__.type tests=[<__main__.type testMethod=test_1>, <__main__.type testMethod=test_2>]> #比如:
mapG=map(test1,MethodsName)
a=test2(mapG) #<__main__.type tests=[<__main__.type testMethod=test_1>, <__main__.type testMethod=test_2>]>
b=test2(mapG) #<__main__.type tests=[]>
所suite集合 就是在TestLoader找测试用例的时候--通过_find_tests这个方法从目录开始找文件(子目录)-模块-类-方法名
class test2(): def __init__(self,tests=None): self._tests=[] self.run(tests) def __repr__(self): return "<%s tests=%s>" % ("%s.%s"%(self.__class__.__module__,self.__class__.__class__.__qualname__), list(self)) #这里用list(self) def __iter__(self): #让这个类变成一个可迭代的对象,并且让self._tests变成一个迭代器----那他有什么作用---就是这个对象只能用一次如下 return iter(self._tests) #返回该可迭代对象的的实例 def run(self,tests): for a in tests: self._tests.append(a) class test1(): def __init__(self,resul): self.resul=resul def __repr__(self): return "<%s testMethod=%s>" %("%s.%s"%(self.__class__.__module__,self.__class__.__class__.__qualname__), self.resul) # def __str__(self): # return self.resul def test_1(self): return self.resul,1 def test_2(self): return self.resul test2=test2 name=["test1","test2","test3"] MethodsName=list(filter(lambda x:x.startswith("test"),dir(test1))) print(MethodsName)#这里打印出来是方法的名字 print(test2(map(test1,MethodsName))) #map(test1,MethodsName))--test("参数") 这个得到结果就是相当于传了不同的方法名--定义了多个实例对象-然后传给test2--得到一个test2的实例对象 #['test_1', 'test_2'] #<__main__.type tests=[<__main__.type testMethod=test_1>, <__main__.type testMethod=test_2>]> #比如: mapG=map(test1,MethodsName) a=test2(mapG) #<__main__.type tests=[<__main__.type testMethod=test_1>, <__main__.type testMethod=test_2>]> b=test2(mapG) #<__main__.type tests=[]>
什么了解suite集合实现的更多相关文章
- 【Selenium】3.介绍Selenium IDE
本文供学习交流之用,没有商业用途,没有盈利. 完全是我自己为督促自己学习而翻译的.翻译的不好,见谅.来源于:http://www.guru99.com/introduction-selenuim-id ...
- 一步一步教你编写与搭建自动化测试框架——python篇
[本文出自天外归云的博客园] 这两天用python写了一个自动化测试框架,取名为Auty.准备用来做Web方面的接口测试,以下为Auty框架一步一步的搭建过程——
- java单元测试(Junit)
JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用. 对不同性质的被 ...
- [翻译]NUnit---Action Attributes(八)
Attributes NUnit 1.0使用传统的基于继承和命名约定来识别测试.从2.0开始NUnit使用自定义特性来实现. 因为NUnit的test fixtures不是从框架类库继承,所以开发人员 ...
- python自动化测试框架unittest
对于刚学习python自动化测试的小伙伴来说,unittest是一个非常适合的框架: 通过unittest,可以管理测试用例的执行,自动生成简单的自动化测试报告: 首先我们尝试编写编写一个最简单的un ...
- unittest(1)
一.unittest核心概念 1.unittest四个核心概念 unittest四个核心概念包括:TestCase.TestSuite.TestRunner.Test Fixture TestCase ...
- TestLoader源码解析
def loadTestsFromTestCase(self, testCaseClass) #看名称分析:从TestCase找测试集--那么就是把我们的def用例加载到testSuit里面 def ...
- 微软极品工具箱-Sysinternals Suite
工具包由来 Sysinternals Suite是微软发布的一套非常强大的免费工具程序集,一共包括74个windows工具.Sysinternals是Winternals公司提供的免费工具,Winte ...
- Github优秀java项目集合(中文版) - 涉及java所有的知识体系
Java资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-java 就是 akullpp 发起维护的 Java 资源列表,内容 ...
随机推荐
- 微信小程序订阅
微信小程序订阅 摘要 1.基于promise封装微信小程序订阅 2.解决由于微信基础库版本低下的兼容 3.解决“总是保持以上选择,不再询问”的取消状态 主要运用API: requestSubscrib ...
- 那些面试官必问的JAVA多线程和并发面试题及回答
Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环 ...
- [书籍分享]0-001.rework(重来:更为简单有效的商业思维)
封面 内容简介 大多数的企业管理的书籍都会告诉你:制定商业计划.分析竞争形势.寻找投资人等等.如果你要找的是那样的书,那么把这本书放回书架吧. 这本书呈现的是一种更好.更简单的经商成功之道.读完 ...
- [JavaWeb基础] 005.Hibernate的配置和简单使用
1.Hibernate简介 Hibernate是一个基于Java的开源的持久化中间件,对JDBC做了轻量的封装.采用ORM映射机制,负责实现Java对象和关系数据库之间的映射,把sql语句传给数据库, ...
- RocketMQ安装及入门
本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文RocketMQ版本为rocketmq-all-4.7.0,系统为win10.请各位去官网下载,也可以留言,我发安装包 RocketMQ安装 ...
- 用TensorFlow搭建一个万能的神经网络框架(持续更新)
我一直觉得TensorFlow的深度神经网络代码非常困难且繁琐,对TensorFlow搭建模型也十分困惑,所以我近期阅读了大量的神经网络代码,终于找到了搭建神经网络的规律,各位要是觉得我的文章对你有帮 ...
- 开心一下-实现基于Java一个中文编程语言
https://mp.weixin.qq.com/s/TsTiLVF5D07-wbDMk9bsyQ 这不是认真的,不是真的要去实现一个中文编程语言. 多年以前,有位同学把Java代码发给我说帮 ...
- 震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……
过场CG: 接到公司领导的文件指示,“小熊”需要在6月底去海外执行一个行动代号为[定时任务]的营救计划,这个计划关系到公司某个项目的生死(数据安全漏洞),作战部拟定两个作战方案: 方案一:使用务定 ...
- Java实现 蓝桥杯 基础练习 闰年判断
基础练习 闰年判断 时间限制:1.0s 内存限制:256.0MB 提交此题 锦囊1 锦囊2 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 年份是4的倍数而不是1 ...
- Java实现 蓝桥杯VIP 算法训练 邮票
算法训练 邮票 时间限制:1.0s 内存限制:512.0MB 问题描述 给定一个信封,有N(1≤N≤100)个位置可以贴邮票,每个位置只能贴一张邮票.我们现在有M(M<=100)种不同邮资的邮票 ...