บทช่วยสอน PyTest: คืออะไร, วิธีการติดตั้ง, กรอบงาน, การยืนยัน

PyTest คืออะไร?

ไพเทส เป็นเฟรมเวิร์กการทดสอบที่ให้ผู้ใช้สามารถเขียนโค้ดทดสอบโดยใช้ Python ภาษาการเขียนโปรแกรม ช่วยให้คุณเขียนกรณีทดสอบที่เรียบง่ายและปรับขนาดได้สำหรับฐานข้อมูล API หรือ UI PyTest ใช้สำหรับเขียนการทดสอบสำหรับ API เป็นหลัก ช่วยในการเขียนการทดสอบตั้งแต่การทดสอบยูนิตแบบง่ายไปจนถึงการทดสอบฟังก์ชันที่ซับซ้อน

เหตุใดจึงต้องใช้ PyTest

ข้อดีบางประการของ pytest คือ

  • ง่ายมากที่จะเริ่มต้นด้วยเนื่องจากมีไวยากรณ์ที่ง่ายและสะดวก
  • สามารถรันการทดสอบแบบขนานได้
  • สามารถรันการทดสอบเฉพาะหรือชุดย่อยของการทดสอบได้
  • ตรวจจับการทดสอบโดยอัตโนมัติ
  • ข้ามการทดสอบ
  • โอเพ่นซอร์ส

วิธีการติดตั้ง PyTest.msc

ต่อไปนี้เป็นกระบวนการเกี่ยวกับการติดตั้ง PyTest:

ขั้นตอน 1) คุณสามารถติดตั้ง pytest ได้โดย

pip install pytest==2.9.1

เมื่อการติดตั้งเสร็จสมบูรณ์คุณสามารถยืนยันได้โดย

py.test -h

นี่จะแสดงความช่วยเหลือ

ติดตั้ง PyTest

PyTest พื้นฐานครั้งแรก

ตอนนี้เราจะเรียนรู้วิธีใช้ Pytest กับตัวอย่าง PyTest พื้นฐาน

สร้างโฟลเดอร์ study_pytest เราจะสร้างไฟล์ทดสอบของเราภายในโฟลเดอร์นี้

โปรดนำทางไปยังโฟลเดอร์นั้นในบรรทัดคำสั่งของคุณ

สร้างไฟล์ชื่อ test_sample1.py ภายในโฟลเดอร์

PyTest พื้นฐานครั้งแรก

เพิ่มโค้ดด้านล่างลงไปแล้วบันทึก

import pytest
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed"
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed" 

รันการทดสอบโดยใช้คำสั่ง

py.test

คุณจะได้ผลลัพธ์เป็น

test_sample1.py F.
============================================== FAILURES ========================================
____________________________________________ test_sample1 ______________________________________
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed"
E       AssertionError: test failed
E       assert 5 == 6
test_sample1.py:6: AssertionError

PyTest พื้นฐานครั้งแรก

ที่นี่ใน test_sample1.py F.

F บอกว่าล้มเหลว

Dot(.) บอกว่าประสบความสำเร็จ

ในส่วนความล้มเหลว คุณสามารถดูวิธีการที่ล้มเหลวและบรรทัดของความล้มเหลว ในที่นี้ x==y หมายถึง 5==6 ซึ่งเป็นเท็จ

ต่อไปในบทช่วยสอน PyTest นี้ เราจะเรียนรู้เกี่ยวกับการยืนยันใน PyTest

การยืนยันใน PyTest

การยืนยัน Pytest คือการตรวจสอบที่ส่งคืนสถานะ True หรือ False ใน Python Pytest หากการยืนยันล้มเหลวในวิธีทดสอบ การดำเนินการของวิธีนั้นจะหยุดอยู่ที่นั่น โค้ดที่เหลือในวิธีทดสอบนั้นจะไม่ถูกดำเนินการ และการยืนยันของ Pytest จะดำเนินต่อไปในวิธีทดสอบถัดไป

ตัวอย่าง Pytest Assert:

assert "hello" == "Hai" is an assertion failure.
assert 4==4 is a successful assertion
assert True is a successful assertion
assert False is an assertion failure.

พิจารณา

assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

วางโค้ดนี้ใน test_file1_method1() แทนการยืนยัน

