主頁 > 後端開發 > 學習筆記之軟體測驗2:基于Python的單元測驗方法(Testcase+Pytest)

學習筆記之軟體測驗2:基于Python的單元測驗方法(Testcase+Pytest)

2020-10-15 23:18:39 後端開發

前言

  • 文章比較詳細,建議先收藏
  • 下一步:專案的具體測驗
  • 有任何問題,評論區留言

單元測驗目錄

  • 單元測驗的目的
    • 單元測驗的由來
    • 單元測驗的優勢
  • Request模塊
    • Request模塊簡介
      • 介紹
      • 安裝
    • 請求方式以及回應
      • HTTP介面動詞說明
      • 查詢引數對應的request模塊中的請求方式
    • Request模塊使用(Httpbin.org)
  • Django單元測驗
    • 說明
    • 資料庫環境準備
    • Testcase
      • setUp和tearDown函式
      • assert斷言捕獲例外的方法
    • Client
      • 說明
      • 登錄測驗兩種實作方法
    • FactoryRequest
      • 簡介
      • 用戶中心登錄測驗
    • mock
      • 簡介
      • mock實操
  • Pytestest單元測驗
    • Pytest介紹
      • pytest是什么
      • pytest的優點
    • Pytest環境準備
      • 安裝
      • 組態檔
      • demo
      • 運行方式
    • Pytest相關函式使用
      • Pytest-assert+warning
      • Pytest-setup/teardown
      • Pytest-fixture
      • Pytest-mark
    • Pytest的插件
      • Pytest-html-生成測驗報告
      • Pytest-orderingrun-控制函式執行順序
      • Pytest-rerunfailures-重測驗失敗的用例
    • Yaml
      • Yaml是什么
      • PyYAML決議

單元測驗的目的

單元測驗的由來

在軟體測驗的發展程序中衍生的一種測驗方法,能夠更高效率、更簡潔地實作軟體系統的模塊化的測驗,

單元測驗的優勢

  • 極大程度上節約測驗時間
    復雜的互動場景中自動化地幫助自己測驗組件,更快速的定位錯誤代碼位置,
  • 測驗本身不僅是發現錯誤,更能預防錯誤
    測驗能夠協助開發以更清晰的思路認識自己的代碼問題,只有認識到代碼問題才能夠讓代碼優化,帶給客戶更優質的體驗,
  • 能夠讓代碼更加簡潔
    測驗后的代碼,邏輯更加清晰,能夠減少代碼冗余,

Request模塊

Request模塊簡介

介紹

一、說明

? Request模塊是一個模擬用戶在客戶端發送各種請求的基于HTTP協議的Python庫

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-P8V9rGXa-1602593196197)(C:\Users\Pine\Desktop\03.png)]

二、作用

  • 軟體測驗使用:腳本化發送請求并分析回傳資料是否例外
  • 爬蟲使用:模擬用戶腳本化自動采集網路資源

安裝

# 切換虛擬環境!!!  安裝鏡像源為清華園
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple 

請求方式以及回應

HTTP介面動詞說明

在這里插入圖片描述

查詢引數對應的request模塊中的請求方式

查詢引數所有請求方式->requests.get(params={})
請求體 json引數非get請求方式(post、put、delete)->requests.post(json={})
請求體 form引數非get請求方式(post、put、delete)->requests.post(data={})
引數傳遞方式requests 接收的關鍵引數名字
請求頭引數所有請求方式->requests.get(headers={})

Request模塊使用(Httpbin.org)

httpbin.org說明:之后的測驗案例都采用對這個網站進行請求的方案

  1. 作用:測驗HTTP的Request請求并回傳對應的Response資訊,適用于GET、POST各種請求介面
  2. 專案架構:基于Python的Flask框架 開源
  3. Github地址:https://github.com/Runscope/httpbin
  4. 官網:http://httpbin.org/
  • Get 請求

    import requests
    from requests import Request, Session
    
    # 1. 定義URL物件
    # url = 'http://www.meiduo.site:8080/'
    url = 'http://httpbin.org/get'
    # 2. 新建request物件 注意+請求方式
    response = requests.get(url)
    # 3. 檢查獲取的資料格式以及內容列印到一個檔案中
    with open('test1.html', 'w') as f:
        f.write(response.text)
        
    # 4. 可以列印response觀察物件型別
    print(type(response))
    # text方法默認列印的回傳資料的json格式
    print(response1.text)
    
    # 默認列印的是回傳資料二進制資料
    print(response1.content)
    # b'{\n  "args": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.23.0", \n    "X-Amzn-Trace-Id": "Root=1-5f818280-636d615a13bf7f173724951b"\n  }, \n  "origin": "106.121.5.147", \n  "url": "http://httpbin.org/get"\n}\n'
    
    • 回傳結果展示
      在這里插入圖片描述
  • POST請求

    # 1. URL
    URL = 'http://httpbin.org/post'
    # 2. request物件
    json_dict = {
        'user': '吳亦凡'
    }
    # 傳入資料 data:表單資料  json:json資料
    # response = requests.post(URL, data=json_dict)
    # response = requests.get(url,params=json_dict)
    response = requests.post(URL, json=json_dict)
    # 3. 寫入檔案
    with open('test1.html', 'w', encoding='utf-8') as f:
        f.write(response.text)
    
    • 回傳結果
      在這里插入圖片描述
  • 回應物件相關屬性說明

    # 1.獲取回應物件的資料 text(requests 會使用其推測的文本編碼)->string型別
    response.text
    # 2.獲取回應物件的資料 content->bytes型別
    # decode() 將 bytes-> str
    response.content.decode()
    # 3.前端回傳狀態碼(無論資料是否驗證正確,都會回傳200狀態碼,測驗判斷不能用狀態碼)
    response.status_code
    # 4.前后端分離開發模式下,存在一個問題無論資料是否驗證正確,都會回傳200狀態碼,測驗判斷不能用狀態碼  
    # 測驗網站登錄功能,介面規定登錄成功回傳json->{'code':0 ,'msg':oK}
    # 4.1獲取回應物件的 json資料---json()
    response.json()
    # 5.獲取請求頭資訊
    response.requests.headers
    # 6.獲取回應頭資訊
    response.headers
    # =====防止被反爬添加請求頭的資訊====
    # 添加請求頭資訊
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'
    }
    request.get(url, headers=headers)
    
  • Cookie請求

    cookie作用:1. 常用與用戶登錄后,登錄狀態資訊的保存 2. 快取一些其他資訊

    # ===方法1:request物件中攜帶cookies====
    # 1. url
    url = 'http://httpbin.org/cookies'
    # 2. 定義cookie值  dict:強制型別轉換
    cookies = dict(cokie_is='Richerd')
    # 3. response加上cookie值
    # response = requests.post(URL, data=cookies)
    response = requests.get(url, cookies=cookies)
    # print(response.text)
    # 4. 寫入檔案
    with open('test1.html', 'w', encoding='utf-8') as f:
        f.write(response.text)
        
    # ===方法2: 直接使用cookie中的RequestsCookieJar()===
    # 這里引入 request.cookie
    # 1.實體化cookie_jar物件
    jar = requests.cookies.RequestsCookieJar()
    # 2.設定cookie
    # jar.set(請求頭key值, value值, 域名, 路徑)
    jar.set('coo', 'zhenxiang', domain='httpbin.org', path='/cookies')
    # 3.url
    url = 'http://httpbin.org/cookies'
    # 4.獲取物件
    response = requests.get(url, cookies=jar)
    print(response.text)
    
  • Session請求

    seesion作用:和cookie類似用于保存一些資訊,但瀏覽器中往往存的是seesionid值,真正的session資訊存盤在資料庫中

    request模塊中Session和Cookie的請求登錄的區分

    • request.get()

    requests.get() 就可以發送請求, 但是 遇到涉及登錄的時候, 應該先發送登錄請求->登錄成功獲取cookies->可以去請求需要登錄認證的頁面

    * 1.login請求: 攜帶賬戶和密碼 response = requests.post(url, json=xxx)
    * 2.決議登錄成功的:cookie   = response.request._cookies
    * 3.登錄用戶中心請求 '/mytaobao...':requests.get('<https://i.taobao.com/my_taobao.htm?spm=xxxx', cookies=cookies)
    
    • session.get()
      • 1.先訪問的是login的請求-- 攜帶賬戶和密碼 response = session.post()
      • 2.再發送 info 請求 – session.get(‘info’)
    from requests import Session
    
    # 1.創建session物件
    s = Session()
    # 2.發送帶cookie的請求  用url設定一個cookie值 之后的cookie將會一直和session物件系結
    s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
    # 3.獲取cookie值 檢查是否獲取成功
    r = s.get("http://httpbin.org/cookies")
    print(r.text)
    
    
    # 1. 設定 用戶名和密碼  即設定session物件的auth屬性默認值
    s.auth = ('user', 'pass')
    # 2. 可以直接增加請求頭中資訊(在原有請求頭欄位中添加)
    s.headers.update({'test1': 'wangyibo'})
    # 3. 請求頭中再次以引數形式添加另一個請求頭資訊  并檢查請求頭中是否已經添加成功
    # 注意這里或默認auth之前添加的資訊也會一塊合并到請求頭中
    r = s.get('http://httpbin.org/headers', headers={'test2': 'yibowangzha'})
    print(r.text)
    
    • 回傳結果
      在這里插入圖片描述

Django單元測驗

注意!:Django每次測驗每次測驗之前會自動創建一個和專案默認資料庫名稱相同的default臨時資料庫,而且臨時資料庫是復制了專案所有的表但是沒有資料,測驗用例測驗結束后,會把臨時創建的default資料庫洗掉

說明

  • Django的單元測驗模塊繼承自Python自帶的測驗基類unittest
  • postman和unitest的區別
    • Postman適用于介面測驗 —>黑盒測驗
    • unitest適用于代碼邏輯測驗 —>白盒測驗

資料庫環境準備

在Django的settings組態檔中進行對測驗資料庫配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  
        'HOST': '127.0.0.1', 
        'PORT': 3306,  
        'USER': 'root',  
        'PASSWORD': 'mysql',  
        'NAME': 'mysql',
        'OPTION': {'charset': 'utf8'},
      
       # 配置測驗的資料庫
       # 1.單元測驗需要使用的資料庫,測驗執行時,會自動創建新的default資料庫包含TEST庫 
       # 2.每次自動創建的資料庫中沒有測驗資料,而且測驗執行完會自動洗掉測驗資料庫
       # 3.如果和default配置相同,使用默認配置
        'TEST':{
          'NAME':'test',
          'CHARSET': 'utf8',  # 設定測驗資料庫的字符集
          'COLLATION': 'utf8_general_ci',  # 測驗資料表中的行的編碼 
        }, 
    },
}

Testcase

注意事項!!!

  1. 由于使用的是Django自帶的測驗模塊,所以所有的測驗代碼都必須在專案的目錄下,且為Python的package
  2. 創建的測驗函式函式名組成格式 test_xxx
  3. 執行方式為終端執行 python manage.py test 默認一鍵執行所有的測驗代碼
  • 執行摸個應用的測驗 python manage.py 應用名
  • 執行應用下的某個測驗檔案 python manage.py 應用名.test_xxx
  • 執行應用下測驗檔案中的具體測驗類 python manage.py 應用名.test_xxx.Demotest
  • 具體到函式 執行應用下測驗檔案中的具體測驗類 python manage.py 應用名.test_xxx.Demotest.test_xxx

