Skip to content

Testing

Rui Marinho edited this page Sep 21, 2023 · 5 revisions

Tools

Framework

  • XUnit is used in most of the projects any new test projects created should utilize XUnit.
  • NUnit is used in some legacy projects, we tend to migrate all tests to run under XUnit so any new test projects created should utilize XUnit.
  • xharness is a dotnet tool and TestRunner library that makes running unit tests in mobile platforms easier.

Project Test Types

  • Unit tests - These are tests that will not run on a device. This is useful for testing device independent logic.
├── Controls 
│   ├── test
│   │   ├── Controls.Core.UnitTests
│   │   ├── Controls.Core.XamlUnitTests
├── Core 
│   ├── test
│   │   ├── Core.UnitTests
├── Essentials 
│   ├── test
│   │   ├── Essentials.UnitTests
├── Graphics
│   ├── test
│   │   ├── Graphics.Tests
├── SingleProject
│   ├── test
│   │   ├── Resizetizer.UnitTests
  • Device tests - These are tests that will run on an actual device or simulator
├── Controls 
│   ├── test
│   │   ├── Controls.DeviceTests
├── Core 
│   ├── test
│   │   ├── Core.DeviceTests
├── Essentials 
│   ├── test
│   │   ├── Essentials.DeviceTests
├── Graphics
│   ├── test
│   │   ├── Graphics.DeviceTests
├── BlazorWebView 
│   ├── test
│   │   ├── MauiBlazorWebView.DeviceTests
  • UI tests - These are tests that will run on an actual device or simulator and interact with an application
├── Controls 
│   ├── test
│   │   ├── Controls.AppiumTests
  • Controls.UITests: .NET MAUI Controls Visual Runner for running device based xunit tests. This is useful for tests that require XAML features

Test count

25/01/2022 20/09/2023
Controls.Core.UnitTests 4670 5498
Controls.Core.XamlUnitTests 989 1037
Controls.DeviceTests.ios 198 257
Controls.DeviceTests.android 214 305
Controls.DeviceTests.maccatalyst 199 212
Controls.DeviceTests.windows 230 0
Controls.UITests.ios 0 38
Controls.UITests.android 0 38
Controls.UITests.maccatalyst 0 28
Controls.UITests.windows 0 25
Core.UnitTests 475 655
Core.DeviceTests.ios 2782 1034
Core.DeviceTests.android 599 1193
Core.DeviceTests.maccatalyst 592 956
Core.DeviceTests.windows 440 810
Essentials.UnitTests 989 283
Essentials.DeviceTests.ios 280 120
Essentials.DeviceTests.android 278 134
Essentials.DeviceTests.maccatalyst 280 123
Essentials.DeviceTests.windows 287 133
MauiBlazorWebView.DeviceTests 1 0
MauiBlazorWebView.DeviceTests.ios 0 3
MauiBlazorWebView.DeviceTests.android 0 3
MauiBlazorWebView.DeviceTests.maccatalyst 0 3
MauiBlazorWebView.DeviceTests.windows 0 3
Graphics.UnitTests 84 316
Graphics.DeviceTests 3 0
Graphics.DeviceTests.ios 0 8
Graphics.DeviceTests.android 0 8
Graphics.DeviceTests.maccatalyst 0 8
Graphics.DeviceTests.windows 0 8
Resizetizer.UnitTests 0 543
Integration.UnitTests 0 36
Total 13572 16661

Running Tests

We use xunit.runner.visualstudio and nunittestadapter for test discoverability and running the tests. This allows us to view the tests from within Visual Studio via the Test Explorer tool pane and utilizing vstest.console.exe <AssemblyPath> from a developer command prompt.

Writing tests

Controls unit tests

The tests on this project are written using XUnit. Add your class and use BaseTestFixture as your base class. You can also add a [Category("Layout")] . You might need to create a Stub for your test you can add that to the TestClasses folder


public class CarouselViewTests : BaseTestFixture
{
	[Fact]
	public void TestPositionChangedCommand()
	{
		var source = new List<string> { "1", "2", "3" };
		var carouselView = new CarouselView
		{
			ItemsSource = source
		};
		int countFired = 0;
		carouselView.PositionChangedCommand = new Command(() => countFired = countFired + 1;);
		Assert.Same(source, carouselView.ItemsSource);
		carouselView.Position = 1;
		Assert.True(countFired == 1);
	}
}

Xaml unit tests

The tests on this project are written using NUnit. To create a new test start by adding a new Xaml ContentPage to the Controls.Core.XamlUnitTests project. In the code behind add your NUnit TestFixture. Make sure to specify a 2nd actor for two TestCase for True/False so that the test runs with and without XAMLC enabled. Also take note that the default actor will not be called 50% of the times.

<ContentPage 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.AutoMergedResourceDictionaries">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="notpink">Purple</Color>
            <Color x:Key="pink">Pink</Color>
            <ResourceDictionary Source="AppResources/Colors.xaml" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <Label x:Name="label" TextColor="{StaticResource notpink}" BackgroundColor="{StaticResource Primary}"/>
</ContentPage>

public partial class AutoMergedResourceDictionaries : ContentPage
{
	public AutoMergedResourceDictionaries()
	{
		InitializeComponent();
	}

	public AutoMergedResourceDictionaries(bool useCompiledXaml)
	{
		//this stub will be replaced at compile time
	}

	[TestFixture]
	public class Tests
	{
		[TestCase(false)]
		[TestCase(true)]
		public void AutoMergedRd(bool useCompiledXaml)
		{
			var layout = new AutoMergedResourceDictionaries(useCompiledXaml);
			Assert.That(layout.label.TextColor, Is.EqualTo(Colors.Purple));
			Assert.That(layout.label.BackgroundColor, Is.EqualTo(Color.FromArgb("#FF96F3")));
		}
	}
}
Clone this wiki locally