Skip to content

Commit

Permalink
TUnit Templates (#1597)
Browse files Browse the repository at this point in the history
* TUnit Templates

* Fix

* Fix

* Tweak

* Templates

* GetPackageProjectsModule

* EnableSourcyAttribute

* Tweak

* IncludeSource
  • Loading branch information
thomhurst authored Jan 18, 2025
1 parent d700e18 commit 1d50ae4
Show file tree
Hide file tree
Showing 21 changed files with 321 additions and 15 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ TUnit is designed to aid with all testing types:
[![nuget](https://img.shields.io/nuget/v/TUnit.svg)](https://www.nuget.org/packages/TUnit/) [![NuGet Downloads](https://img.shields.io/nuget/dt/TUnit)](https://www.nuget.org/packages/TUnit/)
![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/thomhurst/TUnit/dotnet.yml) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/thomhurst/TUnit/main) ![License](https://img.shields.io/github/license/thomhurst/TUnit)

## Quick Start

Assuming you have the .NET SDK installed, simply run:

`dotnet new install TUnit.Templates`
`dotnet new TUnit -n "YourProjectName"`

A new test project will be created for you with some samples of different test types and tips. When you're ready to get going, delete them and create your own!

## Documentation

See here: <https://thomhurst.github.io/TUnit/>
Expand Down
9 changes: 9 additions & 0 deletions README_Template.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ TUnit is designed to aid with all testing types:
[![nuget](https://img.shields.io/nuget/v/TUnit.svg)](https://www.nuget.org/packages/TUnit/) [![NuGet Downloads](https://img.shields.io/nuget/dt/TUnit)](https://www.nuget.org/packages/TUnit/)
![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/thomhurst/TUnit/dotnet.yml) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/thomhurst/TUnit/main) ![License](https://img.shields.io/github/license/thomhurst/TUnit)

## Quick Start

Assuming you have the .NET SDK installed, simply run:

`dotnet new install TUnit.Templates`
`dotnet new TUnit -n "YourProjectName"`

A new test project will be created for you with some samples of different test types and tips. When you're ready to get going, delete them and create your own!

## Documentation

See here: <https://thomhurst.github.io/TUnit/>
Expand Down
26 changes: 12 additions & 14 deletions TUnit.Pipeline/Modules/GetPackageProjectsModule.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
using ModularPipelines.Context;
using ModularPipelines.Extensions;
using ModularPipelines.Git.Extensions;
using ModularPipelines.Modules;
using File = ModularPipelines.FileSystem.File;

namespace TUnit.Pipeline.Modules;

public class GetPackageProjectsModule : Module<List<File>>
{
protected override Task<List<File>?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
protected override async Task<List<File>?> ExecuteAsync(IPipelineContext context, CancellationToken cancellationToken)
{
return context.Git().RootDirectory
.GetFiles(x => x.Extension == ".csproj")
.Where(x => !x.Name.Contains("Pipeline", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("Analyzer", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("Generator", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("Sample", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("Test", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("Timer", StringComparison.OrdinalIgnoreCase))
.Where(x => !x.Name.Contains("CodeFix", StringComparison.OrdinalIgnoreCase))
.ToList()
.AsTask<List<File>?>();
await Task.CompletedTask;

return
[
Sourcy.DotNet.Projects.TUnit_Assertions,
Sourcy.DotNet.Projects.TUnit_Core,
Sourcy.DotNet.Projects.TUnit_Engine,
Sourcy.DotNet.Projects.TUnit,
Sourcy.DotNet.Projects.TUnit_Playwright,
Sourcy.DotNet.Projects.TUnit_Templates
];
}
}
2 changes: 1 addition & 1 deletion TUnit.Pipeline/Modules/PackTUnitFilesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ await context.DotNet()
new KeyValue("AssemblyFileVersion", version.SemVer!),
new KeyValue("IsPackTarget", "true")
],
IncludeSource = true,
IncludeSource = project == Sourcy.DotNet.Projects.TUnit_Templates ? false : true,
Configuration = Configuration.Release,
}, cancellationToken);

Expand Down
6 changes: 6 additions & 0 deletions TUnit.Pipeline/TUnit.Pipeline.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
<EnableTrimAnalyzer>false</EnableTrimAnalyzer>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<AssemblyAttribute Include="Sourcy.EnableSourcyAttribute">
<_Parameter1>$(MSBuildProjectFullPath)</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
5 changes: 5 additions & 0 deletions TUnit.Templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TUnit.Templates

Some templates to help you get started with TUnit!

For more information, check out the repository at https://www.github.com/thomhurst/TUnit
39 changes: 39 additions & 0 deletions TUnit.Templates/TUnit.Templates.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>TUnit.Templates</PackageId>
<PackageVersion>1.0</PackageVersion>
<Title>TUnit Templates</Title>
<Authors>Tom Longhurst</Authors>
<Description>Templates for getting started with TUnit</Description>
<PackageTags>TUnit,test,testing,unit,integration,acceptance</PackageTags>
<PackageProjectUrl>https://www.github.com/thomhurst/TUnit</PackageProjectUrl>

<PackageType>Template</PackageType>
<TargetFramework>net8.0</TargetFramework>
<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
<NoWarn>$(NoWarn);NU5128</NoWarn>
<NoDefaultExcludes>true</NoDefaultExcludes>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<PropertyGroup>
<LocalizeTemplates>false</LocalizeTemplates>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.TemplateEngine.Tasks" Version="*" PrivateAssets="all" IsImplicitlyDefined="true"/>
</ItemGroup>

<ItemGroup>
<Content Include="content\**\*" Exclude="content\**\bin\**;content\**\obj\**;content\Directory.Build.props;content\Directory.Build.targets;content\Directory.Packages.props" />
<Compile Remove="**\*" />
</ItemGroup>

<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions TUnit.Templates/content/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ItemGroup>
<Using Include="TUnit.Core.HookType" Static="True" />
<Using Include="TUnit.Core" />
</ItemGroup>
</Project>
3 changes: 3 additions & 0 deletions TUnit.Templates/content/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
</Project>
5 changes: 5 additions & 0 deletions TUnit.Templates/content/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>
</Project>
20 changes: 20 additions & 0 deletions TUnit.Templates/content/TUnit/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Tom Longhurst",
"description": "Templates for getting started with TUnit",
"classifications": [
"Test",
"TUnit"
],
"name": "TUnit Test Project",
"identity": "TUnit.Test.Project",
"groupIdentity": "TUnit",
"shortName": "TUnit",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "TestProject",
"preferNameDirectory": true
}

16 changes: 16 additions & 0 deletions TUnit.Templates/content/TUnit/Data/DataClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using TUnit.Core.Interfaces;

namespace TestProject;

public class DataClass : IAsyncInitializer, IAsyncDisposable
{
public Task InitializeAsync()
{
return Console.Out.WriteLineAsync("Classes can be injected into tests, and they can perform some initialisation logic such as starting an in-memory server or a test container.");
}

public async ValueTask DisposeAsync()
{
await Console.Out.WriteLineAsync("And when the class is finished with, we can clean up any resources.");
}
}
11 changes: 11 additions & 0 deletions TUnit.Templates/content/TUnit/Data/DataGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace TestProject.Data;

public class DataGenerator : DataSourceGeneratorAttribute<int, int, int>
{
public override IEnumerable<Func<(int, int, int)>> GenerateDataSources(DataGeneratorMetadata dataGeneratorMetadata)
{
yield return () => (1, 1, 2);
yield return () => (1, 2, 3);
yield return () => (4, 5, 9);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using TUnit.Core.Interfaces;

namespace TestProject;

public class DependencyInjectionClassConstructor : IClassConstructor
{
public T Create<T>(ClassConstructorMetadata classConstructorMetadata) where T : class
{
Console.WriteLine("You can also control how your test classes are new'd up, giving you lots of power and the ability to utilise tools such as dependency injection");

if (typeof(T) == typeof(AndEvenMoreTests))
{
return (new AndEvenMoreTests(new DataClass()) as T)!;
}

throw new NotImplementedException();
}
}
21 changes: 21 additions & 0 deletions TUnit.Templates/content/TUnit/GlobalSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Here you could define global logic that would affect all tests

// You can use attributes at the assembly level to apply to all tests in the assembly
[assembly: Retry(3)]

namespace TestProject;

public class GlobalHooks
{
[Before(TestSession)]
public static void SetUp()
{
Console.WriteLine("Or you can define methods that do stuff before...");
}

[After(TestSession)]
public static void CleanUp()
{
Console.WriteLine("...and after!");
}
}
14 changes: 14 additions & 0 deletions TUnit.Templates/content/TUnit/TestProject.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="TUnit" Version="0.6.121" />
</ItemGroup>

</Project>
65 changes: 65 additions & 0 deletions TUnit.Templates/content/TUnit/Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using TestProject.Data;

namespace TestProject;

public class Tests
{
[Test]
public void Basic()
{
Console.WriteLine("This is a basic test");
}

[Test]
[Arguments(1, 2, 3)]
[Arguments(2, 3, 5)]
public async Task DataDrivenArguments(int a, int b, int c)
{
Console.WriteLine("This one can accept arguments from an attribute");

var result = a + b;

await Assert.That(result).IsEqualTo(c);
}

[Test]
[MethodDataSource(nameof(DataSource))]
public async Task MethodDataSource(int a, int b, int c)
{
Console.WriteLine("This one can accept arguments from a method");

var result = a + b;

await Assert.That(result).IsEqualTo(c);
}

[Test]
[ClassDataSource<DataClass>]
[ClassDataSource<DataClass>(Shared = SharedType.PerClass)]
[ClassDataSource<DataClass>(Shared = SharedType.PerAssembly)]
[ClassDataSource<DataClass>(Shared = SharedType.PerTestSession)]
public void ClassDataSource(DataClass dataClass)
{
Console.WriteLine("This test can accept a class, which can also be pre-initialised before being injected in");

Console.WriteLine("These can also be shared among other tests, or new'd up each time, by using the `Shared` property on the attribute");
}

[Test]
[DataGenerator]
public async Task CustomDataGenerator(int a, int b, int c)
{
Console.WriteLine("You can even define your own custom data generators");

var result = a + b;

await Assert.That(result).IsEqualTo(c);
}

public static IEnumerable<(int a, int b, int c)> DataSource()
{
yield return (1, 1, 2);
yield return (2, 1, 3);
yield return (3, 1, 4);
}
}
28 changes: 28 additions & 0 deletions TUnit.Templates/content/TUnit/Tests2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace TestProject;

[Arguments("Hello")]
[Arguments("World")]
public class MoreTests(string title)
{
[Test]
public void ClassLevelDataRow()
{
Console.WriteLine(title);
Console.WriteLine("Did I forget that data injection works on classes too?");
}

// You can even inject in ClassDataSources as properties to avoid repetitive constructors if you're using inheritance!
[ClassDataSource<DataClass>(Shared = SharedType.PerTestSession)]
public required DataClass DataClass { get; init; }

[Test]
public void Matrices(
[Matrix(1, 2, 3)] int a,
[Matrix(true, false)] bool b,
[Matrix("A", "B", "C")] string c)
{
Console.WriteLine("A new test will be created for each data row, whether it's on the class or method level!");

Console.WriteLine("Oh and this is a matrix test. That means all combinations of inputs are attempted.");
}
}
14 changes: 14 additions & 0 deletions TUnit.Templates/content/TUnit/Tests3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace TestProject;

[ClassDataSource<DataClass>]
[ClassConstructor<DependencyInjectionClassConstructor>]
public class AndEvenMoreTests(DataClass dataClass)
{
[Test]
public void HaveFun()
{
Console.WriteLine(dataClass);
Console.WriteLine("For more information, check out the documentation");
Console.WriteLine("https://thomhurst.github.io/TUnit/");
}
}
Loading

0 comments on commit 1d50ae4

Please sign in to comment.