setUp和tearDown函式

  • setUp tearDown

    setUp 和 tearDown函式作用就是在測驗用例代碼執行前/后 做一些準備動作 !!!每個測驗用例執行前后都會執行

    使用場景:測驗之前打開檔案 測驗之后關閉檔案

    class TestDemo(TestCase):
    
        def setUp(self):
            print('---setup---')
    
        def tearDown(self) -> None:
            print('---tearDown---\n')
    
        def test_two(self):
            print('---222---')
    
        def test_three(self):
            print('---3333---')
    
        def test_four(self):
            print('---4444---')
    
    
    class TestDemo2(TestCase):
    
        def test_two(self):
            print('\n---TestDemo---')
    

    測驗結果:

    ---setup---
    ---4444---
    ---tearDown---
    
    ---setup---
    ---3333---
    ---tearDown---
    
    ---setup---
    ---222---
    ---tearDown---
    
    
    ---TestDemo---
    
    
  • @classmthod修飾

    setUpclass 和 tearDownclass 函式在這個類中的所有測驗用例執行前后只會執行一次

    使用場景:測驗用例測驗之前資料庫中添加測驗資料

    class ThreeTest(TestCase):
    
        @classmethod
        def setUpClass(cls):
            print('setUpClass--每個測驗用例類---呼叫一次')
    
        @classmethod
        def tearDownClass(cls):
            print('tearDownClass---每個測驗用例類---呼叫一次')
    
        def test_baidu(self):
            url = 'http://www.baidu.com'
            response = requests.get(url)
            print(response.status_code)
    
        def test_tencent(self):
            url = 'http://www.tencent.com'
            response = requests.get(url)
            print(response.status_code)
    

    回傳結果:

    setUpClass--每個測驗用例類---呼叫一次
    200
    200
    tearDownClass---每個測驗用例類---呼叫一次
    
  • 登錄測驗

    class LoginTest(TestCase):
    
        def test_login(self):
            url = 'http://www.heiheihei.site:8000/login/'
            json_dict = {'username': 'wangyibo', 'password': '12345678'}
            response = requests.post(url, json=json_dict)
            print(response.content.decode())
            
        
    # 登錄成功回傳json字串
    {"code": 0, "errmsg": "ok"}
         
    

assert斷言捕獲例外的方法

# assert 是一個python的關鍵字  作用是捕獲例外  詳細說明查看 https://blog.csdn.net/fengtian12345/article/details/80529510

# 正常使用assert函式
assert (1+1==2)
assert (1+1==3)  # 條件為 false時觸發  AssertionError 例外


# 測驗中使用到的 assert語法   self
self.assert(用于判斷的變數,判斷值,'如果不符合條件的提示')

Django的TestCase中封裝的assert方法:
在這里插入圖片描述

Client

說明

  1. client 自帶login方法 和session類似可以在client物件在被銷毀之前一直攜帶登錄的cookie

  2. client的login不用url地址

  3. client和session發送請求的區別

    session發送的真請求 client發送的偽請求(專案不用運行,直接測驗代碼)

登錄測驗兩種實作方法

unicode-escape編碼集 長這樣b``'\\u4e2d\\u56fd'

# ===================方法1:不使用login方法==================
class LoginTestCase(TestCase):
    def setUp(self):
        # 準備資料庫資料  加一個用戶
        User.objects.create_user(username='liudehua', password='11111111')
        self.client = Client()

    def test_login(self):
        # 1.介面url
        url = '/login/'
        # 2.設定登錄用戶
        json_dict = {'username': 'liudehua', 'password': '11111111'}
        # 3.用client物件進行 post登錄訪問測驗  添加content_type='application/json' 確保向后臺回傳json字串資料
        response = self.client.post(url, data=json_dict, content_type='application/json')
        # 4.檢查回傳資料  是否登陸成功
        print(response.content.decode())
        # 5.由于回傳json資料可能含有其他資料 我們這里只取后臺回傳的狀態碼code
        # 為斷言判斷取值
        code = json.loads(response.content.decode()).get('code')
        # 6.斷言函式 如果code為0則登錄成功  否則輸出‘登錄失敗'
        self.assertEqual(code, 0, '登錄失敗')
        
# =================方法2:使用login函式====================
class LoginTestCase(TestCase):
    def setUp(self):
        # 準備資料庫資料  加一個用戶
        User.objects.create_user(username='wangyibo', password='11111111')
        self.client = Client()

    def test_login(self):
        # 1.使用login函式直接發送請求
        login_result = self.client.login(request='post', username='wangyibo', password='11111111')
        # 登錄成功回傳True  失敗False
        print(login_result)
        # 2.使用斷言函式直接判斷是否登錄成功
        self.assertEqual(login_result, True, '登錄失敗')
        # 3.登錄成功訪問個人中心(檢查cookie攜帶)
        response = self.client.get('/info/')
        # 4.再使用斷言判斷是否訪問成功
        code = json.loads(response.content.decode())['code']
        print(response.content.decode())
        # 檢查cookie資訊
        print('登錄成功之后的cookie:', self.client.cookies)
        # 判斷
        self.assertEqual(code, 0, '個人中心訪問失敗!')

    def tearDown(self) -> None:
        # 退出登錄
        self.client.logout()
        # 檢查退出登錄之后的cookie值是否還在
        print('退出之后的cookie', self.client.cookies)

FactoryRequest

簡介

  • 注意事項

    • 只接受get post put delete head options 和trace 方法,這些方法接受的引數大部分相同, 因為它們只是用來生成請求
    • 它不支持中間件,會話和身份驗證屬性必須由測驗本身提供(如果需要)才能使視圖正常作業
  • 作用

    模擬一個請求物件,直接可以把請求物件傳給指定的視圖函式(作為引數),不需要手動指定url地址,

  • 原理

    # 類視圖:類名稱.as_view()(請求物件)
    # 視圖函式:視圖函式(請求物件)
    
    python manage.py shell
    # shell中匯入
    from django.http import HttpRequest
    from apps.users.views import LoginView
    # 發送請求  登錄介面實作
    request = HttpRequest()
    request.method='post'
    request.url = '/login/'
    
    # response = LoginView().post(request)
    response = LoginView.as_view()(request)
    print(response.content)
    

用戶中心登錄測驗

class LoginInfoTestCase(TestCase):

    def setUp(self) -> None:
        # 實體化物件屬性
        self.factory_request = RequestFactory()
        # 創建用戶
        self.user = User.objects.create_user(
            username='dilireba',
            password='12345678',
        )

    def test_info(self):
        # get方式請求用戶中心 創建factory物件
        factory_request = self.factory_request.get('/info/')
        # 攜帶用戶屬性 為登錄成功
        factory_request.user = self.user
        # 用factory模擬物件訪問用戶中心視圖函式
        response = UserInfoView.as_view()(factory_request)
        print(response.content.decode())
        # 斷言檢查是否進入成功
        code = json.loads(response.content.decode()).get('code')
        self.assertEqual(code, 0, '訪問個人中心失敗!')

