Skip to content

Testing Reference

tests

Automated tests for psychoanalyze.

Tests are documented for both users of and contributors to the package.

  • Users should reference tests as examples for efficient utilization of the psychoanalyze package.
  • Contributors should reference tests to assist in writing the required tests for accepted contributions.

Generally, each test file corresponds to its corresponding submodule.

test_weber

Test psychoanalyze.weber functions.

test_aggregate()

Makes sure that thresholds at a given stimulus intensity are aggregated.

Source code in tests/test_weber.py
def test_aggregate() -> None:
    """Makes sure that thresholds at a given stimulus intensity are aggregated."""
    curve_data = pd.DataFrame.from_records(
        [
            {"Reference Charge (nC)": 0, "Difference Threshold (nC)": 0},
            {"Reference Charge (nC)": 0, "Difference Threshold (nC)": 2},
        ],
        index=pd.MultiIndex.from_frame(
            pd.DataFrame({"Monkey": ["U", "U"], "Dimension": ["Amp", "Amp"]}),
        ),
    )
    agg = weber.aggregate(curve_data)
    assert (
        agg.iloc[0, agg.columns.get_loc("Difference Threshold (nC)")]
        == curve_data["Difference Threshold (nC)"].mean()
    )

test_load(tmp_path)

Given weber_curves.csv, loads dataframe.

Source code in tests/test_weber.py
def test_load(tmp_path: Path) -> None:
    """Given weber_curves.csv, loads dataframe."""
    pd.DataFrame(
        {level_name: [] for level_name in types.block_index_levels}
        | {
            "Reference Charge (nC)": [],
            "location_CI_5": [],
            "location_CI_95": [],
            "Fixed_Param_Value": [],
            "Threshold_Charge_nC": [],
        },
    ).to_csv(tmp_path / "weber_curves.csv", index_label=False)
    assert len(weber.load(tmp_path / "weber_curves.csv")) == 0

test_points

Tests for psychoanalyze.points module.

test_sessions

Tests for psychoanalyze.sessions module.

subjects()

Subjects for session-level data.

Source code in tests/test_sessions.py
@pytest.fixture()
def subjects() -> pd.DataFrame:
    """Subjects for session-level data."""
    return pd.DataFrame({"Monkey": ["U"], "Surgery Date": ["2020-01-01"]})

test_generate_sessions()

Test appropriate number of sessions are generated.

Source code in tests/test_sessions.py
def test_generate_sessions() -> None:
    """Test appropriate number of sessions are generated."""
    assert sessions.generate(3) == [0, 1, 2]

test_from_trials_csv(tmp_path)

Test loading trials from csv.

Source code in tests/test_sessions.py
def test_from_trials_csv(tmp_path: Path) -> None:
    """Test loading trials from csv."""
    csv_dir = tmp_path / "data"
    csv_dir.mkdir()
    csv_path = csv_dir / "trials.csv"
    data: dict[str, list[Any]] = {field: [] for field in ["Monkey", "Date"]}
    trials = pd.DataFrame(data)
    trials.to_csv(csv_path)

    _sessions = sessions.from_trials_csv(csv_path)
    assert set(_sessions.columns) == {"Monkey", "Date"}

test_day_marks_from_monkey_two_sessions(subjects)

Tests calculations of days from dates for multiple subjects.

Source code in tests/test_sessions.py
def test_day_marks_from_monkey_two_sessions(subjects: pd.DataFrame) -> None:
    """Tests calculations of days from dates for multiple subjects."""
    _sessions = pd.DataFrame(
        {"Monkey": ["U", "U"], "Date": ["2020-01-02", "2020-01-03"]},
    )
    assert sessions.day_marks(subjects, _sessions, "U") == {
        1: "2020-01-02",
        2: "2020-01-03",
    }

test_day_marks_from_monkey_one_session(subjects)

Tests calculations of days from dates for single subject.

Source code in tests/test_sessions.py
def test_day_marks_from_monkey_one_session(subjects: pd.DataFrame) -> None:
    """Tests calculations of days from dates for single subject."""
    _sessions = pd.DataFrame({"Monkey": ["U"], "Date": ["2020-01-02"]})

    assert sessions.day_marks(subjects, _sessions, "U") == {1: "2020-01-02"}

test_dashboard

Test dashboard callbacks.

test_blocks

test_thresholds()

Tests threshold plot.

Source code in tests/test_blocks.py
def test_thresholds() -> None:
    """Tests threshold plot."""
    data = pd.DataFrame(
        {
            "Subject": ["A", "B"],
            "5%": [1, 2],
            "50%": [1, 2],
            "95%": [1, 2],
            "Block": [1, 2],
        },
    )
    fig = blocks.plot_thresholds(data)
    subjects = {trace["legendgroup"] for trace in fig.data}
    assert subjects == {"A", "B"}
    assert fig.layout.xaxis.title.text == "Block"
    assert fig.layout.yaxis.title.text == "50%"

test_bayes

test_bayes()

Test plotting bayesian representation of psi data.

