◐ Shell
clean mode source ↗

Python tests can now be debugged by running them as embedded tests within NUnit by tminka · Pull Request #1341 · pythonnet/pythonnet

@@ -0,0 +1,82 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text;
using NUnit.Framework;
using Python.Runtime;
namespace Python.PythonTestsRunner { public class PythonTestRunner { [OneTimeSetUp] public void SetUp() { PythonEngine.Initialize(); }
[OneTimeTearDown] public void Dispose() { PythonEngine.Shutdown(); }
/// <summary> /// Selects the Python tests to be run as embedded tests. /// </summary> /// <returns></returns> static IEnumerable<string[]> PythonTestCases() { // Add the test that you want to debug here. yield return new[] { "test_enum", "test_enum_standard_attrs" }; yield return new[] { "test_generic", "test_missing_generic_type" }; }
Comment thread

tminka marked this conversation as resolved.


/// <summary> /// Runs a test in src/tests/*.py as an embedded test. This facilitates debugging. /// </summary> /// <param name="testFile">The file name without extension</param> /// <param name="testName">The name of the test method</param> [TestCaseSource(nameof(PythonTestCases))] public void RunPythonTest(string testFile, string testName) { // Find the tests directory string folder = typeof(PythonTestRunner).Assembly.Location; while (Path.GetFileName(folder) != "src") { folder = Path.GetDirectoryName(folder); } folder = Path.Combine(folder, "tests"); string path = Path.Combine(folder, testFile + ".py"); if (!File.Exists(path)) throw new FileNotFoundException("Cannot find test file", path);
// We could use 'import' below, but importlib gives more helpful error messages than 'import' // https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly // Because the Python tests sometimes have relative imports, the module name must be inside the tests package PythonEngine.Exec($@" import sys import os sys.path.append(os.path.dirname(r'{folder}')) sys.path.append(os.path.join(r'{folder}', 'fixtures')) import clr clr.AddReference('Python.Test') import tests module_name = 'tests.{testFile}' file_path = r'{path}' import importlib.util spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module try: spec.loader.exec_module(module) except ImportError as error: raise ImportError(str(error) + ' when sys.path=' + os.pathsep.join(sys.path)) module.{testName}() "); } } }