mock

簡介

  • 概念

    注意:老django版本中有這個模塊 后來直接封裝到python庫了

    導包方式

    django < 2.0版本 from django.test import mock
    django > 2.0 版本 from unnitest import mock

    Mock是Python中一個用于支持單元測驗的庫,它的主要功能是使用mock物件替代掉指定的用于發送請求的物件,以達到模擬物件的行為,

  • 實作效果

    import requests
    
    def c(url):
        response = requests.get(url)
    

    mock實作程序:

    使用一個mock物件替換掉上面的requests.get函式,然后執行函式c時,c呼叫requests.get的回傳值就能夠由我們的mock物件來決定(若C函式執行成功<不用管具體的函式執行邏輯>接收函式回傳值,若不成功mock物件賦予默認值),而不需要服務器的參與

  • 適用場景

    • 在專案開發程序中,盡早介入測驗->先把基本功能的輸入輸出測驗,
    • 專案開發差不多,但是服務器架設進度緩慢,可以代替與服務器互動程序,提早測驗

mock實操

  • mock函式常用兩個引數說明

    • side_effect 表示被呼叫的函式名
      • 指向一個可呼叫的物件,一般是函式.當mock物件被呼叫時,如果該函式回傳值不是DEFAULT時,那么以該函式的回傳值作為mock物件呼叫的回傳值,
      • 是例外類或者物件時,當mock被呼叫就會被拋出,
      • 若是可迭代物件,mock每次呼叫就會回傳下一個值,若可迭代物件的元素是例外,就會拋出,
    • return_value 表示被呼叫的函式失效情況下的回傳值
    • 如果被呼叫的函式,功能暫未實作,可以通過return_value指定默認的回傳值,用來在測驗用例中進行斷言判斷
  • mock 小案例

    1. mock基礎使用

    # ==============被測驗的功能模塊===========
    
    mport requests
    # side_effect 表示被呼叫的函式名
    
    # return_value 表示被呼叫的函式的回傳值
    
    # B功能->發請求
    def send_req(url):
        print('B 功能....呼叫!')
        resp = requests.get(url)
        return resp.status_code
        pass
    
    
    # A功能->呼叫B
    def post_func():
        return send_req('http://www.baidu.com')
        pass
    
    # =============測驗上述模塊:兩種情況======================
    
    from . import utils
    from unittest import mock
    from django.test import TestCase
    
    class MockTestCase(TestCase):
        
        def test_B_None(self):
            """ 如果B模塊功能未實作"""
            # 1. 實體化mock物件 由于B功能未實作side_effect=None
            mock_obj = mock.Mock(side_effect=None, return_value=200)
            # 2. 替換send_req模塊 假設被post_func呼叫
            utils.send_req = mock_obj
            # 3. 獲取回傳結果  因為設定了 return_value=200 所以回傳結果應該是200
            results = utils.post_func()
            # 4. 斷言檢查是否為200
            self.assertEqual(results, 200, 'B模塊測驗失敗!')
        
        def test_B_function(self):
            """如果B模塊實作"""
            
            # 1.實體化  mock物件  由于B功能實作side_effect=utils.send_req
            mock_obj = mock.Mock(side_effect=utils.send_req, return_value=300)
            # 2.替換 send_req 模塊
            utils.send_req = mock_obj
            # 3. 獲取回傳結果  如果A功能呼叫B模塊成功 則回傳訪問baidu成功的狀態碼200
            results = utils.post_func()
            # 4. 斷言
            self.assertEqual(results, 200, 'B模塊測驗失敗!')
    

    2. mock 檢查是否被呼叫方法

    class TestMockCalled(TestCase):
        def test_func(self):
            # 1.新建mock物件
            mock_obj = mock.Mock(side_effect=utils.send_req, return_value=400)
            # 2.使用mock物件替換功能B函式
            utils.send_req = mock_obj
            # 3.測驗功能B函式訪問百度是否成功
            utils.visit_func()
            # 4.斷言mock物件是否被呼叫
            self.assertEqual(mock_obj.called, True)
            #  call('http://www.itcast.cn')
            self.assertEqual(mock_obj.call_args, True)
            #  [call('http://www.itcast.cn')]
            self.assertEqual(mock_obj.call_args_list, True)
    

    3. mock 背景關系管理器用法

    # ======測驗一個登陸功能的介面視圖函式是否可以正常被呼叫=======
    
    class LoginMockTest(TestCase):
        def test_class(self):
            """模擬類視圖1"""
            # 實體化mock物件
            mock_obj = mock.Mock(return_value=200)
            # mock替換
            LoginView.post = mock_obj
            print('>>>test_class run>>>')
            self.assertEqual(LoginView.post(), 200)
    
        def test_context_mock_use(self):
            # 1.實體化 模擬物件
            mock_obj = mock.Mock(return_value=200)
            # 2.使用背景關系管理器實作視圖具體函式功能測驗
            # 引數1表示被測驗的類,引數2表示測驗類中的方法,引數3表示mock物件
            with mock.patch.object(LoginView, 'post', mock_obj):
                # 3.呼叫視圖函式  此時已經被mock物件替換
                results = LoginView.post()
                print(results)
                # 4.斷言判斷 post方法是否可以呼叫
                self.assertEqual(results, 200, '登錄失敗!')
    

    4. mock的裝飾器用法

    • reverse反向決議函式在django中的使用

      # 路由正向
      客戶端發請求->url->總路由->子路由->視圖函式
      # 路由反向
      視圖函式->路由
      
      # 使用reverse的前提
      # 1. 總路由需要起名稱  在使用的時候直接使用路由名稱即可
       path('', include(('apps.xxx.urls'),namespace="這個總路由的名"))
      # 2. 子路由起名
      path('login/', views.LoginView.as_view(), name='子路由的名'),
      # 3. 呼叫方法
      reverse('總路由名稱:子路由明名稱')
      # 4. 后端重定向用法
      redirect(reverse())
      
    • 裝飾器形式的mock測驗用戶登錄

      class ReverseTest(TestCase):
      
          def setUp(self) -> None:
              self.client = Client()
              self.url = reverse('User:Login')
              User.objects.create_user(username='wangyibo', password='11111111')
      
          # mock 裝飾器 寫法
          # @mock.patch('精確模塊的路徑')
          @mock.patch('apps.users.views.LoginView')
          def test_mock_decorator_order(self, mock_obj):
              # 1.接收 mock物件
              results = mock_obj
              # 2.指定 mock物件添加return_value屬性值
              results.post.return_value = 200
              # 3.添加測驗用戶
              data_dict = {'username': 'wangyibo', 'password': '11111111'}
              # 4. 測驗用 client 發送請求 測驗  注意測驗的測驗物件是被mock替代了的視圖函式 side_effect=登錄的視圖函式
              response = self.client.post(self.url, data=data_dict, content_type='application/json')
              print(response)
              # 4. 斷言
              self.assertEqual(response.status_code, 200, '測驗失敗!')
      
          def test_reverse_url(self):
              # 反向決議輸出檢查
              order_url = reverse('User:Login')
              print('反向決議的路由:', order_url)
      