Source code in tests/test_bayes.py
def test_bayes():
    """Test plotting bayesian representation of psi data."""
    simulated = pd.DataFrame(
        {
            "x": [-4, -2, 0, 2, 4],
            "Hit Rate": [0.01, 0.19, 0.55, 0.81, 0.99],
        },
    )
    index = pd.Index([-4, -2, 0, 2, 4], name="Hit Rate")
    estimated = pd.Series([0.011, 0.2, 0.56, 0.80, 0.98], index=index)
    fig = pa_bayes.plot(simulated, estimated)
    assert fig.layout.xaxis.title.text == "x"
    assert fig.layout.yaxis.title.text == "Hit Rate"

test_data

Test general-purpose data operations.

subjects()

List of subject names.

Source code in tests/test_data.py
@pytest.fixture()
def subjects() -> list[str]:
    """List of subject names."""
    return ["A", "B"]

test_strength_duration

Tests for psychoanalyze.strength_duration module.

s_d_columns()

Columns needed for a strength-duration dataframe.

Source code in tests/test_strength_duration.py
@pytest.fixture()
def s_d_columns() -> set:
    """Columns needed for a strength-duration dataframe."""
    return {"Monkey", "Block", "Dimension"}

test_strength_duration()

Test strength_duration construction.

Source code in tests/test_strength_duration.py
def test_strength_duration() -> None:
    """Test strength_duration construction."""
    df_index = pd.MultiIndex.from_frame(
        pd.DataFrame(
            {"Monkey": [], "Block": [], "Dimension": [], "Fixed Magnitude": []},
        ),
    )
    blocks = pd.DataFrame({"Threshold": [], "Fixed Magnitude": []}, index=df_index)
    s_d = strength_duration.from_blocks(blocks=blocks, dim="Amp")
    assert set(s_d.columns) == {
        "Fixed Pulse Width (μs)",
        "Threshold Amplitude (μA)",
    }

s_d_empty_df()

Empty strength-duration dataframe.

Source code in tests/test_strength_duration.py
@pytest.fixture()
def s_d_empty_df() -> pd.DataFrame:
    """Empty strength-duration dataframe."""
    return pd.DataFrame({"Threshold": [], "Fixed Magnitude": [], "Dimension": []})

test_strength_duration_amp(s_d_columns, s_d_empty_df)

Tests Strength-duration data for amplitude-modulated data.

Source code in tests/test_strength_duration.py
def test_strength_duration_amp(s_d_columns: set, s_d_empty_df: pd.DataFrame) -> None:
    """Tests Strength-duration data for amplitude-modulated data."""
    blocks = s_d_empty_df
    s_d = strength_duration.from_blocks(blocks=blocks, dim="Amp")
    assert set(s_d.columns) <= s_d_columns | {
        "Threshold Amplitude (μA)",
        "Fixed Pulse Width (μs)",
    }

test_strength_duration_pw(s_d_columns, s_d_empty_df)

Test strength-duration calcs for pulse-width-modulated data.

Source code in tests/test_strength_duration.py
def test_strength_duration_pw(s_d_columns: set, s_d_empty_df: pd.DataFrame) -> None:
    """Test strength-duration calcs for pulse-width-modulated data."""
    s_d = strength_duration.from_blocks(
        blocks=s_d_empty_df,
        dim="Width",
    )
    assert set(s_d.columns) <= s_d_columns | {
        "Fixed Amplitude (μA)",
        "Threshold Pulse Width (μs)",
    }

test_plot_with_data()

Test strenght-duration plot with data.

Source code in tests/test_strength_duration.py
def test_plot_with_data():
    """Test strenght-duration plot with data."""
    x_data = [1.0]
    y_data = [1.0]
    fig = strength_duration.plot(
        dim="Width",
        blocks=pd.DataFrame(
            {
                "Dimension": [],
                "Fixed Amplitude (μA)": [],
                "Threshold Pulse Width (μs)": [],
            },
        ),
        x_data=x_data,
        y_data=y_data,
    )
    assert len(fig.data) == 1

test_trials

Tests for psychoanalyze.points module.

subjects()

Subjects.

Source code in tests/test_trials.py
@pytest.fixture()
def subjects() -> list[str]:
    """Subjects."""
    return ["A", "B"]

x()

Intensity values.

Source code in tests/test_trials.py
@pytest.fixture()
def x() -> list[int]:
    """Intensity values."""
    return list(range(8))

test_normalize()

Given a denormalized dataframe, returns normalized data.

Source code in tests/test_trials.py
def test_normalize() -> None:
    """Given a denormalized dataframe, returns normalized data."""
    fields = {
        "Session": ["Monkey", "Block"],
        "Reference Stimulus": ["Amp2", "Width2", "Freq2", "Dur2"],
        "Channel Configuration": ["Active Channels", "Return Channels"],
        "Test Stimulus": ["Amp1", "Width1", "Freq1", "Dur1"],
    }
    data: dict[str, list[Any]] = {
        field: []
        for field in fields["Session"]
        + fields["Reference Stimulus"]
        + fields["Channel Configuration"]
        + fields["Test Stimulus"]
    }
    _trials = pd.DataFrame(data)
    normalized_data = trials.normalize(_trials)
    assert normalized_data.keys() == {
        "Session",
        "Reference Stimulus",
        "Channel Config",
        "Test Stimulus",
    }

test_labels()

Given trial result integers, translates to labels.

Source code in tests/test_trials.py
def test_labels() -> None:
    """Given trial result integers, translates to labels."""
    assert trials.labels([0, 1]) == ["Miss", "Hit"]

test_ecdf