Tôi có một tệp được lưu ở định dạng cụ thể và một lớp sẽ tạo đối tượng dựa trên dữ liệu trong tệp.Làm thế nào để sử dụng pytest để đảm bảo một đối tượng được tạo ra đúng cách?
Tôi muốn đảm bảo rằng tất cả các giá trị trong tệp/chuỗi được trích xuất một cách chính xác bằng cách kiểm tra từng thuộc tính trong đối tượng.
Đây là một phiên bản đơn giản của những gì tôi đang làm:
classlist.py
import re
class ClassList:
def __init__(self, data):
values = re.findall('name=(.*?)\$age=(.*?)\$', data)
self.students = [Student(name, int(age)) for name, age in values]
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
test_classlist.py
import pytest
from classlist import ClassList
def single_data():
text = 'name=alex$age=20$'
return ClassList(text)
def double_data():
text = 'name=taylor$age=23$' \
'name=morgan$age=25$'
return ClassList(text)
@pytest.mark.parametrize('classinfo, expected', [
(single_data(), ['alex']),
(double_data(), ['taylor', 'morgan'])
])
def test_name(classinfo, expected):
result = [student.name for student in classinfo.students]
assert result == expected
@pytest.mark.parametrize('classinfo, expected', [
(single_data(), [20]),
(double_data(), [23, 25])
])
def test_age(classinfo, expected):
result = [student.age for student in classinfo.students]
assert result == expected
Tôi muốn tạo ra các đối tượng dựa trên các dữ liệu khác nhau và sử dụng chúng như một giá trị parametrized.
Thiết lập hiện tại của tôi hoạt động, mặc dù có sự nghe lén không cần thiết về việc tạo đối tượng cho mỗi thử nghiệm. Tôi muốn chúng được tạo ra một lần.
Nếu tôi cố gắng làm như sau:
...
@pytest.fixture(scope='module') # fixture added
def double_data():
text = 'name=taylor$age=23$' \
'name=morgan$age=25$'
return ClassList(text)
@pytest.mark.parametrize('classinfo, expected', [
(single_data, ['alex']),
(double_data, ['taylor', 'morgan']) #() removed
])
def test_name(classinfo, expected):
result = [student.name for student in classinfo.students]
assert result == expected
...
AttributeError: 'function' object has no attribute 'students'
... nó không hoạt động như nó tham chiếu chức năng chứ không phải là cố định.
Ngoài ra, mã trong test_name
và test_age
gần như giống hệt nhau. Trong mã thực tế của tôi, tôi đang làm điều này cho khoảng 12 thuộc tính. Nên/điều này có thể được sáp nhập vào một chức năng duy nhất? Làm sao?
Tôi làm cách nào để có thể xóa mã thử nghiệm của mình?
Cảm ơn!
Edit:
Tôi cảm thấy đây là có liên quan, nhưng tôi chắc chắn về cách làm cho nó làm việc cho tình hình của tôi: Can params passed to pytest fixture be passed in as a variable?
Tôi đã thử sử dụng phương pháp ma thuật bình đẳng, nhưng trong mã thực tế của tôi, có khoảng 12 thuộc tính (một số trong đó khá dài), vì vậy tôi thấy khó so sánh cả hai và xác định chính xác vị trí của vấn đề. Tôi có nên cải thiện định dạng không? đây có phải là cách tốt hơn không? – Jake
@jake là vấn đề tạo ra phương pháp bình đẳng hoặc thử nghiệm đơn vị? có vẻ như bạn đang sử dụng lớp để lưu trữ dữ liệu, hãy xem [tên tệp] (https://docs.python.org/3/library/collections.html#collections.namedtuple) hoặc [attrs] (https: // pypi.python.org/pypi/attrs/17.2.0) module, vì nó cung cấp các phương thức này miễn phí và nó phù hợp với trường hợp sử dụng này tốt hơn. – salparadise