python接口自动化测试 unittest框架官网学习

简介:

Unittest 是一个单元测试框架。以面向对象的方式提供了以下概念:

  • test fixture 测试夹具  # 表示执行一个或多个测试所需要的测试,以及任何相关的清除动作
  • test case 测试用例  # 测试用例是测试的各个单元。它检查对特定输入集的特定响应
  • test suite 测试套件   # 一个测试套件是测试案例,测试套件,或两者的集合。它用于聚合应该一起执行的测试
  • test runner 测试执行器  # 执行测试并输出测试结果

测试用例发现约定:

测试用例方法必须以 test_开头

测试用例类必须以 Test开头

测试文件必须以 test_开头

多个用例根据用例名称顺序执行

命令行运行方式:

# 指定多个测试模块运行
python -m unittest test_module1 test_module2
# 指定测试模块的路径运行
python -m unittest path/test_module.py
# 指定测试类内的测试用例方法运行
python -m unittest test_module.TestClass
# 指定测试模块内的测试类内的测试用例方法运行
python -m unittest test_module.TestClass.test_method


# 参数
-v 更详细的输出结果
-s directory 指定开始搜索的目录
-p pattern  指定文件匹配模式(默认是 test*.py)
-t directory  指定项目的最上层目录(默认是开始时所在的目录)

代码内运行:

import unittest
from utils.HTMLTestRunner import HTMLTestRunner

if __name__ == '__main__':
    # suite = unittest.TestSuite()
    # 添加单个用例
    # suite.addTest(test=TestOneClass("test_001_login"))
    # suite.addTest(test=TestOneClass("test_002_register"))

    # 添加用例集
    # testcases = [TestOneClass("test_001_login"), TestOneClass("test_002_register")]
    # suite.addTests(tests=testcases)

    # 指定目录查找测试用例集
    suite = unittest.defaultTestLoader.discover(start_dir="./testcase", pattern="test_*.py")

    # 运行  添加defaultTest 可以指定运行的测试套件。默认运行全部用例。
    unittest.main(defaultTest="suite")
    # 默认运行全部用例
    # unittest.main()
    # 使用 HTMLTestRunner 报告运行
    with open(os.path.join("report", "testreport.html"), "wb") as f:
        HTMLTestRunner(stream=f, title="unittest test report", description="this is description").run(suite)

跳过

import unittest


class DemoOne(unittest.TestCase):
    @unittest.skip(reason="直接跳过")
    def test_1_02(self):
        self.assertEqual(1, 1)

    @unittest.skipIf(condition=(1 == 1), reason="条件满足 跳过")
    def test_1_03(self):
        self.assertEqual(1, 1)

    @unittest.skipUnless(condition=(1 == 1), reason="条件满足 不跳过")
    def test_1_04(self):
        self.assertEqual(1, 10)

    @unittest.expectedFailure  # 预期失败,如果用例断言失败,不会将结果添加到失败统计中
    def test_1_05(self):
        ic("@unittest.expectedFailure")
        self.assertEqual(1, 2)


@unittest.skip(reason="跳过类")
class DemoTwo(unittest.TestCase):
    def test_2_01(self):
        self.assertEqual(1, 3)

子测试,测试用例内继续测试

class DemoTwo(unittest.TestCase):
    def test_2_01(self):
        self.assertEqual(1, 3)

    def test_2_02(self):
        self.assertEqual(10, 10)
        for i in range(5):
            with self.subTest(i==i):  # 使用子测试,可以在测试用例方法内继续执行测试用例
                self.assertEqual(i % 2, 0)

下图为执行结果

unittest.TestCase内的断言方法

Method

Checks that

New in

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

Method

Checks that

New in

assertAlmostEqual(a, b)

round(a-b, 7) == 0

assertNotAlmostEqual(a, b)

round(a-b, 7) != 0

assertGreater(a, b)

a > b

3.1

assertGreaterEqual(a, b)

a >= b

3.1

assertLess(a, b)

a < b

3.1

assertLessEqual(a, b)

a <= b

3.1

assertRegex(s, r)

r.search(s)

3.1

assertNotRegex(s, r)

not r.search(s)

3.2

assertCountEqual(a, b)

ab具有相同数量的相同元素,无论它们的顺序如何

3.2

测试套件添加

suite = unittest.TestSuite()
# 测试套件 方式一:单个添加,顺序执行
# suite.addTest(DemoOne("test_1_01"))
# suite.addTest(DemoThree("test_3_01"))
# suite.addTest(DemoOne("test_1_04"))

# 测试套件 方式二:通过列表管理用例集,顺序执行
# test_cases = [DemoOne("test_1_01"), DemoThree("test_3_01"), DemoOne("test_1_04")]
# suite.addTests(test_cases)
# 测试套件 方式三:通过 模块名.类名 加载用例
suite.addTests(unittest.TestLoader().loadTestsFromNames(names=["demo2.DemoThree", "demo1.DemoOne"]))
# 测试套件 方式三:通过 类名 加载用例
# suite.addTests(unittest.TestLoader().loadTestsFromTestCase(testCaseClass=DemoOne))
# 测试套件 方式三:通过 指定路径加载用例
# discover = unittest.defaultTestLoader.discover(start_dir=current_path, pattern="demo*.py")

