import unittest class MyTest(unittest.TestCase): def __init__(self): self.test_login() self.test_query() def test_login(self): print(‘test_login self:‘,id(self)) def test_query(self): print(‘test_query self:‘,id(self)) if __name__ == ‘__main__‘: MyTest()
结果:说明test_login和test_query中的self是一样的
test_login self: 13940664 test_query self: 13940664
继承unittest.TestCase
import unittest class MyTest(unittest.TestCase): def setUp(self): print(‘setup self:‘,id(self)) def tearDown(self): print(‘tearDown self:‘,id(self)) def test_login(self): print(‘test_login self:‘,id(self)) def test_query(self): print(‘test_query self:‘,id(self)) if __name__ == ‘__main__‘: unittest.main()
运行结果:说明test_login和test_query中的self是不一样的,哪怕是在相同的类中
setup self: 17905872 test_login self: 17905872 tearDown self: 17905872 setup self: 17905648 test_query self: 17905648 tearDown self: 17905648
至于上面结果差异的原因,这里不深究,感兴趣的可以去研究下unittest的源码。
上面都是铺垫,这里我们需要考虑的是,接口自动化测试框架中如果关联?
比如我们一个系统需要先登录,后续所有请求都要传登录获取到的token
既然unittest中,哪怕是同一个类中,每个用例的self是不一样的,当然就不能在登录的用例中为self设置一个属性了,self.token=xxx,因为其它用例根本就获取不到
import unittest class MyTest(unittest.TestCase): def setUp(self): print(‘setup self:‘,id(self)) def tearDown(self): print(‘tearDown self:‘,id(self)) def test_login(self): print(‘test_login self:‘,id(self)) self.token = ‘https://www.cnblogs.com/uncleyong/p/10530261.html‘ def test_query(self): print(‘test_query self:‘,id(self)) print(self.token) if __name__ == ‘__main__‘: unittest.main()
报错
Traceback (most recent call last): File "F:/uncleyong/test.py", line 16, in test_query print(self.token) AttributeError: ‘MyTest‘ object has no attribute ‘token‘
方案一:定义依赖方法
如果test_add_b依赖test_add_a,可以把test_add_a改为不是test开头,比如改为add_a,unittest就不会运行add_a,
test_add_b中调用add_a,add_a就就作为test_add_b的一部分来运行,也有必要在add_a中断言是否成功了,如果没成功,就不会执行test_add_b后面的代码,test_add_b这个用例执行也是失败的。
但是,这样略显繁琐,一个py文件不一定只有一个类,且用例不一定在py文件中,这样,每个类中都要写一遍,最好是把token保存为一个全局的
import unittest class MyTest(unittest.TestCase): def setUp(self): print(‘setup self:‘,id(self)) def tearDown(self): print(‘tearDown self:‘,id(self)) def login(self): print(‘test_login self:‘,id(self)) self.token = ‘https://www.cnblogs.com/uncleyong/p/10530261.html‘ def test_query(self): print(‘test_query self:‘,id(self)) self.login() print(self.token) if __name__ == ‘__main__‘: unittest.main()
结果
setup self: 17905032 test_query self: 17905032 test_login self: 17905032 https://www.cnblogs.com/uncleyong/p/10530261.html tearDown self: 17905032
改为静态方法,就需要return
import unittest class MyTest(unittest.TestCase): def setUp(self): print(‘setup self:‘,id(self)) def tearDown(self): print(‘tearDown self:‘,id(self)) @staticmethod def login(): print(‘test_login self‘) token = ‘https://www.cnblogs.com/uncleyong/p/10530261.html‘ return token def test_query(self): print(‘test_query self:‘,id(self)) token = self.login() print(token) if __name__ == ‘__main__‘: unittest.main()
结果
setup self: 17905032 test_query self: 17905032 test_login self https://www.cnblogs.com/uncleyong/p/10530261.html tearDown self: 17905032
其它类也可以用
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
print(‘setup self:‘,id(self))
def tearDown(self):
print(‘tearDown self:‘,id(self))
@staticmethod
def login():
print(‘test_login self‘)
token = ‘https://www.cnblogs.com/uncleyong/p/10530261.html‘
return token
def test_query(self):
print(‘test_query self:‘,id(self))
token = self.login()
print(token)
class MyTest2(unittest.TestCase):
def setUp(self):
print(‘setup self:‘,id(self))
def tearDown(self):
print(‘tearDown self:‘,id(self))
def test_delete(self):
print(‘test_query self:‘,id(self))
token = MyTest.login()
print(token)
if __name__ == ‘__main__‘:
unittest.main()
结果
setup self: 17836464 test_query self: 17836464 test_login self https://www.cnblogs.com/uncleyong/p/10530261.html tearDown self: 17836464 setup self: 17835792 test_query self: 17835792 test_login self https://www.cnblogs.com/uncleyong/p/10530261.html tearDown self: 17835792
问题:如果是支持并发,用例a和用例b都依赖登录的token,用例a先调用登录获取到了token,但是由于网络原因,导致请求还没发送到服务器
此时用例b有获取到token(之前的token失效),那么用例a可能就执行失败了
调用登录,传不同的登录用户名
方案二:定义单例模式的实例变量
单例模式,只有一个实例,测试登录的时候,给这个实例添加一个实例变量,后续的接口要依赖登录的token,直接从实例变量中获取即可。
方案三:写入文件
测试登录的时候,就把获取到的token写入文件,后续的接口要依赖登录的token,直接从文件中读取即可。