Can't test PCL test assembly from Xamarin.Android.NUnitLite or MonoTouch.NUnit.UI

JamesOttawayJamesOttaway USMember

I have a PCL which contains the core logic for my Xamarin app, called Foo.Core, and I have a PCL which contains the tests for Foo.Core, called Foo.Core.Test.Portable.

I am trying to create an Android Unit Test Project, and an iOS Unit Test Project, called Foo.Core.Test.Android and Foo.Core.Test.iOS respectively.

I was going to add a reference to Foo.Core.Test.Portable in the platform-specific unit test projects, and change the calls to this.AddTest(Assembly.GetExecutingAssembly()); and runner.Add(Assembly.GetExecutingAssembly()); (in MainActivity.OnCreate(Bundle) and UnitTestAppDelegate.FinishedLaunching(UIApplication,NSDictionary) respectively) to use the Foo.Core.Test.Portable asssembly.

When I tried to run the tests, the Application Output pad in Xamarin Studio shows Tests run: 0, Passed: 0, Failed: 0, Skipped: 0, Inconclusive: 0 when I hit the 'Run Tests' button.

I've been unable to find an example which follows the idea I'm trying to get working. Even the xamarin/web-tests repo on GitHub uses file linking in the platform-specific test projects to include the test fixtures, rather than adding a reference to the shared tests and passing the assembly.

My understanding is that Xamarin.Android.NUnitLite and MonoTouch.NUnit.UI wrap NUnitLite under the hood, and it looks like NUnitLiteTestAssemblyBuilder happily accepts external assemblies which it loads test fixtures from.

Is there something I'm missing, or is the interface of Xamarin.Android.NUnitLite.TestSuiteActivity and MonoTouch.NUnit.UI.TouchRunner just confusing?

Posts

  • Il.SocioIl.Socio USMember

    Hi James, did you found any solution?
    I'm experiencing the same issue :(

  • JamesOttawayJamesOttaway USMember

    Sorry mate, no luck yet.

    I've resorted to linking the test files between the test projects, but I'd still love to find a solution.

    Thanks for bumping the post up. Hopefully it gets some more attention now.

  • BjornEgilHansenBjornEgilHansen NODeveloper Group Leader

    I have the same problem - any solution to this yet?

  • AtsushiEnomotoAtsushiEnomoto JPMember, Xamarin Team Xamurai

    You could try calling AddTest() with the exact test assembly as the argument, instead of Assembly.GetExecutingAssembly(). I don't think the executing assembly is the test assembly you want to test.

    From the mentioned NUnitLiteTestAssemblyBuilder source, it's not clear to me that NUnitLite build as Xamarin.iOS or Xamarin.Android assembly can also looks for "[TestFixture] and [Test] attribute types from the PCL NUnitLite assembly" as the expecting types (which I believe are [TestFixture] and [Test] from XiOS/XA assemby). If the PCL is implemented the way that it contains platform-specific packages that forward some types, then unless NUnitLite PCL package itself doesn't support XiOS and XA, we cannot do anything special.

  • SebBartholomewSebBartholomew USMember ✭✭
    edited July 2015

    I have also run into this issue. Atsushi is right and this is what I found when I also investigated the source code.

    The Assemblies change between platforms:
    Xamarin.iOS uses MonoTouch.NUnitLite
    Xamarin.Android uses Xamarin.Android.NUnitLite
    and (for sake of demonstation) my PCL used the base NUnit nuget package.

    These three assemblies share the same namespaces for these attributes, but strictly are different types. So the NUnitLite library will not accept the attributes declared using a different library.

    TestFixture and Test attributes specified in my PCL, although in the same namespace, would have to be created using the correct assembly for the platform, which means starting to use compiler flags everywhere - which should not be necessary with PCL.

    I tried to be clever and started looking using Reflection (specifically System.Reflection.Emit) to dynamically create correctly decorated (ie. TestFixture attributes created within correct to platform) methods from methods specified in my PCL. Xamarin.Android would support this (I think) - Problem is Xamarin.iOS does not support this.

    Solution:
    Not ideal but appears to be working - I modified the PCL Project's file (.csproj) to determine which assembly to reference based on build configuration and platform, saved to a build variable called "TestLibraryPath".
    This path is then passed in as the hint path for a reference I've called NUnitLite instead of the previous NUnit library i was referencing.

    PCL Project:
    <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> ... <PropertyGroup> <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> ... <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> <RestorePackages>true</RestorePackages> <TestLibraryPath>..\lib\!REPLACE_WITH_PLATFORM_LIB!.dll</TestLibraryPath> </PropertyGroup> ... <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> <TestLibraryPath>..\lib\Xamarin.Android.NUnitLite.dll</TestLibraryPath> </PropertyGroup> <PropertyGroup Condition=" '$(Platform)' == 'iPhoneSimulator' "> <TestLibraryPath>..\lib\MonoTouch.NUnitLite.dll</TestLibraryPath> </PropertyGroup> <PropertyGroup Condition=" '$(Platform)' == 'iPhone' "> <TestLibraryPath>..\lib\MonoTouch.NUnitLite.dll</TestLibraryPath> </PropertyGroup> ... <ItemGroup> <Reference Include="NUnitLite"> <HintPath>$(TestLibraryPath)</HintPath> </Reference> </ItemGroup> ... </Project>

    Credit and thanks to:

    http://mikaelkoskinen.net/changing-project-s-references-based-on-the-build-configuration
    http://stackoverflow.com/questions/533554/how-to-use-different-files-in-a-project-for-different-build-configurations-vis

Sign In or Register to comment.