diff --git a/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj b/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj
new file mode 100644
index 0000000..69e0137
--- /dev/null
+++ b/Ductus.FluentDocker.XUnit/Ductus.FluentDocker.XUnit.csproj
@@ -0,0 +1,31 @@
+
+
+ netstandard1.6;net461
+ 1.0.0
+ 1.0.0.0
+ 1.0.0.0
+ $(VersionSuffix)
+ false
+ Ductus.FluentDocker.XUnit
+ Mario Toffia
+ Apache-2.0
+ https://github.com/mariotoffia/FluentDocker
+ https://pbs.twimg.com/profile_images/378800000124779041/fbbb494a7eef5f9278c6967b6072ca3e.png
+ Ductus.FluentDocker.XUnit
+ false
+ Docker;Docker-Compose;Docker Compose;Docker-Machine;Docker Machine;Linux;Windows;Mac;Test;NET Core
+ git
+ https://github.com/mariotoffia/FluentDocker
+
+ XUnit Support to allow for create, run one or more docker images while testing using docker, compose, machine (Linux, Windows, Mac) using netcore or full framework.
+ Documentation: https://github.com/mariotoffia/FluentDocker
+
+ © 2016 - 2021 Mario Toffia
+ ..\keypair.snk
+ true
+ true
+
+
+
+
+
diff --git a/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs b/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs
new file mode 100644
index 0000000..543585e
--- /dev/null
+++ b/Ductus.FluentDocker.XUnit/FluentDockerTestBase.cs
@@ -0,0 +1,59 @@
+using System;
+using Ductus.FluentDocker.Builders;
+using Ductus.FluentDocker.Services;
+
+namespace Ductus.FluentDocker.XUnit
+{
+ public abstract class FluentDockerTestBase : IDisposable
+ {
+ protected IContainerService Container;
+
+ protected abstract ContainerBuilder Build();
+
+ public FluentDockerTestBase()
+ {
+ Container = Build().Build();
+ try
+ {
+ Container.Start();
+ }
+ catch
+ {
+ Container.Dispose();
+ throw;
+ }
+
+ OnContainerInitialized();
+ }
+
+ public void Dispose()
+ {
+ OnContainerTearDown();
+
+ var c = Container;
+ Container = null;
+ try
+ {
+ c?.Dispose();
+ }
+ catch
+ {
+ // Ignore
+ }
+ }
+
+ ///
+ /// Invoked just before the container is teared down.
+ ///
+ protected virtual void OnContainerTearDown()
+ {
+ }
+
+ ///
+ /// Invoked after a container has been created and started.
+ ///
+ protected virtual void OnContainerInitialized()
+ {
+ }
+ }
+}
diff --git a/Ductus.FluentDocker.XUnit/PostgresTestBase.cs b/Ductus.FluentDocker.XUnit/PostgresTestBase.cs
new file mode 100644
index 0000000..c2402e9
--- /dev/null
+++ b/Ductus.FluentDocker.XUnit/PostgresTestBase.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Ductus.FluentDocker.Builders;
+using Ductus.FluentDocker.Services.Extensions;
+
+namespace Ductus.FluentDocker.XUnit
+{
+ public abstract class PostgresTestBase : FluentDockerTestBase
+ {
+ protected const string PostgresConnectionString =
+ "Server={0};Port={1};Userid={2};Password={3};" +
+ "Pooling=false;MinPoolSize=1;MaxPoolSize=20;" +
+ "Timeout=15;SslMode=Disable;Database={4}";
+
+ protected const string PostgresUser = "postgres";
+ protected const string PostgresDb = "postgres";
+ protected readonly string DockerImage;
+ protected readonly string PostgresPassword;
+
+ protected string ConnectionString;
+
+ protected PostgresTestBase(string password = "mysecretpassword", string image = "postgres:alpine")
+ {
+ PostgresPassword = password;
+ DockerImage = image;
+ }
+
+ protected override ContainerBuilder Build()
+ {
+ return new Builder().UseContainer()
+ .UseImage("postgres:alpine")
+ .WithEnvironment(
+ $"POSTGRES_PASSWORD={PostgresPassword}",
+ "POSTGRES_HOST_AUTH_METHOD=trust")
+ .ExposePort(5432)
+ .WaitForPort("5432/tcp", 30000 /*30s*/);
+ }
+
+ protected override void OnContainerInitialized()
+ {
+ var ep = Container.ToHostExposedEndpoint("5432/tcp");
+ ConnectionString = string.Format(PostgresConnectionString, ep.Address, ep.Port, PostgresUser,
+ PostgresPassword, PostgresDb);
+ }
+ }
+}
diff --git a/FluentDocker.sln b/FluentDocker.sln
index 43089fe..c2bac81 100644
--- a/FluentDocker.sln
+++ b/FluentDocker.sln
@@ -28,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{60257CD9-E
data\docker_network_inspect.json = data\docker_network_inspect.json
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ductus.FluentDocker.XUnit", "Ductus.FluentDocker.XUnit\Ductus.FluentDocker.XUnit.csproj", "{F8020BBA-78F7-426A-BE28-13716CC17966}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -46,6 +48,10 @@ Global
{FA836F5A-6361-4042-9B12-E38EB057CD41}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA836F5A-6361-4042-9B12-E38EB057CD41}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA836F5A-6361-4042-9B12-E38EB057CD41}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8020BBA-78F7-426A-BE28-13716CC17966}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8020BBA-78F7-426A-BE28-13716CC17966}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8020BBA-78F7-426A-BE28-13716CC17966}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8020BBA-78F7-426A-BE28-13716CC17966}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/README.md b/README.md
index 2835f1b..92663c3 100644
--- a/README.md
+++ b/README.md
@@ -982,7 +982,23 @@ using (
```
## Test Support
-This repo contains two nuget packages, one for the fluent access and the other is a ms-test base classes to be used while testing. For example in a unit-test it is possible to fire up a postgres container and wait when the the db has booted.
+This repo contains three nuget packages, one for the fluent access, one for ms-test base classes and another for xunit base classes to be used while testing. For example in a unit-test it is possible to fire up a postgres container and wait when the the db has booted.
+
+### XUnit
+```cs
+ public class PostgresXUnitTests : IClassFixture
+ {
+ [Fact]
+ public void Test()
+ {
+ // We now have a running postgres
+ // and a valid connection string to use.
+ }
+ }
+```
+
+
+### MSTest
```cs
using (
var container =