Hướng dẫn dùng pytest assert python

Hướng dẫn sử dụng thư viện pytest

1. Cài đặt thư viện pytest:

Vào cmd gõ: py – m pip install pytest

2. Chạy các file test và các phương thức test:

Theo mặc định thì pytest sẽ chỉ nhận dạng được các file có tên bắt đầu với test_ hoặc kết thúc với _test. Còn đối với các phương thức thì yêu cầu tên của các phương thức bắt đầu bằng “test”, những phương thức có tên khác sẽ bị bỏ qua.

Dưới đây là ví dụ về đặt tên file pytest hợp lệ và không hợp lệ:

test_username.py --- hợp lệ

username_test.py --- hợp lệ

testusername --- không hợp lệ

usernametest --- không hợp lệ

Và ví dụ về tên các phương thức pytest hợp lệ và không hợp lệ:

def test_method(): --- hợp lệ

def testmethod(): --- hợp lệ

def method(): ---không hợp lệ

3. Chạy những test được chỉ định:

Chúng ta sẽ sử dụng pytest markers bằng cách định nghĩa các marker trên mỗi phương thức, cách khai báo như sau:

  •  

Ví dụ tạo 2 file test test_1.py và test_2.py có nội dung như bên dưới, sau đó chỉ chạy những test có mark tên example1

Nội dung file test_1.py

import pytest

  1.  

def test_equal_1():

a = 1

b = 2

assert a==b, "a không bằng b"

  1.  

def test_equal_2():

a = 1

b = 2

assert a==b, "a không bằng b"

Nội dung file test_2.py

import pytest

  1.  

def test_equal_1():

a = 1

b = 2

assert a==b, "a không bằng b"

  1.  

def test_equal_2():

a = 1

b = 2

assert a==b, "a không bằng b"

Sau khi lưu lại 2 file trên, chúng ta sẽ chạy những test có mark tên example1 bằng cách vào đường dẫn nơi đặt 2 file vừa tạo và gõ:

pytest –m example1

Kết quả:

Hướng dẫn dùng pytest assert python

Hướng dẫn dùng pytest assert python

Hướng dẫn dùng pytest assert python

Theo như trên hình thì test_1.py có 1 chức năng bị Fail, test_2 có 2 phương thức bị Fail, chỉ ra bị sai ở chỗ nào của phương thức.

Ngoài ra, pytest có cung cấp các mark được định nghĩa sẵn, chúng ta sẽ vào cmd gõ: pytest - -markers

Hướng dẫn dùng pytest assert python

4. Fixtures:

Fixtures được dùng để khởi tạo các thông số đầu vào, thay vì trong mỗi đoạn test chúng ta đều phải khai báo các giá trị để đưa vào test thì ta chỉ cần khai báo một lần duy nhất, khi muốn sử dụng vào đoạn test nào thì gọi hàm đã được chúng ta đánh dấu là fixture.

Chúng ta sẽ đi đến ví dụ sau để dễ hình dung hơn

import pytest

  •  

def input_value():

input = 10

return input

def test_mod_2(input_value):

assert input_value %2 == 0

def test_mod_3(input_value):

assert input_value %3 == 0

Lưu file với tên test_mod.py, sau đó vào cmd chạy file: pytest –k mod –v .Đây là một cách chạy các test có tên có chữ “mod”

Kết quả:

Hướng dẫn dùng pytest assert python

Hướng dẫn dùng pytest assert python


Thông tin khác

  • » LAB 13 : VIẾT ACCESS-CONTROL LIST (ACL) POLICY TRONG CISCO SD-WAN (04.03.2021)
  • » Overlay Management Protocol (OMP) (03.03.2021)
  • » LEAN (01.03.2021)
  • » LAB 12 : VIẾT CENTRALIZED POLICY ĐỂ LEAKING ROUTE GIỮA CÁC SERVICE VPN (01.03.2021)
  • » Tìm hiểu về Ansible, Puppet, Chef (24.02.2021)
  • » LAB 11 : VIẾT TEMPLATE CẤU HÌNH GIAO THỨC DỰ PHÒNG ĐỊNH TUYẾN VRRP TRÊN CISCO SD-WAN (24.02.2021)
  • » TUẦN TỰ HÓA DỮ LIỆU VÀ ĐỊNH DẠNG DỮ LIỆU JSON (22.02.2021)
  • » LAB 10 : VIẾT CENTRALIZED POLICY ĐỂ CÔ LẬP GUEST USER GIỮA CÁC CHI NHÁNH (22.02.2021)

Giới thiệu về Pytest

Đặt vấn đề

Bạn viết 1 service mà nó yêu cầu lấy dữ liệu từ bên thứ ba sau đó phải xử lý dữ liệu nhận được để đưa ra kết quả trả về cho response, giả sử quá trình đó diễn ra rất mất thời gian (tầm 5s). Và bây giờ bạn muốn kiểm thử hoạt động của service của mình nhưng lại không mong muốn nó gọi API của bên thứ 3 liên tục mỗi lần test vì nó sẽ làm cho quá trình test chậm lại, vả lại việc gọi thêm API sẽ đòi hỏi nhiều bước làm của bạn Một trường hợp khác là hàm cần test cần thao tác với database, nhưng ta không được phép thay đổi hay cập nhật vào database đó (vì sẽ làm nguy hiểm đến hệ thống đang chạy). Vậy điều chúng ta cần ở đây chính là việc có thể thay thế việc gọi API hay truy cập database bằng một hành động khác nào đó mà vẫn có dữ liệu trả về tương tự như API, chúng ta tạm gọi đó là việc mock hay còn gọi là patching

