Run all the tests together when running dotnet test

Use custom PHPUnit extension to report their results.
This commit is contained in:
Robert Husák 2020-09-02 15:02:19 +02:00
Родитель 589a2e0847
Коммит 7b6f7d3f47
5 изменённых файлов: 104 добавлений и 6 удалений

Просмотреть файл

@ -19,7 +19,7 @@ namespace Peachpied.PhpUnit.TestAdapter
Context.AddScriptReference(typeof(TestCase).Assembly);
}
public static void Launch(string cwd, string testedAssembly, params string[] args)
public static void Launch(string cwd, string testedAssembly, string[] args, Action<Context> ctxPreparer = null)
{
// Load assembly with tests (if not loaded yet)
Context.AddScriptReference(Assembly.LoadFrom(testedAssembly));
@ -32,6 +32,9 @@ namespace Peachpied.PhpUnit.TestAdapter
// (there is the condition for execution __FILE__ === realpath($_SERVER['SCRIPT_NAME']) in PHPUnit PHAR entry file)
ctx.Server[CommonPhpArrayKeys.SCRIPT_NAME] = "__DUMMY_INVALID_FILE";
// Perform any custom operations on the context
ctxPreparer?.Invoke(ctx);
// Run the PHAR entry point so that all the classes are included
var pharLoader = Context.TryGetDeclaredScript(PharName);
RunScript(ctx, () => pharLoader.Evaluate(ctx, PhpArray.NewEmpty(), null).ToInt());
@ -59,6 +62,9 @@ namespace Peachpied.PhpUnit.TestAdapter
}
}
public static string GetTestNameFromPhp(string fullTestName) =>
fullTestName.Replace('\\', '.').Replace("::", ".");
public static string GetTestNameFromPhp(string className, string methodName) =>
className.Replace('\\', '.') + "." + methodName;
}

Просмотреть файл

@ -36,7 +36,7 @@ namespace Peachpied.PhpUnit.TestAdapter
{
string projectDir = EnvironmentHelper.TryFindProjectDirectory(Path.GetDirectoryName(source));
tempTestsXml = Path.GetTempFileName();
PhpUnitHelper.Launch(projectDir, source, "--teamcity", "--list-tests-xml", tempTestsXml); // TODO: Remove --teamcity switch when it no longer causes crash
PhpUnitHelper.Launch(projectDir, source, new[] { "--teamcity", "--list-tests-xml", tempTestsXml }); // TODO: Remove --teamcity switch when it no longer causes crash
ProcessTestsXml(source, tempTestsXml, discoverySink);

Просмотреть файл

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
namespace Peachpied.PhpUnit.TestAdapter
{
@ -16,10 +18,26 @@ namespace Peachpied.PhpUnit.TestAdapter
public void RunTests(IEnumerable<string> sources, IRunContext runContext, IFrameworkHandle frameworkHandle)
{
var ctx = new PhpUnitContext(sources);
var tests = ctx.FindTestCases();
foreach (var source in sources)
{
try
{
string projectDir = EnvironmentHelper.TryFindProjectDirectory(Path.GetDirectoryName(source));
ctx.RunTests(tests, frameworkHandle);
PhpUnitHelper.Launch(projectDir, source, new[] { "--teamcity", "--extensions", TestReporterExtension.PhpName },
ctx =>
{
ctx.DeclareType<TestReporterExtension>();
var testRunCtx = new TestRunContext(source, frameworkHandle);
ctx.SetProperty(testRunCtx);
});
}
catch (Exception e)
{
frameworkHandle.SendMessage(TestMessageLevel.Error, e.Message + "\n" + e.StackTrace);
}
}
}
public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle)

Просмотреть файл

@ -0,0 +1,54 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Pchp.Core;
using Pchp.Core.Reflection;
using PHPUnit.Runner;
using System;
using System.Collections.Generic;
using System.Text;
namespace Peachpied.PhpUnit.TestAdapter
{
internal class TestReporterExtension : BeforeTestHook, AfterSuccessfulTestHook, AfterTestErrorHook, AfterTestFailureHook, AfterSkippedTestHook
{
public readonly static string PhpName = typeof(TestReporterExtension).GetPhpTypeInfo().Name;
private TestRunContext _testRunContext;
public TestReporterExtension(Context ctx)
{
_testRunContext = ctx.TryGetProperty<TestRunContext>() ?? throw new InvalidOperationException();
}
public void executeBeforeTest([NotNull] string test) =>
_testRunContext.FrameworkHandle.RecordStart(GetTestCase(test));
public void executeAfterSuccessfulTest([NotNull] string test, double time) =>
ReportOutcome(test, TestOutcome.Passed);
public void executeAfterTestError([NotNull] string test, [NotNull] string message, double time) =>
ReportOutcome(test, TestOutcome.Failed);
public void executeAfterTestFailure([NotNull] string test, [NotNull] string message, double time) =>
ReportOutcome(test, TestOutcome.Failed);
public void executeAfterSkippedTest([NotNull] string test, [NotNull] string message, double time) =>
ReportOutcome(test, TestOutcome.Skipped);
private void ReportOutcome(string phpTestName, TestOutcome outcome)
{
var testCase = GetTestCase(phpTestName);
var testResult = new TestResult(testCase)
{
Outcome = outcome
};
_testRunContext.FrameworkHandle.RecordResult(testResult);
}
private TestCase GetTestCase(string phpTestName)
{
string vsTestName = PhpUnitHelper.GetTestNameFromPhp(phpTestName);
return new TestCase(vsTestName, PhpUnitTestExecutor.ExecutorUri, _testRunContext.Source);
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using System;
using System.Collections.Generic;
using System.Text;
namespace Peachpied.PhpUnit.TestAdapter
{
internal class TestRunContext
{
public string Source { get; }
public IFrameworkHandle FrameworkHandle { get; }
public TestRunContext(string source, IFrameworkHandle frameworkHandle)
{
this.Source = source;
this.FrameworkHandle = frameworkHandle;
}
}
}