在 python 的自动化测试过程中,使用了 unittest 的测试框架,每个用例可以单独执行,用例之间没有依赖关系。
但是在实际业务过程中,由于业务逻辑较复杂,一般用例之间是有依赖关系的。比如从用户注册到用户下单支付这个流程过程中,只有用户注册账户成功了,后面的所有的测试用例才有意义,一旦注册失败,后面的所有的测试用例都是需要跳过的。所以当前想解决这个问题。查看了 testng 框架,TestNG 依赖测试使用了 dependsOnMethods ,如下图:
这样在 TestNG 中就可以解决用例之间的依赖问题。
在 python 的测试框架中,有没有类似的方法或库,各位是怎么解决的呢 ,谢谢了
有呀 可以写一个装饰器就 ok 了呀
用 pytest 吧
@user1cy(depends=["test_a"])
def test_c():
写一个简单的装饰呗
import unittest
def skipTest(value):
def deco(function):
def wrapper(self, *args, **kwargs):
if not getattr(self, value):
self.skipTest('未登录跳过用例')
else:
function(self, *args, **kwargs)
return wrapper
return deco
class DemoTest(unittest.TestCase):
isOnline = False # 未登录
def test_1(self):
self.assertTrue(1 == 1)
DemoTest.isOnline = True # 成功登陆
@skipTest('isOnline')
def test_2(self):
print("A test")
if __name__ == '__main__':
unittest.main()
这个思路不错,但是如果有多个依赖关系的话,这样就不太好,我一直想获取 test_1 的测试结果,就是获取不到,有了 test_1 的执行结果,就可以判断了
强行去获取结果,也能获取,但是实际上,还不如楼上的用一个变量作为测试结果来的直白。
# coding=utf-8
import unittest
def skip_if_fail_register(func, depend='test_1register'):
def decorator(self):
fail_register = depend in [fail[0]._testMethodName for fail in self._resultForDoCleanups.failures]
test = unittest.skipIf(fail_register, '注册失败')(func)
return test(self)
return decorator
class TestStringMethods(unittest.TestCase):
def test_1register(self):
print('注册账户')
@user1r
def test_2login(self):
print('登录账户')
if __name__ == '__main__':
unittest.main()
好啦,问题已解决,谢谢各位啦,感谢各位提出的思路,感谢@xiaoj (杰) 和@keke
在这里做个总结:
def skipTest(value):
def deco(function):
def wrapper(self, *args, **kwargs):
if not getattr(self, value):
self.skipTest('跳过用例')
else:
function(self, *args, **kwargs)
return wrapper
return deco
这个方法适用于当前的测试类中,当且仅当只依赖一个测试用例的时候使用,比如登录,获取用户信息,退出,在这 3 个测试用例中,获取用户信息和退出都依赖登录,所以可以使用这种依赖方法,如果当前的测试用例还依赖了第二个其他的测试用例,则本方法不适应
2.keke 的方法
def dependon(depend=None):
import functools
def wraper_func(test_func):
@functools.wraps(test_func)
def inner_func(self):
if depend == test_func.__name__:
raise ValueError("{} cannot depend on itself".format(depend))
print("self._resultForDoCleanups", self._resultForDoCleanups.__dict__)
failures = str([fail[0] for fail in self._outcome.result.failures])
errors = str([error[0] for error in self._outcome.result.errors])
skipped = str([error[0] for error in self._outcome.result.skipped])
flag = (depend in failures) or (depend in errors) or (depend in skipped)
test = unittest.skipIf(flag, '{} failed or error or skipped'.format(depend))(test_func)
return test(self)
return inner_func
对这个方法做了一下小小的改动,以上就是最新的代码。其中 depend 参数的类型为 string,值就是测试用例的方法名称。
可以适用于依赖的测试用例失败或错误时都跳过测试用例,有 dependon 装饰器标记的用例必须在用例 depend(test_login)之后执行
此方法适用于 python3.4+,如果是低版本的 python3,请将 self._outcome.result 修改为 self._outcomeForDoCleanups,如果你是 python2 版本,请将 self._outcome.result 修改为 self._resultForDoCleanups
最后,再次感谢各位,祝各位春节快乐!