自动化工具 python 的 unittest 测试框架中的测试依赖怎么解决呢

zhang · January 10, 2019 · Last by zhang replied at January 11, 2019 · 3852 hits

在python的自动化测试过程中,使用了unittest的测试框架,每个用例可以单独执行,用例之间没有依赖关系。
但是在实际业务过程中,由于业务逻辑较复杂,一般用例之间是有依赖关系的。比如从用户注册到用户下单支付这个流程过程中,只有用户注册账户成功了,后面的所有的测试用例才有意义,一旦注册失败,后面的所有的测试用例都是需要跳过的。所以当前想解决这个问题。查看了testng框架,TestNG依赖测试使用了dependsOnMethods ,如下图:

这样在TestNG中就可以解决用例之间的依赖问题。
在python的测试框架中,有没有类似的方法或库,各位是怎么解决的呢 ,谢谢了

共收到 8 条回复 时间 点赞

有呀 可以写一个装饰器就ok了呀

用 pytest 吧

@pytest.mark.dependency(depends=["test_a"])
def test_c():
zhang #3 · January 10, 2019 作者
YueC 回复

嗯啊,这个用过,感觉还是pytest大法好,但是当前只能用unittets实现😂 ,有相关思路吗

zhang #4 · January 10, 2019 作者
kuale 回复

有这个思路,但是写不出来,没法获取依赖方法的测试执行结果,可以给个demo吗 😀

写一个简单的装饰呗

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()
zhang #6 · January 10, 2019 作者
YueC 回复

这个思路不错,但是如果有多个依赖关系的话,这样就不太好,我一直想获取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('注册账户')

@skip_if_fail_register
def test_2login(self):
print('登录账户')

if __name__ == '__main__':
unittest.main()
zhang #8 · January 11, 2019 作者

好啦,问题已解决,谢谢各位啦,感谢各位提出的思路,感谢@xiaoj (杰) 和@keke

在这里做个总结:

  1. xiaoj (杰)的方法
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

最后,再次感谢各位,祝各位春节快乐!

zhang 关闭了讨论 15 Jan 16:44
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up