關於pytest的一些問題


一. 測試模塊內部使用fixture和測試模塊調用外部公共的fixture

1. unittest框架下的測試用例模塊

from selenium import webdriver
import unittest
from PageObjects.login_page import LoginPage
from PageObjects.index_page import IndexPage
from TestDatas.login_testdatas import *
from TestDatas.CommonData import *
import time


class TestLogin(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.get(common_url)
        self.driver.maximize_window()

    #用戶名密碼正確
    def test_login_success(self):
        LoginPage(self.driver).login(login_success_data["username"], login_success_data["passwd"])
        nickName = IndexPage(self.driver).get_nickName()
        self.assertEqual("我的帳戶[小蜜蜂96027]", nickName)

    def tearDown(self):
        time.sleep(2)
        self.driver.quit()

2. 測試用例模塊內部使用fixture

fixture:即測試用例執行的環境准備和清理,在unittest中即指setup()、teardown()

from selenium import webdriver
import unittest
from PageObjects.login_page import LoginPage
from PageObjects.index_page import IndexPage
from TestDatas.login_testdatas import *
from TestDatas.CommonData import *
import time
import pytest


class TestLogin:

    @pytest.fixture
    def init_driver(self):
        self.driver = webdriver.Chrome()
        self.driver.get(common_url)
        self.driver.maximize_window()
        yield self.driver
        time.sleep(2)
        self.driver.quit()


    #用戶名密碼正確
    def test_login_success(self, init_driver):
        LoginPage(init_driver).login(login_success_data["username"], login_success_data["passwd"])
        nickName = IndexPage(init_driver).get_nickName()
        assert "我的帳戶[小蜜蜂96027]" == nickName

3. 測試用例模塊調用外部公共的fixture

有時,多個測試用例模塊要使用同一fixture,如果在每個模塊內部都定義一遍fixture則略顯麻煩,pytest提供了conftest.py文件,用來定義公共的fixture,多個測試模塊都可以調用,運行測試用例時,不需要導入這個文件,它會自動查找conftest.py文件,然后去找到對應的fixture

在測試用例模塊的同級目錄下創建一個conftest.py文件

from selenium import webdriver
from TestDatas.CommonData import *
import pytest
import time

@pytest.fixture
def init_driver():
    driver = webdriver.Chrome()
    driver.get(common_url)
    driver.maximize_window()
    yield driver
    time.sleep(2)
    driver.quit()

測試用例模塊test_login.py調用外部公共的fixture

from selenium import webdriver
import unittest
from PageObjects.login_page import LoginPage
from PageObjects.index_page import IndexPage
from TestDatas.login_testdatas import *
from TestDatas.CommonData import *
import time
import pytest


class TestLogin: #用戶名密碼正確
    @pytest.mark.usefixtures("init_driver") def test_login_success(self, init_driver):
        LoginPage(init_driver).login(login_success_data["username"], login_success_data["passwd"])
        nickName = IndexPage(init_driver).get_nickName()
        assert "我的帳戶[小蜜蜂96027]" == nickName

4. 比較

pytest和unittest相比:

1. 需要import pytest

2. 不再需要unittest.TestCase

3. 如果在內部使用fixture,則函數只需要傳參,參數為被@pytest.fixture裝飾的函數名init_driver(init_driver=init_driver());如果調用外部公共的fixture,除了傳參之外,還要在測試用例類或函數前面加上一句:@pytest.mark.usefixtures("init_driver")

4. fixture函數中以yield分割環境准備和環境清理,且需要返回self.driver或driver

5. 斷言方式有所改變,unittest采用self.assertEqual或其他,pytest采用assert 表達式

二. 裝飾器函數fixture的作用域默認是function,且autouse=False

@pytest.fixture中的fixture函數源碼如下

四大作用域:

function:每個test都運行,默認是function的scope,即unittest中的setUp和tearDown

class:每個class的所有test只運行一次。即unittest中的setUpClass和tearDownClass

module:每個module的所有test只運行一次(分類里和類外)

session:每個session只運行一次(如連接數據庫操作)

值得注意的是默認的autouse=False,所以函數需要使用對應的fixture時,需要添加@pytest.mark.usefixtures("init_driver"),並且將被fixture裝飾的函數名init_driver作為參數,傳給測試用例函數,如果autouse=True,那么會自動給每個測試用例添加fixture,而init_driver這樣的環境准備和清理工作並非每個測試用例都需要,所以autouse一般采用默認值False

三. pytest收集測試用例的規則

1. 默認從當前目錄中搜集測試用例,即在哪個目錄下運行pytest命令,則從哪個目錄當中搜索

2. 搜索規則:

  1) 符合命令規則test_*.py 或者 *_test.py 的文件

  2) 以test_開頭的函數名

  3) 以Test開頭的測試類 (沒有__init__函數) 當中,以test_開頭的函數

當前目錄下(D:\python_workshop\WEB_framework)有兩個測試用例模塊,test_login.py和test_invest.py,前者測試用例類TestLogin中有四個測試用例,另外還在測試用例類外添加了一個test_demo函數,后者有四個測試用例,這九個測試用例中我只在用戶名為空的用例上打了smoke標記

在調用pytest -m smoke運行時,發現9條用例被找到了,但8條沒有被選擇,只選擇了打了標記的

 

 

 

 

參考文章

http://www.cnblogs.com/cnhkzyy/p/9270830.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM