Đồ đạc Pytest

Hoàn thành

Đồ họa là các chức năng trợ giúp pytest được sử dụng để tạo các xét nghiệm mô-đun, có thể mở rộng và có thể duy trì. Bạn sử dụng thiết bị sửa lỗi để thiết lập điều kiện tiên quyết cho các kiểm tra như kết nối cơ sở dữ liệu, tạo dữ liệu kiểm tra hoặc cấu hình trạng thái hệ thống bắt buộc trước khi kiểm tra có thể chạy. Chúng cũng có thể được sử dụng để dọn dẹp sau khi kiểm tra xong chạy.

Các đặc điểm chính của đồ cố định pytest bao gồm:

  • Kiểm soát phạm vi: Có thể lập cấu hình các thiết bị sửa lỗi để có các phạm vi khác nhau bằng cách dùng tham số scope (chẳng hạn như function, class, module, hoặc session), để xác định tần suất được gọi là fixture.
  • lý thiết lập và xé nhỏ: Pytest quản lý vòng đời của thiết bị cố định, tự động thiết lập và xé nhỏ theo yêu cầu.
  • phụ thuộc tiêm: Fixtures được tiêm vào các chức năng thử nghiệm như là đối số, làm cho nó rõ ràng mà kiểm tra dựa vào những fixtures.
  • năng tái sử dụng và mô-đun: Có thể xác định các đồ dùng ở một nơi và được sử dụng trên nhiều chức năng thử nghiệm, mô-đun hoặc thậm chí là các dự án.

Tạo tệp cố định tạm thời

Khi viết các kiểm tra tương tác với tệp, thông thường sẽ cần các tệp tạm thời không làm xáo trộn sau khi kiểm tra hệ thống tệp. Với pytest, chúng tôi có thể tạo một fixture thiết lập một tập tin tạm thời. Thiết bị cố định sử dụng mô-đun tempfile của Python để tạo ra các tệp tạm thời một cách an toàn, đảm bảo rằng chúng có thể được sử dụng và xóa mà không ảnh hưởng đến môi trường cục bộ. (Trong phiên bản ban đầu này của bản sửa lỗi của chúng tôi, tệp sẽ không tự động bị xóa do có delete=False này. Chúng tôi sẽ giải quyết việc xóa tệp sau.)

Dưới đây là diện mạo của thiết bị:

import pytest
import tempfile

@pytest.fixture
def tmp_file():
    def create():
        # Create a named temporary file that persists beyond the function scope
        temp = tempfile.NamedTemporaryFile(delete=False)
        return temp.name
    return create

Trong thiết lập này, tmp_file() hoạt động như là cố định. Tên của fixture là cách các kiểm tra tham chiếu nó. Trong fixture, hàm lồng nhau create() tệp chỉ khi được gọi, chứ không phải khi thiết lập fixture. Điều này cho phép kiểm soát chính xác thời điểm tạo tệp tạm thời, điều này rất hữu ích trong các kiểm tra trong đó thời gian và trạng thái tệp rất quan trọng.

Trong phạm vi hàm được lồng create(), một tệp tạm thời được tạo và sau đó trả về đường dẫn tuyệt đối đến tệp đó. Dưới đây là ví dụ về cách kiểm tra có thể sử dụng thiết bị cố định mà chúng tôi đã viết:

import os

def test_file(tmp_file):
    path = tmp_file()
    assert os.path.exists(path)

Kiểm tra sử dụng một fixture bằng cách xác định tên của fixture như là một đối số. Trường hợp sử dụng đơn giản của chúng tôi có thể dễ dàng mở rộng bằng cách viết vào tập tin hoặc sửa đổi như thay đổi quyền hoặc quyền sở hữu.

Quản lý phạm vi

Theo lịch trình, việc quản lý vòng đời của các tài nguyên thử nghiệm thông qua các quy trình thiết lập và xé nhỏ là điều quan trọng để duy trì các môi trường thử nghiệm sạch sẽ và hiệu quả. Bạn cũng muốn bảo vệ tính toàn vẹn của các xét nghiệm bằng cách đảm bảo rằng mỗi thử nghiệm bắt đầu với trạng thái nhất quán, đã biết. Theo mặc định, các đồ cố định pytest hoạt động với function vi kiểm tra, tác động đến hành vi theo hai cách:

  • vòng đời cho mỗithử nghiệm: Giá trị trả lại của thiết bị cố định được tính toán lại cho mọi hàm thử nghiệm sử dụng nó, đảm bảo rằng mỗi thử nghiệm hoạt động với trạng thái mới.
  • dọn dẹp sau mỗi lần sử dụng: Mọi hoạt động dọn dẹp cần thiết đều được thực hiện sau mỗi lần thử nghiệm sử dụng fixture.

Pytest cũng cho phép các đồ họa được đặt phạm vi rộng hơn để tối ưu hóa hiệu suất và mức sử dụng tài nguyên. Phạm vi đặc biệt hữu ích trong các tình huống như quản lý trạng thái cơ sở dữ liệu hoặc khi bạn có thiết lập trạng thái phức tạp tốn thời gian để thiết lập. Bốn phạm vi sẵn dùng là:

  • function: Phạm vi mặc định, trình khắc phục được thực hiện một lần cho mỗi thử nghiệm
  • class: Trình khắc phục chạy một lần cho mỗi lớp thử nghiệm.
  • module: chạy một lần cho một mô-đun.
  • session: Chạy một lần cho mỗi phiên thử nghiệm. Phạm vi này hữu ích cho các thao tác đắt tiền cần phải duy trì trong toàn bộ phiên thử nghiệm, chẳng hạn như khởi tạo dịch vụ hoặc khởi động máy chủ cơ sở dữ liệu.

Trong trường hợp này, chạy sau khi nghĩa là giá trị trả về được lưu vào bộ đệm ẩn. Vì vậy, một fixture có một phạm vi của "mô-đun" có thể được gọi là nhiều lần trong một mô-đun thử nghiệm, nhưng giá trị trả lại là của thử nghiệm đầu tiên được gọi là nó.

Dưới đây là diện mạo của tmp_file() cố định với phạm vi mô-đun:

import pytest
import tempfile

@pytest.fixture(scope="module")
def tmp_file():
    def create():
        temp = tempfile.NamedTemporaryFile(delete=False)
        return temp.name
    return create

Quản lý dọn dẹp

Mã trước đó xác định tmp_file cố định sẽ tạo ra một tệp tạm thời, nhưng nó không tự động xử lý dọn dẹp sau khi hoàn tất kiểm tra. Để đảm bảo rằng các tệp tạm thời không bị bỏ lại, bạn có thể sử dụng thiết bị sửa lỗi request của pytest để đăng ký chức năng dọn dẹp.

Dưới đây là cách bạn có thể sửa đổi tmp_file sửa để bao gồm tự động dọn dẹp:

import pytest
import tempfile
import os

@pytest.fixture(scope="module")
def tmp_file(request):
    # Create a temporary file that persists beyond the function scope
    temp = tempfile.NamedTemporaryFile(delete=False)

    def create():
        # Returns the path of the temporary file
        return temp.name

    def cleanup():
        # Remove the file after the tests are done
        os.remove(temp.name)

    # Register the cleanup function to be called after the last test in the module
    request.addfinalizer(cleanup)

    return create

Bằng cách sử request.addfinalizer() nhập và chuyển hàm cleanup() lồng nhau, việc dọn dẹp sẽ được gọi tùy thuộc vào phạm vi. Trong trường hợp này, phạm vi được xác module, vì vậy sau khi tất cả các kiểm tra trong một cuộc gọi pytest mô-đun mà chức năng dọn dẹp.

Sử dụng conftest.py

Thay vì đưa đồ cố định của bạn vào các tệp thử nghiệm, bạn có thể lưu chúng trong một conftest.py của bạn. Tất cả các thiết bị trong conftest.py sẽ tự động có sẵn cho các kiểm tra của bạn trong cùng một thư mục mà không cần phải nhập chúng một cách rõ ràng.

Khám phá các thiết bị cài sẵn

Pytest có nhiều thiết bị cố định tích hợp sẵn được thiết kế để hợp lý hóa việc kiểm tra. Các thiết bị này có thể tự động xử lý việc thiết lập và dọn dẹp, cho phép bạn tập trung vào việc viết các trường hợp thử nghiệm thay vì quản lý kiểm tra.

