比如登录失败时,就跳过退出登录的用例,示例代码如下,大神求教,应该怎么写才能达到跳过的效果,如果使用@unittest.skipIf(),但是我怎么知道上个用例失败了呢
import unittest
class TestDemo(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setupclass")
def setUp(self):
print("setup")
def test_login(self):
print("test_login")
self.assertEqual(1, 2) # 这里让登录判断为失败
def test_logout(self):
print("test_logout")
def tearDown(self):
print("teardown")
@classmethod
def tearDownClass(cls):
print("teardownclass")
if __name__ == "__main__":
testsuite = unittest.TestSuite()
testsuite.addTest(TestDemo("test_login"))
testsuite.addTest(TestDemo("test_logout"))
runner = unittest.TextTestRunner()
runner.run(testsuite)
我自己解决了哈哈哈,主要使用两个知识点,装饰器和 TestCase中的_outcome.result (python2中为_resultForDoCleanups),具体代码如下
import unittest
from functools import wraps
def skip_dependon(depend=""):
"""
:param depend: 依赖的用例函数名,默认为空
:return: wraper_func
"""
def wraper_func(test_func):
@wraps(test_func) # @wraps:避免被装饰函数自身的信息丢失
def inner_func(self):
if depend == test_func.__name__:
raise ValueError("{} cannot depend on itself".format(depend))
# print("self._outcome", self._outcome.__dict__)
# 此方法适用于python3.4 +
# 如果是低版本的python3,请将self._outcome.result修改为self._outcomeForDoCleanups
# 如果你是python2版本,请将self._outcome.result修改为self._resultForDoCleanups
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)
if failures.find(depend) != -1:
# 输出结果 [<__main__.TestDemo testMethod=test_login>]
# 如果依赖的用例名在failures中,则判定为失败,以下两种情况同理
# find()方法:查找子字符串,若找到返回从0开始的下标值,若找不到返回 - 1
test = unittest.skipIf(flag, "{} failed".format(depend))(test_func)
elif errors.find(depend) != -1:
test = unittest.skipIf(flag, "{} error".format(depend))(test_func)
elif skipped.find(depend) != -1:
test = unittest.skipIf(flag, "{} skipped".format(depend))(test_func)
else:
test = test_func
return test(self)
return inner_func
return wraper_func
class TestDemo(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setupclass")
def setUp(self):
print("setup")
def test_login(self):
print("test_login")
self.assertEqual(1, 2) # 这里让登录判断为失败
@skip_dependon(depend="test_login")
def test_logout(self):
print("test_logout")
self.assertEqual(1, 1)
@skip_dependon(depend="test_logout")
def test_1(self):
print("test1")
@skip_dependon(depend="test_1")
def test_2(self):
print("test2")
def tearDown(self):
print("teardown")
@classmethod
def tearDownClass(cls):
print("teardownclass")
if __name__ == '__main__':
testsuite = unittest.TestSuite()
testsuite.addTest(TestDemo("test_login"))
testsuite.addTest(TestDemo("test_logout"))
testsuite.addTest(TestDemo("test_1"))
testsuite.addTest(TestDemo("test_2"))
runner = unittest.TextTestRunner()
runner.run(testsuite)
import json
import re
import unittest
import requests
from inspect import isfunction
from functools import wraps
def skipIf(exp, reason):
"""自己实现unittest.skipIf 装饰器,不满足条件跳过测试用例,原因?装饰器是静态编译的,而unittest.skipIf在编译时就会判断condition是否满足条件,
如果我们想要动态决定是否跳过测试用例,就需要在执行测试用例的时候,在执行之前判断条件是否满足
:param exp: 依赖的表达式
:param reason: 跳过原因
:return: wraper_func
"""
def wraper_func(test_func):
@wraps(test_func) # @wraps:避免被装饰函数自身的信息丢失
def func(self):
if isfunction(exp):
res = exp()
if res == 1:
self.skipTest(reason)
return
else:
return test_func(self)
else:
raise TypeError('条件必须是函数')
return
return func
return wraper_func
status = 0
class Test(unittest.TestCase):
request = requests.Session()
def setUp(self):
print('setup')
# name = input("请输入name:")
# print(name)
def tearDown(self):
print('tearDown')
@classmethod
def setUpClass(cls):
print('setUpClass')
@classmethod
def tearDownClass(cls):
print('tearDownClass')
def test_True(self):
self.assertTrue(True)
def test_login(self):
headers = {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"origin": "https://passport.mp-t.mallcoo.cn",
"x-requested-with": "XMLHttpRequest"
}
data = {
'username': '345345',
'password': '34534',
'ispersistent': 'true'
}
r = self.request.post(
'https://passport.mp-t.mallcoo.cn/Home/PostLogin', data=data, headers=headers)
res = r.json()
global status
if res["success"] == 1: # 1 代表true, 0 代表false#
print('登陆成功')
status = 200
else:
print('登陆失败')
status = 500
self.assertTrue(res["success"], "登陆成功")
@skipIf(lambda: status == 500, "登录失败")
def test_getWeatherCitys(self):
r = self.request.get(
'http://bi.mp-t.mallcoo.cn/Project/GetWeatherCitys?_c=1567591439050')
res = r.json()
if res['dic'][0]['Code'] == 'beijing':
try:
assert res['sussess'] == 1 # 1 代表true, 0 代表false#
print('断言通过')
except AssertionError as e:
print('断言不通过')
else:
print('464641830@qq.com' + "登录失败")
if name == '__main__':
suite = unittest.TestSuite()
tests = [Test("test_True"), Test("test_login"),
Test("test_getWeatherCitys")]
suite.addTests(tests)
with open('UnittestTextReport.txt', 'a', encoding='utf-8', errors='ignore') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)