using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using UnitTestSharp; namespace TestsForUnitTestSharp { /// /// Tests the test runner functions /// public class TestRunnerTests : TestFixture { public void Hidden() { var output = TestRunner.NotifyUserOfHiddenTests(new[] { GetType().GetMethod("Hidden") }); CheckEqualRegex("Hidden", output); } public void NotifyUserOfFinalStatus_Success() { var actual = TestRunner.NotifyUserOfFinalStatus(0, 0, 1); CheckEqualRegex("Success: 1 tests pass", actual); } public void NotifyUserOfFinalStatus_Failure() { var actual = TestRunner.NotifyUserOfFinalStatus(1, 1, 1); CheckEqualRegex("FAILURE", actual); } public void NotifyUserOfFinalStatus_FailedChecks() { var actual = TestRunner.NotifyUserOfFinalStatus(0, 1, 1); CheckEqualRegex("FAILURE", actual); } public void NotifyUserOfFinalStatus_FailedTests() { var actual = TestRunner.NotifyUserOfFinalStatus(1, 0, 1); CheckEqualRegex("FAILURE", actual); } public void NotifyUserOfFinalStatus_MoreFailedThanTests() { CheckThrow(); var actual = TestRunner.NotifyUserOfFinalStatus(2, 1, 1); } public class BasicTests : TestFixture { [IgnoreFixture] class FauxFixture : TestFixture { public void Test() { } void HiddenTest() { } [IgnoreTest] void IgnoredTest() { } } public void ExtractMethodsToRun_Test() { int ignored, hidden; IList testsToRun; string outputExpected = BuildMessages.MSBuildMessage( "Method is non public. Did you forget " + "to mark it public? If you don't want the method tested, " + "mark it with the IgnoreMethod attribute.", "TestsForUnitTestSharp::TestRunnerTests.BasicTests.FauxFixture::HiddenTest", false, null, null ) + "\n"; string outputActual = ""; FauxFixture fixture = new FauxFixture(); TestRunner.ExtractMethodsToRun( fixture, (outputString) => outputActual += outputString, out testsToRun, out ignored, out hidden); CheckEqual(1, ignored); CheckEqual(1, hidden); CheckEqual(1, testsToRun.Count); CheckEqual(outputExpected, outputActual); } [IgnoreFixture] class OverriddenFindTestMethods : TestFixture { public override IList FindTestableMethods(ref int ignored) { return new List() { typeof(OverriddenFindTestMethods).GetMethod("Test") }; } [IgnoreTest] private void Test() { } } public void ExtractMethodsToRun_OverriddenFindTestableMethods() { int ignored, hidden; IList testsToRun; string outputActual = ""; TestRunner.ExtractMethodsToRun(new OverriddenFindTestMethods(), (outputString) => outputActual += outputString, out testsToRun, out ignored, out hidden); CheckEqual(1, ignored); CheckEqual(0, hidden); CheckEqual(new List {typeof(OverriddenFindTestMethods).GetMethod("Test")}, testsToRun); } [IgnoreFixture] class OverriddenCheckPrivateMethods : TestFixture { public override void CheckPrivateMethods(ref List missingIgnoreAttr, ref int ignored) { } [IgnoreTest] private void Test() { } } public void ExtractMethodsToRun_OverriddenCheckPrivateMethods() { int ignored, hidden; IList testsToRun; string outputActual = ""; TestRunner.ExtractMethodsToRun(new OverriddenCheckPrivateMethods(), (outputString) => outputActual += outputString, out testsToRun, out ignored, out hidden); CheckEqual(0, ignored); CheckEqual(0, hidden); CheckEqual(new List {}, testsToRun); } } public class CanCount : TestFixture { [IgnoreFixture] class FauxFixture : TestFixture { public void Test1() { } public void Test2() { Check(false); Check(false); } public void Test3() { Check(false); } } public void CanCountTest() { string output = ""; int totalTests = 0; int failedTests = 0; int failedChecks = 0; TestRunner.RunTestFixture(typeof(FauxFixture), (outputString) => output += outputString, ref totalTests, ref failedTests, ref failedChecks); CheckEqual(3, totalTests); CheckEqual(2, failedTests); CheckEqual(3, failedChecks); } } public class RunTestFixtureTests : UnitTestSharp.TestFixture { private static int ThrowException() { throw new System.Exception(""); } [IgnoreFixture] public class BadFixture : UnitTestSharp.TestFixture { int x = ThrowException(); } public void ThrowsAnException() { string output = ""; int totalTests = 0, failedTests = 0, failedChecks = 0; TestRunner.RunTestFixture(typeof(BadFixture), (outputString) => output += outputString, ref totalTests, ref failedTests, ref failedChecks); CheckEqualRegex("Failure creating test fixture", output); } } public class ParameterizedFromDerived : UnitTestSharp.TestFixture { [IgnoreFixture] public class InternalTestBase : UnitTestSharp.TestFixture { [Parameterized("TestData")] public void Test(int value) { CheckEqual(2, value); } } [IgnoreFixture] public class InternalTestDerivedStatic : InternalTestBase { public static dynamic[] TestData = new dynamic[] { 1, 2, 3}; } [IgnoreFixture] public class InternalTestDerivedInstance : InternalTestBase { public dynamic[] TestData = new dynamic[] { 1, 2, 3 }; } public void SourceIsFromDerivedStatic() { string output = ""; int totalTests = 0, failedTests = 0, failedChecks = 0; TestRunner.RunTestFixture(typeof(InternalTestDerivedStatic), (outputString) => output += outputString, ref totalTests, ref failedTests, ref failedChecks); CheckEqual(3, totalTests); CheckEqual(2, failedTests); CheckEqual(2, failedChecks); CheckEqualRegex( "TestsForUnitTestSharp::TestRunnerTests.ParameterizedFromDerived.InternalTestDerivedStatic", output); } public void SourceIsFromDerivedInstance() { string output = ""; int totalTests = 0, failedTests = 0, failedChecks = 0; TestRunner.RunTestFixture(typeof(InternalTestDerivedInstance), (outputString) => output += outputString, ref totalTests, ref failedTests, ref failedChecks); CheckEqual(3, totalTests); CheckEqual(2, failedTests); CheckEqual(2, failedChecks); CheckEqualRegex( "TestsForUnitTestSharp::TestRunnerTests.ParameterizedFromDerived.InternalTestDerivedInstance", output); } } public class PreloadReferencedAssembliesTests : TestFixture { public void LoadsReferencesOfReferences() { TestRunner.PreloadReferencedAssemblies(); var loaded = new HashSet( AppDomain.CurrentDomain.GetAssemblies().Select(assembly => assembly.FullName)); // Two levels is enough to pin down the part that matters: a reference of a reference is exactly what // the CLR would otherwise have faulted in lazily, in the middle of whichever test touched it first. foreach (AssemblyName direct in Assembly.GetEntryAssembly().GetReferencedAssemblies()) { CheckTrue(loaded.Contains(direct.FullName)); foreach (AssemblyName indirect in Assembly.Load(direct).GetReferencedAssemblies()) { CheckTrue(loaded.Contains(indirect.FullName)); } } } } public class TestSetupFailureTests : TestFixture { [IgnoreFixture] public class Testee : TestFixture { public override void TestSetup() { CheckEqual("setup-expected", "setup-actual"); } public void Test() { CheckEqual("body-expected", "body-actual"); } } /// /// A failure in TestSetup is a separate fact from a failure in the test body; losing either one /// looks, from the log, exactly like that check never ran at all. /// public void SetupFailure_StillAppearsAlongsideABodyFailure() { string output = ""; int failedChecks = 0; TestRunner.RunTest(new Testee(), typeof(Testee).GetMethod("Test"), null, 0, (outputString) => output += outputString, ref failedChecks); CheckEqualRegex("setup-expected", output); CheckEqualRegex("body-expected", output); } [IgnoreFixture] public class AllocationTestee : TestFixture { public override void TestSetup() { CheckEqual("setup-expected", "setup-actual"); } [AllocationTest] public void Test() { CheckNoAllocations(); } } /// /// Nothing resets the log mid-test anymore, so this survives for an [AllocationTest] too - not /// just a plain test - even though the failure itself aborts warmup almost immediately after. /// public void SetupFailure_AlsoSurvivesForAnAllocationTest() { string output = ""; int failedChecks = 0; TestRunner.RunTest(new AllocationTestee(), typeof(AllocationTestee).GetMethod("Test"), null, 0, (outputString) => output += outputString, ref failedChecks); CheckEqualRegex("setup-expected", output); } } public class ExceptionInsideFixtureSetup : TestFixture { [IgnoreFixture] public class Testee : TestFixture { public override void FixtureSetup() { throw new System.Exception(); } } public void DoesNotIncludeTestRunnerInStackTrace() { string output = ""; int totalTests = 0, failedTests = 0, failedChecks = 0; TestRunner.RunTestFixture(typeof(Testee), (outputString) => output += outputString, ref totalTests, ref failedTests, ref failedChecks); CheckEqual(0, output.Count(c => c.Equals('\n'))); } } public class CpuTimeoutForTests : UnitTestSharp.TestFixture { [IgnoreTest] [CpuTimeout(1234)] public void Annotated() { } [IgnoreTest] public void NotAnnotated() { } public void Annotated_ReturnsAttributeValue() { CheckEqual(1234, TestRunner.CpuTimeoutFor(GetType().GetMethod("Annotated"))); } public void NotAnnotated_ReturnsDefault() { CheckEqual(TestRunner.TestCpuTimeoutInMilliseconds, TestRunner.CpuTimeoutFor(GetType().GetMethod("NotAnnotated"))); } public void NullMethod_ReturnsDefault() { CheckEqual(TestRunner.TestCpuTimeoutInMilliseconds, TestRunner.CpuTimeoutFor(null)); } } public class FindBinderReferenceTests : UnitTestSharp.TestFixture { public void AssemblyUsingDynamic_FindsTheReference() { CheckEqual("Microsoft.CSharp", TestRunner.FindBinderReference(Assembly.GetEntryAssembly()).Name); } public void AssemblyWithoutDynamic_ReturnsNull() { CheckNull(TestRunner.FindBinderReference(typeof(TestRunner).Assembly)); } } public class WarmUpDynamicBinderTests : UnitTestSharp.TestFixture { public void SuiteUsingDynamic_WarmsTheBinder() { CheckTrue(TestRunner.WarmUpDynamicBinder()); } public void RepeatedCalls_StayHarmless() { CheckTrue(TestRunner.WarmUpDynamicBinder()); CheckTrue(TestRunner.WarmUpDynamicBinder()); } } public class AnyTestIsParameterizedTests : UnitTestSharp.TestFixture { public class ParameterizedSubject { static dynamic[] data = new[] { new { x = 1 } }; [Parameterized("data")] public void Test(dynamic row) { } } public class DerivedSubject : ParameterizedSubject { } public class PlainSubject { public void Test() { } } public class HiddenSubject { static dynamic[] data = new[] { new { x = 1 } }; [Parameterized("data")] private void Test(dynamic row) { } } public class StaticSubject { static dynamic[] data = new[] { new { x = 1 } }; [Parameterized("data")] public static void Test(dynamic row) { } } public void NoTypes_ReturnsFalse() { CheckFalse(TestRunner.AnyTestIsParameterized(new Type[0])); } public void OnlyPlainTests_ReturnsFalse() { CheckFalse(TestRunner.AnyTestIsParameterized(new[] { typeof(PlainSubject) })); } public void OneParameterizedTestAmongPlainOnes_ReturnsTrue() { CheckTrue(TestRunner.AnyTestIsParameterized( new[] { typeof(PlainSubject), typeof(ParameterizedSubject) })); } public void InheritedParameterizedTest_ReturnsTrue() { CheckTrue(TestRunner.AnyTestIsParameterized(new[] { typeof(DerivedSubject) })); } public void NonPublicParameterizedTest_ReturnsFalse() { CheckFalse(TestRunner.AnyTestIsParameterized(new[] { typeof(HiddenSubject) })); } public void StaticParameterizedTest_ReturnsFalse() { CheckFalse(TestRunner.AnyTestIsParameterized(new[] { typeof(StaticSubject) })); } } public class RuntimeBinderFactoryTests : UnitTestSharp.TestFixture { public static TestRunner.RuntimeBinderFactory Loaded() { return TestRunner.RuntimeBinderFactory.Load( Assembly.Load(TestRunner.FindBinderReference(Assembly.GetEntryAssembly()))); } public class LoadTests : UnitTestSharp.TestFixture { public void BinderAssembly_ReturnsAFactory() { CheckNotNull(Loaded()); } public void AssemblyWithoutTheBinderTypes_ReturnsNull() { CheckNull(TestRunner.RuntimeBinderFactory.Load(typeof(TestRunner).Assembly)); } } public class GetMemberTests : UnitTestSharp.TestFixture { public void NamesAMember_ReadsIt() { var site = CallSite>.Create(Loaded().GetMember("Length")); CheckEqual(4, site.Target(site, "warm")); } } public class BinaryOperationTests : UnitTestSharp.TestFixture { public void Equal_ComparesBothOperands() { var site = CallSite>.Create( Loaded().BinaryOperation(ExpressionType.Equal)); CheckEqual(true, site.Target(site, 1, 1)); CheckEqual(false, site.Target(site, 1, 2)); } } public class ConvertTests : UnitTestSharp.TestFixture { public void Boolean_CastsToTheTargetType() { var site = CallSite>.Create(Loaded().Convert(typeof(bool))); CheckTrue(site.Target(site, true)); CheckFalse(site.Target(site, false)); } } public class InvokeMemberTests : UnitTestSharp.TestFixture { public void NamesAMethod_CallsItWithTheArgument() { var site = CallSite>.Create( Loaded().InvokeMember("Equals")); CheckEqual(true, site.Target(site, "warm", "warm")); CheckEqual(false, site.Target(site, "warm", "cold")); } } } } }