assert x == y,"test failed"

การรันการทดสอบจะทำให้เกิดความล้มเหลวดังเช่น AssertionError: การทดสอบล้มเหลว x=5 y=6

PyTest ระบุไฟล์ทดสอบและวิธีการทดสอบอย่างไร

โดยค่าเริ่มต้น pytest จะระบุเฉพาะชื่อไฟล์ที่ขึ้นต้นด้วย ทดสอบ_ หรือลงท้ายด้วย _ทดสอบ เป็นไฟล์ทดสอบ อย่างไรก็ตาม เราสามารถระบุชื่อไฟล์อื่นได้อย่างชัดเจน (อธิบายในภายหลัง) Pytest กำหนดให้ชื่อเมธอดการทดสอบเริ่มต้นด้วย "ทดสอบ- ชื่อวิธีการอื่นๆ ทั้งหมดจะถูกละเว้น แม้ว่าเราจะขอให้เรียกใช้วิธีการเหล่านั้นอย่างชัดเจนก็ตาม

ดูตัวอย่างชื่อไฟล์ pytest ที่ถูกต้องและไม่ถูกต้อง

test_login.py - valid
login_test.py - valid
testlogin.py -invalid
logintest.py -invalid

หมายเหตุ: ใช่ เราสามารถขอให้ pytest เลือก testlogin.py และ logintest.py ได้อย่างชัดเจน

ดูตัวอย่างวิธีทดสอบ pytest ที่ถูกต้องและไม่ถูกต้อง

def test_file1_method1(): - valid
def testfile1_method1(): - valid
def file1_method1(): - invalid	

หมายเหตุ: แม้ว่าเราจะกล่าวถึง file1_method1() อย่างชัดเจนแล้ว pytest จะไม่เรียกใช้เมธอดนี้

เรียกใช้การทดสอบหลายรายการจากไฟล์เฉพาะและหลายไฟล์

ปัจจุบัน ภายในโฟลเดอร์ study_pytest เรามีไฟล์ test_sample1.py สมมติว่าเรามีไฟล์หลายไฟล์ เช่น test_sample2.py , test_sample3.py หากต้องการรันการทดสอบทั้งหมดจากไฟล์ทั้งหมดในโฟลเดอร์และโฟลเดอร์ย่อย เราจำเป็นต้องรันคำสั่ง pytest

py.test

สิ่งนี้จะเรียกใช้ชื่อไฟล์ทั้งหมดที่ขึ้นต้นด้วย test_ และชื่อไฟล์ที่ลงท้ายด้วย _test ในโฟลเดอร์นั้นและโฟลเดอร์ย่อยภายใต้โฟลเดอร์นั้น

หากต้องการรันการทดสอบจากไฟล์ใดไฟล์หนึ่งเท่านั้น เราสามารถใช้ py.test

py.test test_sample1.py

รันเซ็ตย่อยของการทดสอบทั้งหมดด้วย PyTest

บางครั้งเราไม่ต้องการรันชุดทดสอบทั้งหมด Pytest ช่วยให้เราทำการทดสอบเฉพาะได้ เราสามารถทำได้ 2 วิธี

  • การจัดกลุ่มชื่อการทดสอบตามการจับคู่สตริงย่อย
  • การจัดกลุ่มการทดสอบตามเครื่องหมาย

เรามี test_sample1.py อยู่แล้ว สร้างไฟล์ test_sample2.py และเพิ่มโค้ดด้านล่างเข้าไป

def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

ดังนั้นเราจึงมีในปัจจุบัน

• test_sample1.py
• test_file1_method1()
• test_file1_method2()
• test_sample2.py
• test_file2_method1()
• test_file2_method2()

ตัวเลือก 1) ทำการทดสอบโดยการจับคู่สตริงย่อย

ที่นี่เพื่อรันการทดสอบทั้งหมดที่มี method1 อยู่ในชื่อ เราจะต้องดำเนินการ

py.test -k method1 -v
-k <expression> is used to represent the substring to match
-v increases the verbosity

การรัน py.test -k method1 -v จะให้ผลลัพธ์ดังต่อไปนี้

test_sample2.py::test_file2_method1 FAILED
test_sample1.py::test_file1_method1 FAILED