Các thiết bị cài sẵn chính bao gồm:

  • cache: Được sử dụng để tạo và quản lý bộ đệm ẩn mức kiểm tra, rất hữu ích để lưu trữ dữ liệu giữa các phiên kiểm tra.
  • capsys: Chụp và cho phép kiểm tra stderrstdout, giúp dễ dàng kiểm tra và kiểm tra đầu ra bảng điều khiển.
  • tmpdir: Cung cấp một thư mục tạm thời cho các tệp cần được tạo và sử dụng trong quá trình kiểm tra.
  • monkeypatch: Cung cấp một cách để sửa đổi hành vi và giá trị của đối tượng, chức năng và môi trường hệ điều hành của bạn một cách an toàn.

Vai trò của monkeypatching trong thử nghiệm

Việc kiểm tra mã tích hợp chặt chẽ với các tài nguyên bên ngoài như cơ sở dữ liệu hoặc API bên ngoài có thể khó khăn do các phụ thuộc có liên quan. Một kỹ thuật được gọi là khỉ vá liên quan đến việc tạm thời sửa đổi hệ thống của bạn trong khi chạy thử nghiệm, cho phép độc lập từ hệ thống bên ngoài và cho phép bạn một cách an toàn thay đổi trạng thái và hành vi của môi trường hệ điều hành của bạn trong quá trình thử nghiệm.

Dưới đây là ví dụ về cách ghi đè hàm os.path.exists() cách sử dụng monkeypatch cố định:

import os

def test_os(monkeypatch):
    # Override os.path.exists to always return False
    monkeypatch.setattr('os.path.exists', lambda x: False)
    assert not os.path.exists('/')

Ngoài ra, bạn có thể sử dụng phương pháp setattr() với tham chiếu trực tiếp đến đối tượng và thuộc tính:

def test_os(monkeypatch):
    # Specify the object and attribute to override
    monkeypatch.setattr(os.path, 'exists', lambda x: False)
    assert not os.path.exists('/')

Ngoài việc đặt thuộc tính và phương pháp ghi đè, trình khắc phục monkeypatch có thể đặt và xóa các biến môi trường, thay đổi giá trị từ điển và sửa đổi đường dẫn hệ thống. Thiết monkeypatch cố định sẽ tự động hoàn nguyên mọi thay đổi sau mỗi lần thử nghiệm nhưng cần phải cẩn thận khi sử dụng monkeypatch cố định. Dưới đây là một số lý do cần cẩn thận khi sử dụng:

- rõ ràng và bảo trì: Sử dụng quá nhiều monkeypatch hoặc sử dụng nó theo những cách phức tạp có thể làm cho kiểm tra khó hiểu và duy trì hơn. Khi bạn đọc kết quả kiểm tra của mình, có thể không rõ cấu phần hoạt động bình thường như thế nào so với cách sửa đổi chúng để thử nghiệm. - kiểm tra tínhkiểm tra: Monkeypatching đôi khi có thể dẫn đến các xét nghiệm vượt qua trong điều kiện nhân tạo rất khác với môi trường sản xuất. Điều này có thể tạo ra một cảm giác sai lầm về bảo mật, như các xét nghiệm có thể vượt qua bởi vì thử nghiệm đã thay đổi hành vi của hệ thống quá đáng kể. - phụ thuộc quá mức vào chi tiết thực hiện: Các kiểm tra dựa trên monkeypatching có thể được kết hợp chặt chẽ với các chi tiết thực hiện cụ thể của mã mà họ đang thử nghiệm. Điều này có thể làm cho các kiểm tra trở nên giòn và dễ bị phá vỡ với ngay cả những thay đổi nhỏ đối với cơ sở mã cơ sở. - gỡ lỗi sự phức tạp: Gỡ lỗi kiểm tra sử dụng monkeypatch có thể phức tạp hơn, đặc biệt là nếu các bản vá thay đổi các khía cạnh cơ bản của hành vi ứng dụng. Hiểu tại sao kiểm tra không thành công có thể đòi hỏi phải tìm hiểu sâu hơn về cách sửa đổi các thành phần trong quá trình kiểm tra.

Trong khi monkeypatch là một công cụ mạnh mẽ để tạo ra các môi trường thử nghiệm bị cô lập và kiểm soát, nó nên được sử dụng một cách thận trọng và với một sự hiểu biết rõ ràng về làm thế nào nó ảnh hưởng đến bộ thử nghiệm và hành vi của ứng dụng.