Below is a test file for the Streamlink library. I was reading the test files to understand how testing is done and found a confusing set up for the tests. The test set up a series of @pytest.fixture
s to help with testing. The assert_live
fixture below is defined and passed into some tests, but never called at all. I dont think this is a mistake because a similar pattern is found throughout the file. I read the docs for fixtures but couldn't find anything that mentions this functionality. I got excited when they talked about using yeild
inside a fixture but that turned not to touch on the subject either. Google was even less helpful. I am at a loss, but I am very interested in contributing to this library and need to understand how it works and how they test. Test is at the bottom of the code below. Thank you in advance!
# Other fixtures for context/continuity
@pytest.fixture
def mocker(self):
# The built-in requests_mock fixture is bad when trying to reference the following constants or classes
with requests_mock.Mocker() as mocker:
mocker.register_uri(requests_mock.ANY, requests_mock.ANY, exc=requests_mock.exceptions.InvalidRequest)
yield mocker
@pytest.fixture
def mock(self, request, mocker: requests_mock.Mocker):
mock = mocker.post("https://gql.twitch.tv/gql", **getattr(request, "param", {"json": {}}))
yield mock
assert mock.called_once
payload = mock.last_request.json() # type: ignore[union-attr]
assert tuple(sorted(payload.keys())) == ("extensions", "operationName", "variables")
assert payload.get("operationName") == "PlaybackAccessToken"
assert payload.get("extensions") == {
"persistedQuery": {
"sha256Hash": "0828119ded1c13477966434e15800ff57ddacf13ba1911c129dc2200705b0712",
"version": 1,
},
}
# The confusing fixture
@pytest.fixture
def assert_live(self, mock):
yield
assert mock.last_request.json().get("variables") == { # type: ignore[union-attr]
"isLive": True,
"isVod": False,
"login": "channelname",
"vodID": "",
"playerType": "embed",
}
# The confusing test
# note that assert_live is passed as an arg but is not actually used.
@pytest.mark.parametrize("plugin,mock", [
(
[("api-header", [("Authorization", "OAuth invalid-token")])],
{
"status_code": 401,
"json": {"error": "Unauthorized", "status": 401, "message": "The \"Authorization\" token is invalid."},
},
),
], indirect=True)
def test_auth_failure(self, caplog: pytest.LogCaptureFixture, plugin: Twitch, mock: requests_mock.Mocker, assert_live):
with pytest.raises(NoStreamsError) as cm:
plugin._access_token(True, "channelname")
assert str(cm.value) == "No streams found on this URL: https://twitch.tv/channelname"
assert mock.last_request._request.headers["Authorization"] == "OAuth invalid-token" # type: ignore[union-attr]
assert [(record.levelname, record.module, record.message) for record in caplog.records] == [
("error", "twitch", "Unauthorized: The \"Authorization\" token is invalid."),
]