============================================== FAILURES ==============================================
_________________________________________ test_file2_method1 _________________________________________
    def test_file2_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample2.py:5: AssertionError

_________________________________________ test_file1_method1 _________________________________________
    @pytest.mark.only
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample1.py:8: AssertionError

================================= 2 tests deselected by '-kmethod1' ==================================
=============================== 2 failed, 2 deselected in 0.02 seconds ===============================

ที่นี่คุณสามารถเห็นได้ในตอนท้าย ยกเลิกการเลือกการทดสอบ 2 รายการโดย '-kmethod1' คือ test_file1_method2 และ test_file2_method2

ลองใช้ชุดค่าผสมต่างๆ เช่น:-

py.test -k method -v - will run all the four methods
py.test -k methods -v – will not run any test as there is no test name matches the substring 'methods'

ตัวเลือกที่ 2) ทำการทดสอบโดยใช้เครื่องหมาย

Pytest ช่วยให้เราสามารถตั้งค่าคุณสมบัติต่างๆ สำหรับวิธีทดสอบโดยใช้เครื่องหมาย pytest @pytest.mark หากต้องการใช้เครื่องหมายในไฟล์ทดสอบ เราจำเป็นต้องนำเข้า pytest ในไฟล์ทดสอบ

ที่นี่เราจะใช้ชื่อเครื่องหมายที่แตกต่างกันเพื่อทดสอบวิธีและดำเนินการทดสอบเฉพาะตามชื่อเครื่องหมาย เราสามารถกำหนดเครื่องหมายบนชื่อการทดสอบแต่ละรายการได้โดยใช้

@pytest.mark.<name>.			

เรากำลังกำหนดมาร์กเกอร์ set1 และ set2 บนเมธอดการทดสอบ และเราจะรันการทดสอบโดยใช้ชื่อมาร์กเกอร์ อัปเดตไฟล์การทดสอบด้วยโค้ดต่อไปนี้

test_sample1.py

import pytest
@pytest.mark.set1
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set2
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

test_sample2.py

import pytest
@pytest.mark.set1
def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set1
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

เราสามารถทำการทดสอบที่ทำเครื่องหมายไว้ได้โดย

py.test -m <name>
-m <name> mentions the marker name

เรียกใช้ py.test -m set1 ซึ่งจะเรียกใช้เมธอด test_file1_method1, test_file2_method1, test_file2_method2

การรัน py.test -m set2 จะรัน test_file1_method2

ทำการทดสอบแบบขนานกับ Pytest

โดยปกติ ชุดทดสอบจะมีไฟล์ทดสอบหลายไฟล์และวิธีการทดสอบหลายร้อยวิธีซึ่งจะใช้เวลานานในการดำเนินการ Pytest ช่วยให้เราทำการทดสอบแบบขนานได้

เพื่อที่เราจะต้องติดตั้ง pytest-xdist ก่อนโดยการรัน

pip install pytest-xdist

ทำการทดสอบแบบขนานกับ Pytest

คุณสามารถทำการทดสอบได้ทันทีโดย

py.test -n 4

-n ดำเนินการทดสอบโดยใช้ผู้ปฏิบัติงานหลายคน ในคำสั่งข้างต้น จะมีคนงาน 4 คนทำการทดสอบ

โปรแกรมการแข่งขัน ไพเทสต์

Fixtures ถูกใช้เมื่อเราต้องการรันโค้ดก่อนทุกวิธีการทดสอบ ดังนั้นแทนที่จะใช้รหัสเดิมซ้ำในทุกการทดสอบ เราจึงกำหนดโปรแกรมการแข่งขัน โดยปกติแล้ว ฟิกซ์เจอร์จะใช้เพื่อเริ่มต้นการเชื่อมต่อฐานข้อมูล ส่งผ่านฐาน ฯลฯ

วิธีการถูกทำเครื่องหมายว่าเป็นฟิกซ์เจอร์ของ Pytest โดยการทำเครื่องหมายด้วย

@pytest.fixture

วิธีทดสอบสามารถใช้ฟิกซ์เจอร์ของ Pytest ได้โดยการกล่าวถึงฟิกซ์เจอร์เป็นพารามิเตอร์อินพุต