Pytestest單元測驗

Pytest介紹

pytest是什么

  • 是python的一個用于測驗的框架
  • 適用于任何級別、任何代碼的測驗

pytest的優點

  • 命令列模式工具,撰寫測驗用例簡單,豐富的檔案參考
  • 支持單元測驗和功能測驗還有assert斷言 支持運行由Unittest撰寫的測驗Case
  • 支持跳過某些測驗,對某些預期失敗的case標記為失敗
  • 第三方插件豐富,可自定義
  • 支持引數化

Pytest環境準備

安裝

# !!!最好切換到虛擬環境
workon xxx
pip install pytest

組態檔

pytest的組態檔通常放在測驗目錄下,名稱為pytest.ini,命令運行時會使用該組態檔中的配置

[pytest]

# 1.給 pytest  傳引數  三個插件的組態檔中寫寫法如下
# -s 輸出測驗用例中的print內容  
# --html 插件 將測驗結果輸出為報告網頁  
# --rerun碰見測驗報錯重新測驗幾遍
addopts = -s --html=./a.html --reruns 3

# 2.指定 測驗腳本的 路徑
testpaths = ./

# 3.指定 測驗檔案的 名字
python_files = test_a*.py

# 4.指定 測驗檔案類的 名字  當前的目錄下有指定名稱檔案才會執行
python_classes = Test*

# 5.指定 測驗檔案函式的 名字
python_functions = test_*

demo

# 檔案名    test_demo.py  

import pytest
import requests


def test_one():
    r = requests.get('http://baidu.com')
    assert r.status_code == 200


def test_two():
    r = requests.get('http://baidu.com')
    assert r.encoding == 'utf'

# ======運行結果======
# 第一個測驗無報錯   第二個報錯 結果為 ISO-8859-1 != utf

運行方式

都是在終端環境下運行如下命令

  • pytest -s 運行當前目錄下的 所有測驗用例

    • -s 作用 就是 如果測驗用例通過, 測驗函式中的print輸出列印內容
  • pytest test_xx.py 執行 test_xx.py檔案 中 所有測驗用例

  • pytest test_xx.py::類::函式 執行具體的某個測驗用例

  • pytest.main([’-s’]) 腳本執行

    import pytest
    
    if __name__ == '__main__':
        pytest.main(['test_1.py','-s'])
    

Pytest相關函式使用

Pytest-assert+warning

  • 原生斷言

    import requests
    
    
    def test_assert():
        age = 20
    
        # 判斷 年齡是不是大于18歲
    
        assert age >= 18, '未成年!'
    
    
    def test_jingdong():
        response = requests.get('http://www.jd.com')
    
        print(response.content.decode())
    
        assert response.status_code == 202, '沒成功'
    

- 例外測驗

  # ====================測驗案例:判斷平年閏年================
  def is_leap_year(year):
  
      # 先判斷year是不是整型
      if isinstance(year, int) is not True:
          raise TypeError("傳入的引數不是整數")
  	# year 不能為0 的取值例外
      elif year == 0:
          raise ValueError("公元元年是從公元一年開始!!")
  	# year 必須為正整數的  型別例外
      elif abs(year) != year:
          raise ValueError("傳入的引數不是正整數")
  	# year的平潤年判斷
      # 以下代碼  和 例外型別 無關
      elif (year % 4 ==0 and year % 100 != 0) or year % 400 == 0:
          print("%d年是閏年" % year)
          return True
      else:
          print("%d年不是閏年" % year)
          return False
  # 一定要注意的是:站在測驗的角度去寫代碼   
  # 我們測驗報錯是否在業務邏輯中實作  而不是要看到測驗的報錯資訊  如果測驗OK不會有報錯的
  
  # =================raise()方法的使用================
  class TestException():
  
      def test_ValueError1(self):
          with pytest.raises(ValueError):
              utils.is_leap_year(-5)
  
      def test_TypeError(self):
          with pytest.raises(TypeError) as info:
              utils.is_leap_year(6.6)
          # 這里也可以搭配 assert方法提示報錯資訊
          assert info.type == TypeError
  
      def test_ValueError2(self):
          # match對應的錯誤資訊 因為數值錯誤有兩個 可能會匹配到其中任意一個
          # 如果 例外型別 相同 對比不出來, 需要借助例外中的提示資訊 二次
          # match的實作底層借用 re.search() 方法  尋找符合條件的字串提示資訊進行具體的錯誤型別匹配
          with pytest.raises(ValueError, match="公元元年"):
              utils.is_leap_year(0)
  
      def test_ValueError3(self):
          with pytest.raises(ValueError, match="正整數"):
              utils.is_leap_year(-9)
  
      def test_leap_year(self):
          assert utils.is_leap_year(2001) == True, "不是閏年"
  

