meta-pytorch / meta-pytorch/data
Refactor test suite to be more readable?
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.3k
- Forks
- 179
- Avg merge
- 6d 1h
- Merged PRs (30d)
- 2
Description
While working on #174, I also worked on the test suite. In there we have the ginormous tests that are hard to parse, because they do so many things at the same time:
I was wondering if there is a reason for that. Can't we split this into multiple smaller ones? Utilizing pytest, placing the following class in the test module is equivalent to the test above:
class TestLineReader:
@pytest.fixture
def text1(self):
return "Line1\nLine2"
@pytest.fixture
def text2(self):
return "Line2,1\nLine2,2\nLine2,3"
def test_functional_read_lines_correctly(self, text1, text2):
source_dp = IterableWrapper([("file1", io.StringIO(text1)), ("file2", io.StringIO(text2))])
line_reader_dp = source_dp.readlines()
expected_result = [("file1", line) for line in text1.split("\n")] + [
("file2", line) for line in text2.split("\n")
]
assert expected_result == list(line_reader_dp)
def test_functional_strip_new_lines_for_bytes(self, text1, text2):
source_dp = IterableWrapper(
[("file1", io.BytesIO(text1.encode("utf-8"))), ("file2", io.BytesIO(text2.encode("utf-8")))]
)
line_reader_dp = source_dp.readlines()
expected_result_bytes = [("file1", line.encode("utf-8")) for line in text1.split("\n")] + [
("file2", line.encode("utf-8")) for line in text2.split("\n")
]
assert expected_result_bytes == list(line_reader_dp)
def test_functional_do_not_strip_newlines(self, text1, text2):
source_dp = IterableWrapper([("file1", io.StringIO(text1)), ("file2", io.StringIO(text2))])
line_reader_dp = source_dp.readlines(strip_newline=False)
expected_result = [
("file1", "Line1\n"),
("file1", "Line2"),
("file2", "Line2,1\n"),
("file2", "Line2,2\n"),
("file2", "Line2,3"),
]
assert expected_result == list(line_reader_dp)
def test_reset(self, text1, text2):
source_dp = IterableWrapper([("file1", io.StringIO(text1)), ("file2", io.StringIO(text2))])
line_reader_dp = LineReader(source_dp, strip_newline=False)
expected_result = [
("file1", "Line1\n"),
("file1", "Line2"),
("file2", "Line2,1\n"),
("file2", "Line2,2\n"),
("file2", "Line2,3"),
]
n_elements_before_reset = 2
res_before_reset, res_after_reset = reset_after_n_next_calls(line_reader_dp, n_elements_before_reset)
assert expected_result[:n_elements_before_reset] == res_before_reset
assert expected_result == res_after_reset
def test_len(self, text1, text2):
source_dp = IterableWrapper([("file1", io.StringIO(text1)), ("file2", io.StringIO(text2))])
line_reader_dp = LineReader(source_dp, strip_newline=False)
with pytest.raises(TypeError, match="has no len"):
len(line_reader_dp)
This is a lot more readable, since we now actually have 5 separate test cases that can individually fail. Plus, while writing this I also found that test_reset and test_len were somewhat dependent on test_functional_do_not_strip_newlines since they don't neither define line_reader_dp nor expected_result themselves.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the cited test/test_datapipe.py block at lines 382–426 and inspect the existing LineReader tests. Split the combined coverage into independent pytest cases like the proposed TestLineReader class, ensuring each test defines its own data and setup. Done means the cases can fail independently and the existing behavior remains covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100