Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use the actual pytest runner
  • Loading branch information
filmor committed Dec 8, 2025
commit a38eddcd71375a7478aed1a650c8d15245ab4d8b
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ jobs:
run: pytest --runtime netfx

- name: Python tests run from .NET
# For some reason, it won't find pytest on the Windows + 3.10
# combination, which hints that it does not handle the venv properly in
# this combination.
if: ${{ matrix.os.category != 'windows' || matrix.python != '3.10' }}
run: dotnet test --runtime any-${{ matrix.os.platform }} src/python_tests_runner/
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<FullVersion>$([System.IO.File]::ReadAllText("$(MSBuildThisFileDirectory)version.txt").Trim())</FullVersion>
<VersionPrefix>$(FullVersion.Split('-', 2)[0])</VersionPrefix>
<VersionSuffix Condition="$(FullVersion.Contains('-'))">$(FullVersion.Split('-', 2)[1])</VersionSuffix>
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
Expand Down
8 changes: 8 additions & 0 deletions src/python_tests_runner/Python.PythonTestsRunner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@
</PackageReference>
</ItemGroup>

<Target Name="WriteRepoRootFile" AfterTargets="Build">
<WriteLinesToFile
File="$(OutputPath)tests_location.txt"
Lines="$(RepositoryRoot)/tests"
Overwrite="true"
/>
</Target>

</Project>
47 changes: 15 additions & 32 deletions src/python_tests_runner/PythonTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,29 @@
using NUnit.Framework;

using Python.Runtime;
using Python.Test;

namespace Python.PythonTestsRunner
{
public class PythonTestRunner
{
string OriginalDirectory;

[OneTimeSetUp]
public void SetUp()
{
PythonEngine.Initialize();
OriginalDirectory = Environment.CurrentDirectory;

var codeDir = File.ReadAllText("tests_location.txt").Trim();
TestContext.Progress.WriteLine($"Changing working directory to {codeDir}");
Environment.CurrentDirectory = codeDir;
}

[OneTimeTearDown]
public void Dispose()
{
PythonEngine.Shutdown();
Environment.CurrentDirectory = OriginalDirectory;
}

/// <summary>
Expand All @@ -46,39 +53,15 @@ static IEnumerable<string[]> PythonTestCases()
[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")
using dynamic pytest = Py.Import("pytest");

using var args = new PyList();
args.Append(new PyString($"{testFile}.py::{testName}"));
int res = pytest.main(args);
if (res != 0)
{
folder = Path.GetDirectoryName(folder);
Assert.Fail($"Python test {testFile}.{testName} failed");
}
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}()
");
}
}
}
2 changes: 1 addition & 1 deletion src/runtime/Util/PythonEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private static Dictionary<string, string> TryParse(string venvCfg)

private static string ProgramNameFromPath(string path)
{
if (Runtime.IsWindows)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Path.Combine(path, "Scripts", "python.exe");
}
Expand Down