- 警告測驗

  # =================測驗案例:幾個警告的提示函式=============
  class MakeWarns():
      # 1. 棄用警告 函式
      def make_decotat_warns(self):
          warnings.warn('deprecate', DeprecationWarning)
  
      # 2. 用戶警告 函式
      def make_user_warns(self):
          warnings.warn('user', UserWarning)
  
      # 3. 語法警告 函式
      def make_syntax_warns(self):
          warnings.warn('syntax', SyntaxWarning)
  
      # 4. 位元組警告 函式
      def make_bytes_warns(self):
          warnings.warn('bytes', BytesWarning)
  
      # 5. 運行時 runtime警告 函式
      def make_runtime_warns(self):
          warnings.warn('runtime', RuntimeWarning)
  
      # 6. 無警告 函式
      def not_warns(self):
          pass
  	# 7. 很多警告
      def many_warns(self):
          warnings.warn('runtime', RuntimeWarning)
          warnings.warn('user', UserWarning)
  
  # ===================測驗用例============
  import warning
  
  class TestWarnsType():
  
      def test_deprecate(self):
          # 測驗棄用警告
          with pytest.warns(DeprecationWarning):
              MakeWarns().make_decotat_warns()
  
      def test_bytes(self):
          # 測驗位元組警告
          with pytest.warns(BytesWarning):
              MakeWarns().make_bytes_warns()
  
      def test_sync(self):
          # 測驗語法警告
          with pytest.warns(SyntaxWarning, match='syntax'):
              MakeWarns().make_syntax_warns()
  
      def test_many_warning(self):
          # 測驗 很多警告 中Runtime是否生效
          with pytest.warns(RuntimeWarning) as record:
              MakeWarns().many_warns()
                
      def test_as(self):
          """warning的幾個資訊查看用法"""
          with pytest.warns(UserWarning) as warninfo:

            make_warning.warn_message()

          print('\n', warninfo)
          print(len(warninfo))
          print(warninfo[0].message)
          print(warninfo[1].message)

          assert len(warninfo) == 2
          assert str(warninfo[0].message) == "user"
          assert str(warninfo[1].message) == "runtime"

Pytest-setup/teardown

類似于django的Teatcase中的setUp和tearDown函式

一、函式分類及介紹

  • 函式級別
    • setup_function和teardown_function
      • 只針對測驗類 外面的 測驗函式 每個函式執行前后都會執行
    • setup_method和teardown_method
      • 只針對測驗類 里面的 測驗函式 類中每個函式執行前后都會執行
    • setup_class和teardown_class
      • 一個測驗用例類 只呼叫一次
  • 模塊
    • setup_module和teardown_module
      • 一個py測驗檔案只執行一次

二、優先級順序

  • 測驗代碼中不建議同時全部使用
  • 先后順序
    • setup執行先后順序
      • module>class>method 類里面的測驗函式
      • module>function 單獨測驗函式的
    • teardown執行先后順序
      • method>class>module 類里面的測驗函式
      • function>moudle 單獨測驗函式的

三、Demo演示

# =============優先級查看代碼=============

def setup_module():
    print('\n>> setup_module  setup_module ...')


def teardown_module():
    print('\n>> teardown_module  teardown_module ...')


def test_one():
    print('\n>>> test_one 111....')


def test_two():
    print('\n>>> test_two 222....')


class TestSetUpMethod():

    def setup_class(self):
        print('\n>> setup_class ...')

    def teardown_class(self):
        print('\n>> teardown_class ...')

    def setup_method(self):
        print('\n>>> setup_method ...')

    def teardown_method(self):
        print('\n>>> teardown_method ...')

    def test_three(self):
        print('\n>>> test_three 333....')

    def test_four(self):
        print('\n>>> test_four 444....')


class TestSetUpMethodTwo():

    def test_three(self):
        print('\n>>> test_three 555....')

    def test_four(self):
        print('\n>>> test_four 666....')

# =================輸出結果==============
setup_module  setup_module ...

>>> test_one 111....
.
>>> test_two 222....
.
>> setup_class ...

>>> setup_method ...

>>> test_three 333....
.
>>> teardown_method ...

>>> setup_method ...

>>> test_four 444....
.
>>> teardown_method ...

>> teardown_class ...

>>> test_three 555....
.
>>> test_four 666....
.
>> teardown_module  teardown_module ...

Pytest-fixture

一 、fixture是什么

  • fixture是pytest特有的功能,它用pytest.fixture標識,以裝飾器形式定義在函式上面,在撰寫測驗函式的時候,可以將此函式名稱做為傳入引數,pytest將會以依賴注入方式,將該函式的回傳值作為測驗函式的傳入引數.

二、 場景舉例

  • 如果測驗類中 5個測驗用例 , 其中 有 3個測驗用例需要登錄, 2個不需要
    • setup_method 可以實作 但是不夠靈活
    • 直接使用fixture就可以實作哪個需要給哪個

三、 使用

@pytest.fixture()
def user_login():
    # 實作用戶登錄
    print('用戶登錄成功')

# 測驗用例:有些要求用戶必須登錄,有些要求可以不登錄訪問
def test_user_orders(user_login):
    print('>>>test_user_orders run >>>')

def test_payment_status(user_login):
    print('>>>test_payment_status run >>>')

# 專案首頁,任何人都可以訪問
def test_index():
    print('>>>test_index run >>>')
# ============不同級別情況下使用fixture的執行次數==========

# function級別共執行3次
# class級別共執行2次
# module級別共執行1次
# session級別共執行1次

# 定義fixture
@pytest.fixture(scope='function')
def user_login():
    # 實作用戶登錄
    print('用戶登錄成功')
# 在類外面使用fixture,在類外面依然可以使用
def test_1(user_login):
    print('>>>test_1 run>>>')

# 在類外面使用fixture,在類里面依然可以使用
class TestLogin(object):
    # 測驗用例:有些要求用戶必須登錄,有些要求可以不登錄訪問
    def test_user_orders(self, user_login):
        print('>>>test_user_orders run >>>')

    def test_payment_status(self, user_login):
        print('>>>test_payment_status run >>>')

