IonizationChamber/Software/MeasurementAcquisition/tests_ut/test_mcp3425_converter.py

86 wiersze
3.4 KiB
Python
Executable File

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""Unit tests for :pyclass:`measurement_acquisition.mcp3425_converter.MCP3425Converter`."""
from __future__ import annotations
import pytest
from measurement_acquisition.mcp3425_converter import (
MCP3425Converter,
ADCResolution,
)
class TestMCP3425Converter: # pylint: disable=too-few-public-methods
"""Validate conversion across resolutions, edge cases, and bad input."""
@pytest.fixture()
def converter(self) -> MCP3425Converter: # noqa: D401 – fixture
"""Return a concrete converter instance for the tests."""
return MCP3425Converter()
# ------------------------------------------------------------------
# Nominal conversion values
# ------------------------------------------------------------------
@pytest.mark.parametrize(
"upper, lower, res, expected",
[
# 16bit resolution tests (LSB = 62.5µV)
(0x00, 0x00, ADCResolution.R16, 0.0),
(0x7F, 0xFF, ADCResolution.R16, 2.0479375),
(0x80, 0x00, ADCResolution.R16, -2.048),
(0x00, 0x01, ADCResolution.R16, 0.0000625),
(0xFF, 0xFF, ADCResolution.R16, -0.0000625),
# 14bit resolution tests
(0x00, 0x00, ADCResolution.R14, 0.0),
(0x7F, 0xFC, ADCResolution.R14, 2.04775),
(0x80, 0x00, ADCResolution.R14, -2.048),
(0x00, 0x04, ADCResolution.R14, 0.00025),
# 12bit resolution tests
(0x00, 0x00, ADCResolution.R12, 0.0),
(0x7F, 0xF0, ADCResolution.R12, 2.047),
(0x80, 0x00, ADCResolution.R12, -2.048),
(0x00, 0x10, ADCResolution.R12, 0.001),
# Boundary mixes
(0x7F, 0xFF, ADCResolution.R14, 2.0479375),
(0x1F, 0xFF, ADCResolution.R16, 0.5119375),
],
)
def test_converter_values( # pylint: disable=too-many-arguments,too-many-positional-arguments
self,
converter: MCP3425Converter,
upper: int,
lower: int,
res: ADCResolution,
expected: float,
) -> None:
"""Ensure calculated voltage matches expected value within 1e6 V."""
result = converter.convert(upper, lower, res)
assert result == pytest.approx(expected, abs=1e-6)
# ------------------------------------------------------------------
# Graceful fallback on invalid resolution
# ------------------------------------------------------------------
def test_invalid_resolution(self, converter: MCP3425Converter) -> None:
"""Passing an unknown resolution string returns 0.0 (legacy behaviour)."""
result = converter.convert(0x00, 0x00, "invalid") # type: ignore[arg-type]
assert result == 0.0
# ------------------------------------------------------------------
# Inputrange validation
# ------------------------------------------------------------------
@pytest.mark.parametrize(
"upper, lower, res",
[
(-1, 0, ADCResolution.R16),
(0, -1, ADCResolution.R16),
(256, 0, ADCResolution.R16),
(0, 256, ADCResolution.R16),
],
)
def test_invalid_bytes(
self, converter: MCP3425Converter, upper: int, lower: int, res: ADCResolution
) -> None:
"""Outofrange byte values must raise :class:`ValueError`."""
with pytest.raises(ValueError):
converter.convert(upper, lower, res)