Pytest

Không giống như phần lớn các ngôn ngữ lập trình, Python sử dụng 1 thư viện built-in cho việc testting đó là pytest Để cài đặt và sử dụng pytest, ta chạy câu lệnh sau:

pip install pytest-mock

Cách sử dụng của Pytest

Đầu tiên ta cần có một hàm để mang đi test, giả sử nó có tên là example() Việc ta cần làm là:

  1. Tạo file test với cú pháp bắt buộc: có bắt đầu hoặc kết thúc bằng từ test Ví dụ: test_file.py
  2. Tạo hàm test với cú pháp bắt đầu bằng từ test Ví dụ: test_example() Sử dụng assert để so sánh kết quả khi gọi hàm example() với output ta mong muốn (assert sẽ raise lên lỗi khi kết quả không bằng nhau)
  3. Chạy test Sử dụng command-line để chạy dòng lệnh sau:

pytest [-k example] -[v] -[vv] [-s]

Giải thích:
    Flag `-k` đi kèm với 1 keyword, Pytest sẽ tìm các hàm có tên hàm chứa keyword đó để chạy (rất hữu ích trong trường hợp bạn viết nhiều hàm test cho nhiều API và muốn chạy 1 hàm cụ thể)
    Flag `-v` sẽ hiển thị nhiều thông tin của testcase hơn khi chạy testing
    Flag `-vv` tương tự như `-v` nhưng sẽ hiển thị chi tiết trong trường hợp nếu testcase failed (đầu ra với output khác nhau) sẽ chỉ ra khác nhau ở đoạn nào
    Flag `-s` sẽ thực thi và in ra nội dung của các câu lệnh print trong code (Mà pytest sẽ bỏ qua lệnh print)

Ví dụ đơn giản về sử dụng Pytest

Ví dụ này sẽ giúp bạn hiểu tại sao nên sử dụng mock để có thể tăng tốc độ testing và không ảnh hưởng đến code base mà bạn đã viết Giả sử ta có hàm get_operating_system sẽ cho ta biết máy tính đang sử dụng Windows hay Linux

# application.py 
from time import sleep  
def is_windows():    
    # This sleep could be some complex operation instead
    sleep(5)    
    return True  
def get_operating_system():    
    return 'Windows' if is_windows() else 'Linux'

Trong đó, hàm is_windows để check nếu hệ điều hành hiện tại là Windows hay không, ta giả sử hàm này khá phức tạp và tốn khá nhiều thời gian để chạy, ta giả sử bằng hàm sleep(5), nghĩa là chương trình sẽ mất 5s để xử lý Hàm get_operating_system sẽ là phần code base và ta cần phải mang nó đi test để kiểm thử Ta cần một hàm chạy test, có tên là test_get_operating_system sau:

# test_application.py

from application import get_operating_system

def test_get_operating_system():
    assert get_operating_system() == 'Windows'

Sau đó ta chạy lệnh test:

$ pytest
================ test session starts ========================
Python 3.7.3, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /usr/Personal/Projects/pytest-and-mocking
plugins: mock-2.0.0
collected 1 item

test_application.py .                                    [100%]

================ 1 passed in 5.05s ==========================

Ta thấy kết quả chạy thực sự khá lâu, và để khắc phục điều đó, ta sẽ sử dụng khái niệm gọi là mocker và để nó là tham số của hàm test, nó có tác dụng làm test của ta khi gọi đến hàm is_windows() sẽ không chạy hàm thật, mà return luôn về giá trị mà ta định sẵn trong đối số của mocker mocker sẽ nhận 2 đối số, một là path - là đường dẫn đến nơi hàm mà ta định fake hàm, hai là return_value là giá trị trả về khi gọi hàm fake đó Bây giờ ta sẽ update lại hàm test, sử dụng mocker:

# 'mocker' fixture provided by pytest-mock
def test_get_operating_system(mocker):  
    # Mock the slow function and return True always
    mocker.patch('application.is_windows', return_value=True) 
    assert get_operating_system() == 'Windows'

Ta chạy lại code test sẽ thấy kết quả được cải thiện:

$ pytest
============ test session starts ==================
Python 3.7.3, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /mnt/c/Personal/Projects/pytest-and-mocking
plugins: mock-2.0.0
collected 1 item

test_application.py .                          [100%]

=========== 1 passed in 0.11s ======================

Trong ví dụ trên ta mặc định những gì ta trả về chỉ là giá trị true, giờ muốn nó là false thì sẽ viết như sau:

def test_operation_system_is_linux(mocker):
    mocker.patch('application.is_windows', return_value=False) # set the return value to be False
    assert get_operating_system() == 'Linux'

Tài liệu tham khảo

https://www.freblogg.com/pytest-functions-mocking-1