สร้างไฟล์ใหม่ test_basic_fixture.py พร้อมด้วยโค้ดดังต่อไปนี้

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

Here

  • เรามีฟิกซ์เจอร์ชื่อ supply_AA_BB_CC วิธีนี้จะส่งคืนรายการ 3 ค่า
  • เรามีวิธีทดสอบ 3 วิธีเปรียบเทียบกับแต่ละค่า

แต่ละฟังก์ชันการทดสอบมีอาร์กิวเมนต์อินพุตซึ่งมีชื่อตรงกับฟิกซ์เจอร์ที่มีอยู่ จากนั้น Pytest จะเรียกใช้วิธีการฟิกซ์เจอร์ที่สอดคล้องกัน และค่าที่ส่งคืนจะถูกเก็บไว้ในอาร์กิวเมนต์อินพุต นี่คือรายการ [25,35,45] ขณะนี้มีการใช้รายการในวิธีทดสอบสำหรับการเปรียบเทียบ

ตอนนี้ทำการทดสอบและดูผลลัพธ์

 py.test test_basic_fixture
test_basic_fixture.py::test_comparewithAA FAILED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithBB PASSED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithCC FAILED
                                                                                                                                                                                       
============================================== FAILURES ==============================================
_________________________________________ test_comparewithAA _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithAA(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"
E    AssertionError: aa and zz comparison failed
E    assert 25 == 35
test_basic_fixture.py:10: AssertionError

_________________________________________ test_comparewithCC _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithCC(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
E    AssertionError: cc and zz comparison failed
E    assert 45 == 35
test_basic_fixture.py:16: AssertionError
================================= 2 failed, 1 passed in 0.05 seconds =================================

test_comparewithBB ผ่านการทดสอบตั้งแต่ zz=BB=35 และการทดสอบ 2 รายการที่เหลือล้มเหลว

วิธีการฟิกซ์เจอร์มีขอบเขตภายในไฟล์ทดสอบที่กำหนดไว้เท่านั้น หากเราพยายามเข้าถึงฟิกซ์เจอร์ในไฟล์ทดสอบอื่น เราจะได้รับข้อผิดพลาดแจ้งว่าฟิกซ์เจอร์ ไม่พบ 'supply_AA_BB_CC' สำหรับวิธีทดสอบในไฟล์อื่นๆ

หากต้องการใช้ฟิกซ์เจอร์เดียวกันกับไฟล์ทดสอบหลายไฟล์ เราจะสร้างวิธีการฟิกซ์เจอร์ในไฟล์ชื่อ conftest.py

มาดูตัวอย่าง PyTest ด้านล่างนี้กัน สร้างไฟล์ conftest.py, test_basic_fixture.py, test_basic_fixture3.py จำนวน 2 ไฟล์ด้วยโค้ดต่อไปนี้

conftest.py

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

test_basic_fixture.py

import pytest
def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

test_basic_fixture2.py

import pytest
def test_comparewithAA_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

pytest จะค้นหาฟิกซ์เจอร์ในไฟล์ทดสอบก่อน และหากไม่พบก็จะค้นหาใน conftest.py

รันการทดสอบโดย py.test -k test_comparewith -v เพื่อให้ได้ผลลัพธ์ดังนี้

test_basic_fixture.py::test_comparewithAA FAILED  
test_basic_fixture.py::test_comparewithBB PASSED 
test_basic_fixture.py::test_comparewithCC FAILED 
test_basic_fixture2.py::test_comparewithAA_file2 PASSED 
test_basic_fixture2.py::test_comparewithBB_file2 FAILED 
test_basic_fixture2.py::test_comparewithCC_file2 FAILED

การทดสอบแบบกำหนดพารามิเตอร์ของไพเทสต์

วัตถุประสงค์ของการกำหนดพารามิเตอร์การทดสอบคือทำการทดสอบกับชุดอาร์กิวเมนต์หลายชุด เราสามารถทำได้โดย @pytest.mark.parametrize

เราจะเห็นสิ่งนี้ด้วยตัวอย่าง PyTest ด้านล่าง ที่นี่เราจะส่งอาร์กิวเมนต์ 3 ข้อไปยังวิธีทดสอบ วิธีทดสอบนี้จะเพิ่มอาร์กิวเมนต์ 2 ข้อแรกและเปรียบเทียบกับอาร์กิวเมนต์ที่ 3

สร้างไฟล์ทดสอบ test_addition.py ด้วยโค้ดด้านล่าง

import pytest
@pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
def test_add(input1, input2, output):
	assert input1+input2 == output,"failed"

วิธีทดสอบนี้รับอาร์กิวเมนต์ 3 ตัว ได้แก่ input1, input2, output โดยจะเพิ่ม input1 และ input2 เข้าไปแล้วเปรียบเทียบกับเอาต์พุต

มารันการทดสอบด้วย py.test -k test_add -v และดูผลลัพธ์

test_addition.py::test_add[5-5-10] PASSED                                                                                                                                                                                              
test_addition.py::test_add[3-5-12] FAILED                                                                                                                                                                                              
============================================== FAILURES ==============================================
__________________________________________ test_add[3-5-12] __________________________________________
input1 = 3, input2 = 5, output = 12
    @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
    def test_add(input1, input2, output):
>   	assert input1+input2 == output,"failed"
E    AssertionError: failed
E    assert (3 + 5) == 12
test_addition.py:5: AssertionError

คุณสามารถดูการทดสอบได้ 2 ครั้ง – ครั้งแรกตรวจสอบ 5+5 ==10 และการทดสอบอื่นๆ 3+5 ==12

test_addition.py::test_add[5-5-10] ผ่านแล้ว

test_addition.py::test_add[3-5-12] ล้มเหลว

Pytest Xfail / ข้ามการทดสอบ

จะมีบางสถานการณ์ที่เราไม่ต้องการทดสอบหรือก กรณีทดสอบ ไม่เกี่ยวข้องกับช่วงเวลาใดเวลาหนึ่ง ในสถานการณ์เหล่านั้น เรามีตัวเลือกในการ Xfail การทดสอบหรือข้ามการทดสอบ

การทดสอบ xfail จะถูกดำเนินการ แต่จะไม่นับว่าเป็นส่วนหนึ่งของการทดสอบที่ล้มเหลวหรือผ่านการทดสอบ จะไม่มีการแสดงการติดตามย้อนกลับหากการทดสอบนั้นล้มเหลว เราสามารถทดสอบ xfail ได้โดยใช้

@ pytest.mark.xfail.

การข้ามการทดสอบหมายความว่าการทดสอบจะไม่ได้รับการดำเนินการ เราสามารถข้ามการทดสอบโดยใช้

@pytest.mark.ข้าม.

แก้ไข test_addition.py ด้วยโค้ดด้านล่าง

import pytest
@pytest.mark.skip
def test_add_1():
	assert 100+200 == 400,"failed"

@pytest.mark.skip
def test_add_2():
	assert 100+200 == 300,"failed"

@pytest.mark.xfail
def test_add_3():
	assert 15+13 == 28,"failed"

@pytest.mark.xfail
def test_add_4():
	assert 15+13 == 100,"failed"

def test_add_5():
	assert 3+2 == 5,"failed"

def test_add_6():
	assert 3+2 == 6,"failed"

Here

  • test_add_1 และ test_add_2 ถูกข้ามไปและจะไม่ถูกดำเนินการ
  • test_add_3 และ test_add_4 เป็น xfailed การทดสอบเหล่านี้จะดำเนินการและจะเป็นส่วนหนึ่งของการทดสอบ xfailed (เมื่อทดสอบล้มเหลว) หรือ xpassed (เมื่อผ่านการทดสอบ) จะไม่มีการย้อนกลับสำหรับความล้มเหลว
  • test_add_5 และ test_add_6 จะถูกดำเนินการและ test_add_6 จะรายงานความล้มเหลวด้วยการย้อนกลับในขณะที่ test_add_5 ผ่าน

ดำเนินการทดสอบโดย py.test test_addition.py -v และดูผลลัพธ์

test_addition.py::test_add_1 SKIPPED
test_addition.py::test_add_2 SKIPPED
test_addition.py::test_add_3 XPASS
test_addition.py::test_add_4 xfail
test_addition.py::test_add_5 PASSED
test_addition.py::test_add_6 FAILED

============================================== FAILURES ==============================================
_____________________________________________ test_add_6 _____________________________________________
    def test_add_6():
>   	assert 3+2 == 6,"failed"
E    AssertionError: failed
E    assert (3 + 2) == 6
test_addition.py:24: AssertionError

================ 1 failed, 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.07 seconds =================

ผลลัพธ์ XML

เราสามารถสร้างผลการทดสอบในรูปแบบ XML ซึ่งเราสามารถป้อนไปยังเซิร์ฟเวอร์การรวมต่อเนื่องเพื่อการประมวลผลต่อไปได้ ซึ่งสามารถทำได้โดย

py.test test_sample1.py -v –junitxml=”ผลลัพธ์.xml”

result.xml จะบันทึกผลการดำเนินการทดสอบ ค้นหาตัวอย่าง result.xml ด้านล่าง

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="0" failures="1" name="pytest" skips="0" tests="2" time="0.046">
   <testcase classname="test_sample1" file="test_sample1.py" line="3" name="test_file1_method1" time="0.001384973526">
     <failure message="AssertionError:test failed because x=5 y=6 assert 5 ==6">
    @pytest.mark.set1
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
         test_sample1.py:9: AssertionError
    </failure>
   </testcase>
   <testcase classname="test_sample1" file="test_sample1.py" line="10" name="test_file1_method2" time="0.000830173492432" />
</testsuite>

จาก เราจะเห็นการทดสอบทั้งหมด 0 ครั้ง ซึ่งครั้งหนึ่งล้มเหลว ด้านล่างนี้คือรายละเอียดเกี่ยวกับการทดสอบที่ดำเนินการแต่ละรายการ แท็ก

Pytest Framework ทดสอบ API

ตอนนี้เราจะสร้างเฟรมเวิร์ก pytest ขนาดเล็กเพื่อทดสอบ API API ที่ใช้ที่นี่เป็นฟรีจาก https://reqres.in/- เว็บไซต์นี้มีไว้เพื่อให้บริการ API ที่ทดสอบได้เท่านั้น เว็บไซต์นี้ไม่ได้จัดเก็บข้อมูลของเรา

ที่นี่เราจะเขียนการทดสอบบางอย่างสำหรับ

  • รายชื่อผู้ใช้บางส่วน
  • เข้าสู่ระบบด้วยผู้ใช้

สร้างไฟล์ด้านล่างด้วยรหัสที่กำหนด

conftest.py – มีฟิกซ์เจอร์ที่จะจัดหา URL พื้นฐานสำหรับวิธีทดสอบทั้งหมด

import pytest
@pytest.fixture
def supply_url():
	return "https://reqres.in/api"

test_list_user.py – มีวิธีทดสอบสำหรับการแสดงรายการผู้ใช้ที่ถูกต้องและไม่ถูกต้อง

  • test_list_valid_user ทดสอบการดึงข้อมูลผู้ใช้ที่ถูกต้องและตรวจสอบการตอบสนอง
  • test_list_invaliduser ทดสอบการดึงข้อมูลผู้ใช้ที่ไม่ถูกต้องและตรวจสอบการตอบสนอง
import pytest
import requests
import json
@pytest.mark.parametrize("userid, firstname",[(1,"George"),(2,"Janet")])
def test_list_valid_user(supply_url,userid,firstname):
	url = supply_url + "/users/" + str(userid)
	resp = requests.get(url)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['data']['id'] == userid, resp.text
	assert j['data']['first_name'] == firstname, resp.text

def test_list_invaliduser(supply_url):
	url = supply_url + "/users/50"
	resp = requests.get(url)
	assert resp.status_code == 404, resp.text

test_login_user.py – มีวิธีทดสอบสำหรับทดสอบฟังก์ชันการเข้าสู่ระบบ

  • test_login_valid ทดสอบความพยายามเข้าสู่ระบบที่ถูกต้องด้วยอีเมลและรหัสผ่าน
  • test_login_no_password ทดสอบความพยายามเข้าสู่ระบบที่ไม่ถูกต้องโดยไม่ผ่านรหัสผ่าน
  • test_login_no_email ทดสอบความพยายามเข้าสู่ระบบที่ไม่ถูกต้องโดยไม่ส่งอีเมล
import pytest
import requests
import json
def test_login_valid(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com','password':'something'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['token'] == "QpwL5tke4Pnpja7X", resp.text

def test_login_no_password(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing password", resp.text

def test_login_no_email(supply_url):
	url = supply_url + "/login/" 
	data = {}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing email or username", resp.text

รันการทดสอบโดยใช้ py.test -v

เห็นผลเป็น.

test_list_user.py::test_list_valid_user[1-George] PASSED                                                                                                                                                                               
test_list_user.py::test_list_valid_user[2-Janet] PASSED                                                                                                                                                                                
test_list_user.py::test_list_invaliduser PASSED                                                                                                                                                                                        
test_login_user.py::test_login_valid PASSED                                                                                                                                                                                            
test_login_user.py::test_login_no_password PASSED                                                                                                                                                                                      
test_login_user.py::test_login_no_email PASSED

อัปเดตการทดสอบและลองใช้เอาต์พุตต่างๆ

สรุป

ในบทช่วยสอน PyTest นี้ เราได้กล่าวถึงแล้ว

  • ติดตั้ง pytest โดยใช้ pip ติดตั้ง ไพเทส=2.9.1
  • โปรแกรม pytest อย่างง่ายและรันด้วยคำสั่ง py.test
  • คำสั่งยืนยัน assert x==y จะส่งกลับค่า True หรือ False
  • pytest ระบุไฟล์ทดสอบและวิธีการอย่างไร
  • ทดสอบไฟล์ที่ขึ้นต้นด้วย ทดสอบ_ หรือลงท้ายด้วย _ทดสอบ
  • วิธีทดสอบเริ่มต้นด้วย ทดสอบ
  • คำสั่ง py.test จะรันไฟล์ทดสอบทั้งหมดในโฟลเดอร์และโฟลเดอร์ย่อยนั้น หากต้องการเรียกใช้ไฟล์ใดไฟล์หนึ่ง เราสามารถใช้คำสั่ง py.test
  • เรียกใช้ชุดย่อยของวิธีทดสอบ
  • การจัดกลุ่มชื่อการทดสอบตามสตริงย่อยmatching.py.test -k -v จะทำการทดสอบทั้งหมดที่มี ในนามของมัน
  • รันการทดสอบโดย markers ทำเครื่องหมายการทดสอบโดยใช้ @pytest.mark และรันการทดสอบโดยใช้ pytest -m เพื่อทำการทดสอบที่ทำเครื่องหมายเป็น -
  • ทำการทดสอบแบบขนาน
  • ติดตั้ง pytest-xdist โดยใช้ pip install pytest-xdist
  • รันการทดสอบโดยใช้ py.test -n NUM โดยที่ NUM คือจำนวนคนทำงาน
  • การสร้างวิธีการติดตั้งเพื่อรันโค้ดก่อนการทดสอบทุกครั้งโดยทำเครื่องหมายวิธีการด้วย @ pytest.fixture
  • ขอบเขตของวิธีการฟิกซ์เจอร์อยู่ภายในไฟล์ที่กำหนดไว้
  • วิธีฟิกซ์เจอร์สามารถเข้าถึงได้จากไฟล์ทดสอบหลายไฟล์โดยกำหนดไว้ในไฟล์ conftest.py
  • วิธีทดสอบสามารถเข้าถึงฟิกซ์เจอร์ของ Pytest ได้โดยใช้เป็นอาร์กิวเมนต์อินพุต
  • การทดสอบการกำหนดพารามิเตอร์เพื่อรันกับอินพุตหลายชุด
    @pytest.mark.parametrize(“input1, input2, เอาท์พุท”,[(5,5,10),(3,5,12)])
    def test_add (อินพุต 1, อินพุต 2, เอาต์พุต):
    ยืนยัน input1+input2 == เอาต์พุต”ล้มเหลว”
    จะทำการทดสอบด้วยอินพุต (5,5,10) และ (3,5,12)
  • การทดสอบข้าม/xfail โดยใช้ @pytets.mark.skip และ @pytest.mark.xfail
  • สร้างผลการทดสอบในรูปแบบ XML ซึ่งครอบคลุมรายละเอียดการทดสอบที่ดำเนินการโดยใช้ py.test test_sample1.py -v –junitxml=”result.xml”
  • ตัวอย่างเฟรมเวิร์ก pytest เพื่อทดสอบ API