python_unittest

1.基础知识

setUp和tearDown是每一次test_xx都会执行的,即使加上@classmethod也做不到每个类只执行一次

import unittest

class TestDemo001(unittest.TestCase):
    @classmethod
    def setUp(cls):
        print("====setup========")

    @classmethod
    def tearDown(cls):
        print("=====tearDown======")

    def test_001(self):
        print("======test001====")

    def test_002(self):
        print("======test002======")

if __name__ == "__main__":
    unittest.main()

setUpClass和tearDownClass是每个类只执行一次,而且必须配合@classmethod才会生效

import unittest

class TestDemo001(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("====setup========")

    @classmethod
    def tearDownClass(cls):
        print("=====tearDown======")

    def test_001(self):
        print("======test001====")

    def test_002(self):
        print("======test002======")

if __name__ == "__main__":
    unittest.main()

2.抽象requests方法

import requests
import json

data = {
    "username":"aaa",
    "password":"123123"
}
url = "http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html"
class RunMain:
    def __init__(self,url,method,data=None):
        self.res = self.run_main(url,method,data)

    def send_get(self,url,data=None):
        result = requests.get(url).json()
        return json.dumps(result,indent=2,sort_keys="true")

    def send_post(self,url,data):
        result = requests.post(url,data).json()
        return json.dumps(result,indent=2,sort_keys="true")

    def run_main(self,url,method,data=None):
        res = None
        if method == "GET":
            res = self.send_get(url,data)
        else:
            res = self.send_post(url,data)
        return res

if __name__ == "__main__":
    run = RunMain(url,"GET",data)
    print(run.res)

3、基本断言方法

基本的断言方法提供了测试结果是True还是False。所有的断言方法都有一个msg参数,如果指定msg参数的值,则将该信息作为失败的错误信息返回。

序号断言方法断言描述
1assertEqual(arg1, arg2, msg=None)验证arg1=arg2,不等则fail
2assertNotEqual(arg1, arg2, msg=None)验证arg1 != arg2, 相等则fail
3assertTrue(expr, msg=None)验证expr是true,如果为false,则fail
4assertFalse(expr,msg=None)验证expr是false,如果为true,则fail
5assertIs(arg1, arg2, msg=None)验证arg1、arg2是同一个对象,不是则fail
6assertIsNot(arg1, arg2, msg=None)验证arg1、arg2不是同一个对象,是则fail
7assertIsNone(expr, msg=None)验证expr是None,不是则fail
8assertIsNotNone(expr, msg=None)验证expr不是None,是则fail
9assertIn(arg1, arg2, msg=None)验证arg1是arg2的子串,不是则fail
10assertNotIn(arg1, arg2, msg=None)验证arg1不是arg2的子串,是则fail
11assertIsInstance(obj, cls, msg=None)验证obj是cls的实例,不是则fail
12assertNotIsInstance(obj, cls, msg=None)验证obj不是cls的实例,是则fail

4、unittest的全局变量

1.setupclass里设置self.xxx变量,不同用例之间无法实时共享参数变动

2.setupclass里设置globals().["xxx"]变量,不同用例之间可以实时共享参数变动

3.setupclass里设置 ClassName.XXX变量,不同用例之间可以实时共享参数变动

4.setupclass之前设置 XXX变量

 

2.setupclass里设置globals().["xxx"]

from settings import *
import requests,json
import unittest


class Login(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        api_token = '/v1/api/common/getToken'
        self.real_token_url = API_TEST_BASE_URL + api_token
        globals()["token"] = None

    def test_get_token(self):
        r = requests.post(url=self.real_token_url)
        globals()["token"] = json.loads(r.text)['model']['token']
        print("第一个case获得的token:",globals()["token"])
        return globals()["token"]

    def test_get_u(self):
        print("第二个case获得token值:",globals()["token"])

if __name__ == '__main__':
    unittest.main()


执行结果:

第一个case获得的token: 44c5fcccca6c4e64a1c5d314b7ee22fc
第二个case获得token值: 44c5fcccca6c4e64a1c5d314b7ee22fc

3.setupclass里设置 ClassName.XXX变量

import unittest

class Mydemo(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        Mydemo.a = "88"

    def test1(self):
        print("test1-----{}".format(Mydemo.a))
        Mydemo.a = "99"

    def test2(self):
        print("test2-----{}".format(self.a))
        print("test2_2---{}".format(Mydemo.a))


if __name__ == '__main__':
    unittest.main()
复制代码
执行结果:

test1-----88
test2-----99
test2_2---99

4.setupclass之前设置 XXX变量

class AlienTest(unittest.TestCase):
    status = 200

    @classmethod
    def setUpClass(cls):
        cls.url = "http://www.baidu.com"
        globals()['status'] = 300

    def test_1_alien(self):
        print("test_1_status:", self.status)

    def test_2_alien(self):
        self.status = 404
        print("test_2_status", self.status)

    def test_4_alien(self):
        print("test_4_global_status", globals()['status'])
        print("test_4_status", self.status)


if __name__ == '__main__':
    unittest.main()


test_1_status: 200
test_2_status 404
test_4_global_status 300
test_4_status 200

5.unittest中方法的执行顺序

结论: unittest执行测试用例,默认是根据用例的方法名 的  ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z

那么如何控制用例执行顺序呢?

方式1,通过TestSuite类的addTest方法,按顺序加载测试用例

 1 # coding=utf-8
 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
 3 
 4 #2.注释:包括记录创建时间,创建人,项目名称。
 5 '''
 6 Created on 2019-4-23
 7 @author: 北京-宏哥
 8 Project:学习和使用unittest框架编写测试用例执行顺序
 9 '''
10 #3.导入unittest模块
11 import unittest
12 #4.执行顺序和运行测试
13 import unittest
14 
15 class TestLogin(unittest.TestCase):
16 
17     def setUp(self):
18         pass
19     def test_login_blog(self):
20         """登录博客园
21 
22         :return:
23         """
24         print("登录博客园")
25     def test_add_essay(self):
26         """ 添加随笔
27 
28         :return:
29         """
30         print("添加随笔")
31     def test_release_essay(self):
32         """ 发布随笔
33 
34         :return:
35         """
36         print("发布随笔")
37     def test_quit_blog(self):
38         """退出博客园
39 
40         :return:
41         """
42         print("退出博客园")
43 
44     def tearDown(self):
45         pass
46 if __name__ == '__main__':
47     # 启动单元测试
48     # unittest.main()
49 
50     # 获取TestSuite的实例对象
51     suite = unittest.TestSuite()
52 
53     # 将测试用例添加到测试容器中
54     suite.addTest(TestLogin('test_login_blog'))
55     suite.addTest(TestLogin('test_add_essay'))
56     suite.addTest(TestLogin('test_release_essay'))
57     suite.addTest(TestLogin('test_quit_blog'))
58 
59     # 创建TextTestRunner类的实例对象
60     runner = unittest.TextTestRunner()
61     runner.run(suite)
62     #unittest.TextTestRunner(verbosity=3).run(suite)

方式2,通过修改函数名的方式

 1 # coding=utf-8
 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
 3 
 4 #2.注释:包括记录创建时间,创建人,项目名称。
 5 '''
 6 Created on 2019-4-23
 7 @author: 北京-宏哥
 8 Project:学习和使用unittest框架编写测试用例执行顺序
 9 '''
10 #3.导入unittest模块
11 import unittest
12 #4.执行顺序和运行测试
13 import unittest
14 
15 class TestLogin(unittest.TestCase):
16 
17     def setUp(self):
18         pass
19     def test_1_login_blog(self):
20         """登录博客园
21 
22         :return:
23         """
24         print("登录博客园")
25     def test_2_add_essay(self):
26         """ 添加随笔
27 
28         :return:
29         """
30         print("添加随笔")
31     def test_3_release_essay(self):
32         """ 发布随笔
33 
34         :return:
35         """
36         print("发布随笔")
37     def test_4_quit_blog(self):
38         """退出博客园
39 
40         :return:
41         """
42         print("退出博客园")
43 
44     def tearDown(self):
45         pass
46 if __name__ == '__main__':
47     # 启动单元测试
48     unittest.main()

6.unittest----skip装饰器

@unittest.skip(reason)   无条件跳过用例,reason是说明原因

@unittest.skipIf(conditionreason)    condition为true的时候跳过

@unittest.skipUnless(condition, reason)   condition为False的时候跳过

@unittest.expectedFailure 

(Mark the test as an expected failure. If the test fails when run, the test is not counted as a failure.)将测试标记为预期的失败。 如果测试在运行时失败,则该测试不算作失败。

断言的时候跳过(暂时不知道有啥用,没看懂,貌似断言失败,也变成用例pass了。)  

7. HTMLTestRunner生成报告

1、下载HTMLTestRunner报告(只是一个py文件),http://tungwaiyip.info/software/HTMLTestRunner_0_8_2/HTMLTestRunner.py

2、将该文件保存在python安装路径下的lib文件夹中。在文件中能import HTMLTestRunner成功,即配置成功

注意:

在python3中用HTMLTestRunner.py报importError“:No module named 'StringIO'解决办法

  1. 原因是官网的是python2语法写的,看官手动把官网的HTMLTestRunner.py改成python3的语法。

  2. 修改内容:
第94行,将import StringIO修改成import io

第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()

第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:

第631行,将print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))

第766行,将uo = o.decode('latin-1')修改成uo = e
 
第772行,将ue = e.decode('latin-1')修改成ue = e

生成报告的代码:

import unittest
import HTMLTestRunner

class TestDemo001(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("====setup========")
        globals()["abc"] = "111"

    @classmethod
    def tearDownClass(cls):
        print("=====tearDown======")

    def test_002(self):
        print("======test002======")
        res = "1001"
        print("globals()[\"abc\"]===", globals()["abc"])
        #self.assertEqual(res,"1001","测试成功")

    def test_001(self):
        print("======test001====")
        res = "1000"
        print("globals()[\"abc\"]===",globals()["abc"])
        #self.assertEqual(res, "1001", "测试成功")

    @unittest.skip("test_bw")
    def test_000(self):
        print("======000====")
        globals()["abc"] = "000"
        print("globals()[\"abc\"]===", globals()["abc"])

if __name__ == "__main__":
    #unittest.main()
    suite = unittest.TestSuite()
    suite.addTest(TestDemo001("test_001"))
    suite.addTest(TestDemo001("test_002"))

    filepath = "../report/demo001.html"
    f = open(filepath,"wb")
    run = HTMLTestRunner.HTMLTestRunner(stream=f,title="这是一个demo001测试报告")
    run.run(suite)

关于python3 使用pycharm+unittest+html+HTMLTestRunner 测试用例运行正常,但却不能生成测试报告的解决方法

该方法适用于以下条件:

1.运行测试用例一切正常,只是没有测试报告显示

2.使用命令行pyhon 脚本名字.py 却可以生成测试报告

pycharm 在运行测试用例的时候 默认是以unittest 框架来运行的,所以不能生成测试报告

如何判断是否是用unitest框架运行的呢?

运行完成后,如果发现右上角有unittest in ***** ,说明是以框架的方式来运行的

设置运行方式如已下步骤,设置完成后,再运行就能够生产报告了

 

1、如何使用python开发测试框架?

python开发,request进行网络请求,unnitest管理case(断言,跳过),生成测试报告(HTMLTestRunner),数据的存储,持续集成(批处理文件),

2、如何管理case

两个case之间有依赖:skip,case写在excel

3.简述case的执行

case的执行顺序

4.如何解决case的依赖

全局变量

5.如何生成测试报告

HTMLTesTRunner

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值