四、fixture函式共享

  • 作用
    • 給所有的測驗用例添加可以直接呼叫的功能
  • 實作方式
    • 在測驗檔案目錄下新建 conftest.py 檔案 (檔案名不能修改!!!)
    • 在這個檔案中定義 通用的 可能需要被測驗類呼叫的函式 pytest執行測驗時會自動呼叫
  • demo舉例
# ==========================檔案名:conftest.py======================
import pytest

"""
function:對所有的測驗函式生效,不同的測驗檔案中執行多次;
class:對所有的測驗類和測驗函式生效,不同的測驗檔案中執行多次
module:對所有的測驗類和測驗函式生效,一個測驗檔案,只執行一次

session:對所有的測驗類和測驗函式生效,多個測驗檔案,只執行一次

"""


# 添加功能: 登錄成功輸出資訊
@pytest.fixture(scope='function')
# @pytest.fixture(scope='class')
# @pytest.fixture(scope='module')
# @pytest.fixture(scope='session')
def user_login():
    print('\n用戶登錄成功\n')

# ========================檔案名:fixture_test.py===============
import pytest


# 使用共享檔案中的fixture裝飾的的user_login的功能函式
def test_1(user_login):
    print('\n>>> test_1 run >>>\n')


def test_2():
    print('\n>>> test_2 run >>>\n')


# fixture標記函式共享檔案的使用
@pytest.mark.usefixtures('user_login')
class TestOrders(object):
    """
    fixture標記函式共享檔案的使用:
    1.可以直接傳給測驗類中的指定測驗函式,只對測驗函式生效
    2.也可以直接把測驗類使用fixture進行標記,對該類中的所有測驗函式都生效
    """

    def test_get_orders(self):
        print('\n>>> test_get_orders run >>>\n')

    def test_get_goods(self):
        print('\n>>> test_get_goods run >>>\n')


五、fixture的引數化

  • 三個引數說明

    • scope 作用域:即 function、class、module、session 這四個級別
      • function:即測驗 類外的測驗函式、類中的測驗用例函式 運行多次
      • class:即作用測驗用例類 一個類一次
      • Module:作用整個py模塊 一個模塊一次
      • Sessioon:作用整個一次的測驗包含所有的測驗用例 pytest一次
    • param:List型別,默認None, 接收引數值,對于param里面的每個值,fixture都會去遍歷執行一次.
    • autouse:Bool型別,默認Ture 為true時此session中的所有測驗函式都會呼叫fixture
  • demo

    import pytest
    from _pytest.fixtures import SubRequest
    
    # 1.多個引數串列
    user_list = ['dlireba', 'oyangnanan']
    pwd_list = ['111111', '222222']
    
    
    # 2.多個fixture
    # params引數的用法
    @pytest.fixture(params=user_list)
    def user_name(request):
        return request.param
    
    
    @pytest.fixture(params=pwd_list)
    def pwd_content(request):
        return request.param
    
    # scope引數的用法
    # @pytest.fixture(scope='function')
    @pytest.fixture(scope='class')
    # @pytest.fixture(scope='module')
    # @pytest.fixture(scope='session')
    def pwd_content(request):
        return 'scope測驗'
    
    
    # 3.給測驗函式 多個fixture
    class TestOrders(object):
    
        # 呼叫  fixture裝飾的函式   會自動遍歷匹配   一共會生成4個測驗用例
        def test_get_orders(self, user_name, pwd_content):
            print('\n從fixture傳過來的name資料', user_name)
            print('從fixture傳過來的pwd資料', pwd_content)
            print('>>> test_fixture2 run >>>\n')
    
    # ===   autouse引數  一般情況下不用,影響測驗靈活性======
    # True  一旦執行pytest后的所有的測驗用例將會自動被傳遞hell()函式
    # False  默認關閉此功能
    @pytest.fixture(autouse=True)
    def hello():
        print('\nhello world 2020\n')
    
    

Pytest-mark

一、作用以及常用的5個標記函式

  • 作用

    標記測驗用例,以滿足在某些特定場景下測驗用例的特殊要求實作的功能

  • 6個標記函式

    • pytest.mark.usefixtures 給測驗用例 添加fixture
    • pytest.mark.xfail 標識測驗用例預期失敗
    • pytest.mark.skip 沒有限制條件情況下跳過測驗用例
    • pytest.mark.skipif 有限制條件情況下跳過測驗用例
    • pytest.fixture(params=[]) 直接給fixture函式傳遞引數
    • pytest.mark.parametrize() 直接給測驗用例函式傳遞引數

二、6個標記函式的使用

import pytest


# fixture標記函式共享檔案的使用
@pytest.mark.usefixtures('user_login')
class TestMark():

    def test_one(self):
        print('\n test_one .....')
        assert 1

    """
        pytest.mark.xfail() 
        如果不寫引數  默認預期失敗
        如果有引數   condition reason 必須都寫
    """

    @pytest.mark.xfail(condition=False, reason="測驗 登錄失敗! ")
    def test_two(self):
        print('\n test_two .....')
        assert 0, '測驗失敗了!'

    """
        無條件 跳過
    """

    @pytest.mark.skip()
    def test_three(self):
        print('\n test_three .....')
        assert 1

    """
        有條件 跳過
        pytest.mark.skipif() 
        如果 不寫引數 --默認就跳過
        寫了引數   必須兩個一起寫 condintion  reason
    """

    @pytest.mark.skipif(condition=True, reason='跳過的原因')
    def test_four(self):
        print('\n test_four .....')
        assert 1

    username = "user,pwd"
    values = [('reba', '12345678'), ('oyangnanan', '99999999')]
    """
        key   -argnames     引數型別-string  -- "k1,k2,k3"
        value -argvalues    引數型別-list    -- [v1,v2,v3]
    """

    @pytest.mark.parametrize(username, values)
    def test_five(self, user, pwd):
        print('\n test_five .....')
        print('\n 測驗函式接收外界的引數:', user)
        print('\n 測驗函式接收外界的引數:', pwd)
        print('\n parametrize測驗用例 .....')
        assert 1

    """
        之前的fixture引數傳遞
    """

    @pytest.fixture(params='fixture_param_test')
    def test_six(self, request):
        print('\n test_six .....')
        return request.param

    # 傳遞后使用
    def test_seven(self, test_six):
        print('\n test_seven .....')
        print('\nfixture的param測驗:', test_six)
        assert 1

