diff --git a/testsuite/pytests/sli2py_regressions/test_ticket_310.py b/testsuite/pytests/sli2py_regressions/test_ticket_310.py
new file mode 100644
index 0000000000..d6bd5eb74c
--- /dev/null
+++ b/testsuite/pytests/sli2py_regressions/test_ticket_310.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+#
+# test_ticket_310.py
+#
+# This file is part of NEST.
+#
+# Copyright (C) 2004 The NEST Initiative
+#
+# NEST is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# NEST is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NEST. If not, see .
+
+import nest
+import pytest
+
+# Models to skip to do given reasons
+skip_list = [
+ "correlospinmatrix_detector", # not a neuron
+ "eprop_iaf_bsshslm_2020", # no ArchivingNode, thus no t_spike
+ "eprop_iaf_adapt_bsshslm_2020", # no ArchivingNode, thus no t_spike
+ "eprop_readout_bsshslm_2020", # no ArchivingNode, thus no t_spike
+ "eprop_iaf", # no ArchivingNode, thus no t_spike
+ "eprop_iaf_adapt", # no ArchivingNode, thus no t_spike
+ "eprop_iaf_psc_delta", # no ArchivingNode, thus no t_spike
+ "eprop_iaf_psc_delta_adapt", # no ArchivingNode, thus no t_spike
+ "eprop_readout", # no ArchivingNode, thus no t_spike
+ "iaf_chxk_2008", # non-standard spiking conditions
+ "izhikevich", # generating output spike not reliably suppressed even for subthreshold V_m
+]
+
+
+def has_Vm_and_Vth(model):
+ params = nest.GetDefaults(model)
+ return "V_m" in params and "V_th" in params
+
+
+relevant_models = [model for model in nest.node_models if model not in skip_list and has_Vm_and_Vth(model)]
+
+
+@pytest.mark.parametrize("model", relevant_models)
+def test_ticket_310(model):
+ """
+ Regression test for Ticket #310.
+
+ Ensure that all neuron models that have V_m and V_th permit
+ V_m to be set to >= V_th, and that they emit a spike with
+ time stamp == resolution in that case.
+
+ Author: Hans Ekkehard Plesser, 2009-02-11
+ """
+
+ time_resolution = 2**-3 # Use power-of-two resolution to avoid round-off problems
+
+ nest.ResetKernel()
+ nest.resolution = time_resolution
+
+ nrn = nest.Create(model)
+ nrn.V_m = nrn.V_th + 15
+
+ nest.Simulate(time_resolution)
+
+ assert 0 < nrn.t_spike <= time_resolution # for precise neurons, < is possible; -1 if never spiked
diff --git a/testsuite/regressiontests/ticket-310.sli b/testsuite/regressiontests/ticket-310.sli
deleted file mode 100644
index eed11a5b25..0000000000
--- a/testsuite/regressiontests/ticket-310.sli
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * ticket-310.sli
- *
- * This file is part of NEST.
- *
- * Copyright (C) 2004 The NEST Initiative
- *
- * NEST is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * NEST is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NEST. If not, see .
- *
- */
-
-/*
- * Regression test for Ticket #310.
- *
- * Ensure that all neuron models that have V_m and V_th permit
- * V_m to be set to >= V_th, and that they emit a spike with
- * time stamp == resolution in that case.
- *
- * Hans Ekkehard Plesser, 2009-02-11
- *
- */
-
-(unittest) run
-/unittest using
-
-% use power-of-two resolution to avoid roundof problems
-/res -3 dexp def
-
-/skip_list [ /iaf_chxk_2008 % non-standard spiking conditions
- /correlospinmatrix_detector % not a neuron
- /eprop_iaf_bsshslm_2020 % no ArchivingNode, thus no t_spike
- /eprop_iaf_adapt_bsshslm_2020 % no ArchivingNode, thus no t_spike
- /eprop_readout_bsshslm_2020 % no ArchivingNode, thus no t_spike
- /eprop_iaf % no ArchivingNode, thus no t_spike
- /eprop_iaf_adapt % no ArchivingNode, thus no t_spike
- /eprop_iaf_psc_delta % no ArchivingNode, thus no t_spike
- /eprop_iaf_psc_delta_adapt % no ArchivingNode, thus no t_spike
- /eprop_readout % no ArchivingNode, thus no t_spike
- ] def
-
-{
- GetKernelStatus /node_models get
- {
- dup skip_list exch MemberQ not
- {
- /model Set
-
- ResetKernel
- << /resolution res >> SetKernelStatus
- model Create /n Set
-
- % see if we have V_m and V_th, otherwise return true
- n GetStatus 0 get dup /V_m known exch /V_th known and
- {
- n << /V_m n /V_th get 15.0 add >> SetStatus
- res Simulate
- n /t_spike get res leq % works also for precise models
- dup not { (FAILED: ) model cvs join == n ShowStatus } if
- }
- { true }
- ifelse
- }
- { true }
- ifelse
- }
- Map
-
- % see if all entries are true
- true exch { and } Fold
-
-}
-assert_or_die
-
-endusing