运行测试,生成报告

import unittest


# txt报告
with open(current_path + "\\report.txt", "w") as report:
    # verbosity=2 输出详细结果  可选:0:不输出;1:简单输出(默认显示 . 的方式);2:详细
    runner = unittest.TextTestRunner(stream=report, verbosity=2)
    runner.run(test=suite)
    runner.run(test=discover)

# 使用html报告 需要将HTMLTestRunner.py复制到Python/lib目录下
from HTMLTestRunner import HTMLTestRunner
with open(current_path + r"\report.html", 'wb') as report:
    # verbosity=2 输出详细结果  可选:0:不输出;1:简单输出(默认显示 . 的方式);2:详细
    runner = HTMLTestRunner(stream=report, title="测试报告", description="描述", verbosity=2).run(test=suite)
    # runner.run(test=discover)
HTMLTestRunner 报告下载地址 ,提取码:pjiz

接口自动化:
        +, 接口session使用,关联
          

import unittest
import warnings
import requests

# 模块级别 在当前模块内最先执行
def setUpModule():
    createConnection()

# 模块级别 在当前模块内最后执行
def tearDownModule():
    closeConnection()



class TestShop(unittest.TestCase):
    @classmethod
    def setUpClass(cls):  # 类级别 在当前类内最先执行
        pass

    @classmethod
    def tearDownClass(cls):  # 类级别 在当前类内最后执行
        pass

    def setUp(self):  # 方法级别 在每个方法前执行
        # 初始化实例化session对象
        self.session = requests.session()
        warnings.filterwarnings("ignore")

    def tearDown(self):  # 方法级别 在每个方法结束后执行
        self.session.close()

    def test_code(self):
        # 实例化响应结果
        response = self.session.get("http://localhost/index.php?m=Home&c=User&a=verify")
            try:
                # 断言响应码
                self.assertEqual(200, response.status_code)
                # print("状态码成功")
                # 断言响应类型
                self.assertIn("image", response.headers.get("Content-Type"))
                # print("图片类型成功")
            except Exception as e:
                print(e)

    def test_login(self):
        self.test_code()
        url_login = "http://localhost/index.php?m=Home&c=User&a=do_login"
        data = {"username": "13899999999", "password": "111111", "verify_code": "8888"}
        response = self.session.post(url_login, data)
        try:
            # print(response.json())
            self.assertEqual(1, response.json().get("status"))
            self.assertIn("登陆成功", response.json().get("msg"))
        except Exception as e:
            print(e)

    def test_order(self):
        self.test_login()
        url_order = "http://localhost/Home/Order/order_list.html"
        response = self.session.get(url_order)
        # print(response.text)
        try:
            self.assertEqual(200, response.status_code)
        except Exception as e:
            print(e)


    
    
    
        1,直连数据库:
          

 """方法封装"""
import pymysql

class Utils:
    #获取链接
    @classmethod
    def get_con(cls):
        con = pymysql.Connect(host="localhost",
                                          user="root",
                                          password="root",
                                          port=3306,
                                          database="books",
                                          charset="utf8")
        return con

    #获取游标
    @classmethod
    def get_cursor(cls, con):
        cursor = con.cursor()
        return cursor

    #关闭链接,关闭游标
    @classmethod
    def close_resource(cls, con, cursor):
        if con:
            con.close()
            con = None
        if cursor:
            cursor.close()
            cursor = None

if __name__ == '__main__':
    con = Utils().get_con()
    cur = Utils().get_cursor(con)
    try:
        cur.execute("select title from t_book")
        cur.execute("select * from t_book")
        print(cur.fetchall())
        #事物提交
        con.commit()
    except Exception as e:
        #事物回滚
        cur.rollback()
    finally:
        #关闭链接,关闭游标
        Utils().close_resource(con, cur)


        
        
        2,mock

"""mock模拟接口实现,解除第三方接口依赖,模拟系统异常"""
from unittest import mock


# 前置接口
def login(tel, name):
    return False


# 后置接口
def cart():
    if login:
        print("通过")


class Test:
    @classmethod
    def test_cart(cls):
        # 模拟登陆成功
        login = mock.Mock()
        if login:
            flag = login("123", "1234")
        print(flag)
        cart()
        
        
if __name__ == '__main__':
    Test().test_cart()


        
        
        3,统计数据库查询结果的行数: cursor.rowcount()
            获取一行数据:cursor.fetchone()
            获取所有行: cursor.fetchall()
            获取cookies: response.cookies
            获取cookies的某一项的值: response.cookies.get("PHPSESSION")
            响应状态码:response.status_code
            响应文本:response.text
            响应URL:response.url
            响应头:response.headers
            响应编码集:response.encoding
            
 


                

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值