Pytest的插件

三個常用插件: pytest-html pytest-orderingrun pytest-rerunfailures

安裝:

pip install pytest-html -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pytest-ordering -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pytest-rerunfailures -i https://pypi.tuna.tsinghua.edu.cn/simple

Pytest-html-生成測驗報告

兩種使用方式

  • 終端命令列:pytest 測驗檔案.py --html=存盤路徑/report.html
  • 組態檔中修改:appopts= -s --html=./report.html

Pytest-orderingrun-控制函式執行順序

import pytest
  
# 通過插件,指定測驗函式執行的順序
"""
  正整數:值越小,先執行
  負數:值越小,先執行
  正負數:優先執行正數,最后執行負數,值越小,先執行
  0:優先執行0,然后正數、負數
"""
  
class TestOrdering(object):
    # 默認從上往下執行  !!直接使用標記函式的方式進行呼叫!!
    @pytest.mark.run(order=1)
    def test_login(self):
        print('\n>>>登錄執行>>>\n')
  
    @pytest.mark.run(order=0)
    def test_register(self):
        print('\n>>>注冊執行>>>\n')
  
    @pytest.mark.run(order=2)
    def test_user_info(self):
        print('\n>>>獲取用戶資訊執行>>>\n')

Pytest-rerunfailures-重測驗失敗的用例

**作用 **

  • 就只在某種情況下(網路阻塞、軟體卡頓),測驗用例測驗程序例外測驗失敗,進行自動重新測驗

兩種使用方式

  • 終端命令列:pytest 測驗檔案.py --reruns 重試次數
  • 組態檔中修改:appopts= -s --reruns 重試次數

Yaml

Yaml是什么

一、介紹

? 一種支持所有編程語言的序列化標準,用來存盤資料,類似于json

二、語法規則

  • 大小寫敏感
  • 縮進表示層級關系, 不建議使用tab鍵 縮進空格數量不重要,重要的是同層級對齊即可

三、種資料型別

  • object(物件):

    鍵值對的集合,又稱為映射/hash/字典 —> python中dict

    dilireba: 18
    	oyangnana: kavayi
    		wangyibo: cool
    
  • array(陣列):

    一組按照次序排列的值,又稱序列(sequence)、串列 —> python中list

    dilireba: [18, 18, 18]
    nazha:
    	- 18
    	- 18
    	- 18
    
  • scalars(純量):

    單個的、不可再分的值, 包括 字串、布林值、整數、浮點數、null、日期 —>python中的不可拆分的資料型別

    animal: pets # !!!!!注意冒號后面必須要有一個空格!!!
    	dog: beibei
    # 字串
    value: "hello"
    轉換為python代碼
    {"value":"hello"}
    
    # 布林值
    value1: true
    value2: false
    轉換為python代碼
    {'value1': True, 'value2': False}
    
    # 整數,浮點數
    value1: 12
    value2: 12.102
    # 轉換為python代碼
    {'value1': 12, 'value2': 12.102}
    
    # 空(Null)
    value1: ~ # ~ 表示為空
    轉換為python代碼
    {'value1': None}
    
    # 日期
    value1: 2017-10-11 15:12:12
    轉換為python代碼
    {'languages': {'value1': datetime.datetime(2017, 10, 11, 15, 12, 12)}}
    
  • 錨點的使用

    錨點類似于一個變數,只不過其中只存盤著value供別人呼叫

    data: &ok   # & 是錨點標示符號
        value: 456
    name:
        value1: 123
        <<: *ok # "<<:" 合并到當前位置,"*imp" 參考錨點imp
    
    # 轉換為python代碼  注意字典是無序的  
    # 錨點本身字典也會被pyYAML轉換(下節)
        {'data': {'value': 456}, 'name': {'value': 456, 'value1': 123}}
    

PyYAML決議

一、作用

  • 一個python庫用于對yaml檔案進行決議,決議為字典格式的資料
  • yaml->json->dict

二、安裝

  • pip3 install PyYAML

三、實操

# ========================yaml格式檔案===================


data_one: zhangsan
data_dict: {'user':'A', 'pwd':'123456'}

data_list:
  - a
  - b
  - c

data_list_two: [1,2,3,4]

# 純量  單個變數
str_one: "abcdefg"
bool_data: true
int_data: 100
float_data: 1.2
# 轉換后 呈現格式都是 None
null_data: ~ # ~
null_one: null
null_two: None

datetime_data: 2020-10-13 16:14:24
date_two: 2020-10-13
# 這種時間格式不支持  會轉換成秒數輸出
time_data: 16:14:28
# ===========================測驗代碼=======================
import yaml
from pprint import pprint


def test_parse_yaml_file1():
    f = open('test.yaml', 'r')
    # data = f.read()

    # 1.讀取決議 yaml檔案的資料 Loader默認為空  但是不賦值會有警告
    data = yaml.load(f, Loader=yaml.FullLoader)
    # 字典 格式
    print(type(data))

    # 2.將資料  寫入yaml檔案
    f_write = open('test.yaml', 'a')
    # 新建一個字典資料
    data_dict = {'username': '吳亦凡'}
    # 轉換格式寫入
    yaml.dump(data_dict, f_write, allow_unicode=True)


def test_parse_yaml_file2():
    # 打開
    f = open('test.yaml', 'r')
    # 轉換為字典
    data = yaml.load(f, Loader=yaml.FullLoader)
    # 優化列印出來的資料效果 pprint
    pprint(data)

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/173321.html

標籤:java

上一篇:李宏毅深度學習人類語言處理dhlp2020 hw1-hw5作業下載、環境配置及訓練筆記

下一篇:OpenAI 發布模型實作自動定理證明,媽媽再也不用擔心我的數學?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more