Skip to content

Commit 3f8a075

Browse files
authored
Merge pull request #1615 from alex-bogomaz/mstest-specify-tests-to-run
MSTest: add Tests parameter to specify list of tests
2 parents 2abd771 + 9466708 commit 3f8a075

File tree

10 files changed

+314
-9
lines changed

10 files changed

+314
-9
lines changed

build.fsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ open SourceLink
6969
open Fake.ReleaseNotesHelper
7070
open Fake.AssemblyInfoFile
7171
open Fake.Testing.XUnit2
72+
open Fake.MSTest
7273
open Fake.Testing.NUnit3
7374
#endif
7475

@@ -233,6 +234,7 @@ let dotnetAssemblyInfos =
233234
"Fake.DotNet.Testing.MSpec", "Running mspec test runner"
234235
"Fake.DotNet.Testing.NUnit", "Running nunit test runner"
235236
"Fake.DotNet.Testing.XUnit2", "Running xunit test runner"
237+
"Fake.DotNet.Testing.MSTest", "Running mstest test runner"
236238
"Fake.IO.FileSystem", "Core Filesystem utilities"
237239
"Fake.IO.Zip", "Core Zip functionality"
238240
"Fake.netcore", "Command line tool"
@@ -382,7 +384,7 @@ Target "Test" (fun _ ->
382384
|> MSpec (fun p ->
383385
{p with
384386
ToolPath = findToolInSubPath "mspec-x86-clr4.exe" (currentDirectory @@ "tools" @@ "MSpec")
385-
ExcludeTags = ["HTTP"]
387+
ExcludeTags = if isWindows then ["HTTP"] else ["HTTP"; "WindowsOnly"]
386388
TimeOut = System.TimeSpan.FromMinutes 5.
387389
HtmlOutputDir = reportDir})
388390
try

src/Fake-netcore.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fake.DotNet.Testing.NUnit",
4343
EndProject
4444
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fake.DotNet.Testing.XUnit2", "app\Fake.DotNet.Testing.XUnit2\Fake.DotNet.Testing.XUnit2.fsproj", "{21E2FE31-4E7C-489E-8215-9303108A2F39}"
4545
EndProject
46+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fake.DotNet.Testing.MSTest", "app\Fake.DotNet.Testing.MSTest\Fake.DotNet.Testing.MSTest.fsproj", "{21E2FE31-4E7C-489E-8215-9303108A2F30}"
47+
EndProject
4648
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fake.IO.FileSystem", "app\Fake.IO.FileSystem\Fake.IO.FileSystem.fsproj", "{4B1416CD-C7CB-4670-8EFE-871ED316D51D}"
4749
EndProject
4850
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fake.IO.Zip", "app\Fake.IO.Zip\Fake.IO.Zip.fsproj", "{46ED6A9C-C5BF-4495-924E-478736FC280E}"
@@ -306,6 +308,18 @@ Global
306308
{21E2FE31-4E7C-489E-8215-9303108A2F39}.Release|x64.Build.0 = Release|x64
307309
{21E2FE31-4E7C-489E-8215-9303108A2F39}.Release|x86.ActiveCfg = Release|x86
308310
{21E2FE31-4E7C-489E-8215-9303108A2F39}.Release|x86.Build.0 = Release|x86
311+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
312+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
313+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|x64.ActiveCfg = Debug|x64
314+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|x64.Build.0 = Debug|x64
315+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|x86.ActiveCfg = Debug|x86
316+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Debug|x86.Build.0 = Debug|x86
317+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
318+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|Any CPU.Build.0 = Release|Any CPU
319+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|x64.ActiveCfg = Release|x64
320+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|x64.Build.0 = Release|x64
321+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|x86.ActiveCfg = Release|x86
322+
{21E2FE31-4E7C-489E-8215-9303108A2F30}.Release|x86.Build.0 = Release|x86
309323
{4B1416CD-C7CB-4670-8EFE-871ED316D51D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
310324
{4B1416CD-C7CB-4670-8EFE-871ED316D51D}.Debug|Any CPU.Build.0 = Debug|Any CPU
311325
{4B1416CD-C7CB-4670-8EFE-871ED316D51D}.Debug|x64.ActiveCfg = Debug|x64
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Auto-Generated by FAKE; do not edit
2+
namespace System
3+
open System.Reflection
4+
5+
[<assembly: AssemblyTitleAttribute("FAKE - F# Make Running mstest test runner")>]
6+
[<assembly: AssemblyProductAttribute("FAKE - F# Make")>]
7+
[<assembly: AssemblyVersionAttribute("5.0.0")>]
8+
[<assembly: AssemblyInformationalVersionAttribute("5.0.0")>]
9+
[<assembly: AssemblyFileVersionAttribute("5.0.0")>]
10+
do ()
11+
12+
module internal AssemblyVersionInformation =
13+
let [<Literal>] AssemblyTitle = "FAKE - F# Make Running mstest test runner"
14+
let [<Literal>] AssemblyProduct = "FAKE - F# Make"
15+
let [<Literal>] AssemblyVersion = "5.0.0"
16+
let [<Literal>] AssemblyInformationalVersion = "5.0.0"
17+
let [<Literal>] AssemblyFileVersion = "5.0.0"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<VersionPrefix>1.0.0-alpha-10</VersionPrefix>
4+
<!--<TargetFrameworks>net46;netstandard1.6</TargetFrameworks>-->
5+
<TargetFramework>netstandard1.6</TargetFramework>
6+
<DefineConstants>$(DefineConstants);NO_DOTNETCORE_BOOTSTRAP</DefineConstants>
7+
<DebugType>pdbonly</DebugType>
8+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
9+
<AssemblyName>Fake.DotNet.Testing.MSTest</AssemblyName>
10+
<OutputType>Library</OutputType>
11+
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netstandard1.6' ">$(PackageTargetFallback);portable-net45+win8;dnxcore50</PackageTargetFallback>
12+
</PropertyGroup>
13+
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.6' ">
14+
<DefineConstants>$(DefineConstants);NETSTANDARD;USE_HTTPCLIENT</DefineConstants>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
17+
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
18+
</PropertyGroup>
19+
<ItemGroup>
20+
<Compile Include="AssemblyInfo.fs" />
21+
<Compile Include="MSTest.fs" />
22+
</ItemGroup>
23+
<ItemGroup>
24+
<ProjectReference Include="..\Fake.Core.Environment\Fake.Core.Environment.fsproj" />
25+
<ProjectReference Include="..\Fake.Core.Tracing\Fake.Core.Tracing.fsproj" />
26+
<ProjectReference Include="..\Fake.Core.Process\Fake.Core.Process.fsproj" />
27+
<ProjectReference Include="..\Fake.Core.String\Fake.Core.String.fsproj" />
28+
<ProjectReference Include="..\Fake.Core.Globbing\Fake.Core.Globbing.fsproj" />
29+
<ProjectReference Include="..\Fake.IO.FileSystem\Fake.IO.FileSystem.fsproj" />
30+
<ProjectReference Include="..\Fake.Core.BuildServer\Fake.Core.BuildServer.fsproj" />
31+
<ProjectReference Include="..\Fake.Testing.Common\Fake.Testing.Common.fsproj">
32+
<FromP2P>true</FromP2P>
33+
</ProjectReference>
34+
<ProjectReference Include="..\Fake.Core.Context\Fake.Core.Context.fsproj">
35+
<FromP2P>true</FromP2P>
36+
</ProjectReference>
37+
</ItemGroup>
38+
<!--<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
39+
<Reference Include="mscorlib">
40+
<FromP2P>true</FromP2P>
41+
</Reference>
42+
<Reference Include="System">
43+
<FromP2P>true</FromP2P>
44+
</Reference>
45+
<Reference Include="System.Core">
46+
<FromP2P>true</FromP2P>
47+
</Reference>
48+
</ItemGroup>-->
49+
<ItemGroup>
50+
<DotNetCliToolReference Include="dotnet-compile-fsc">
51+
<Version>1.0.0-preview2-020000</Version>
52+
</DotNetCliToolReference>
53+
</ItemGroup>
54+
<Import Project="..\..\..\.paket\Paket.Restore.targets" />
55+
</Project>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/// Contains tasks to run [MSTest](http://en.wikipedia.org/wiki/Visual_Studio_Unit_Testing_Framework/) unit tests.
2+
module Fake.DotNet.Testing.MSTest
3+
4+
open System
5+
open System.Text
6+
open Fake.Core.String
7+
open Fake.Core.Process
8+
open Fake.Core
9+
open Fake.Testing.Common
10+
11+
/// [omit]
12+
let mstestPaths =
13+
[| @"[ProgramFilesX86]\Microsoft Visual Studio 14.0\Common7\IDE";
14+
@"[ProgramFilesX86]\Microsoft Visual Studio 12.0\Common7\IDE";
15+
@"[ProgramFilesX86]\Microsoft Visual Studio 11.0\Common7\IDE";
16+
@"[ProgramFilesX86]\Microsoft Visual Studio 10.0\Common7\IDE" |]
17+
18+
/// [omit]
19+
let mstestexe =
20+
if Environment.isWindows then "mstest.exe"
21+
else failwith "MSTest is only supported on Windows platform"
22+
23+
// TODO: try to use VSTest.Console.exe as well (VS2012 and up only)
24+
/// Option which allow to specify if a MSTest error should break the build.
25+
type ErrorLevel = TestRunnerErrorLevel
26+
27+
/// Parameter type to configure the MSTest.exe.
28+
[<CLIMutable>]
29+
type MSTestParams =
30+
{ /// Test category filter (optional). The test category filter consists of one or more test category names separated by the logical operators '&', '|', '!', '&!'. The logical operators '&' and '|' cannot be used together to create a test category filter.
31+
Category : string
32+
/// Test results directory (optional)
33+
ResultsDir : string
34+
/// Path to the Test Metadata file (.vsmdi) (optional)
35+
TestMetadataPath : string
36+
/// Path to the Test Settings file (.testsettings) (optional)
37+
TestSettingsPath : string
38+
/// Working directory (optional)
39+
WorkingDir : string
40+
/// List of tests be run (optional)
41+
Tests : string list
42+
/// A timeout for the test runner (optional)
43+
TimeOut : TimeSpan
44+
/// Path to MSTest.exe
45+
ToolPath : string
46+
/// Option which allow to specify if a MSTest error should break the build.
47+
ErrorLevel : ErrorLevel
48+
/// Run tests in isolation (optional).
49+
NoIsolation : bool }
50+
51+
/// MSTest default parameters.
52+
let MSTestDefaults =
53+
{ Category = null
54+
ResultsDir = null
55+
TestMetadataPath = null
56+
TestSettingsPath = null
57+
WorkingDir = null
58+
Tests = []
59+
TimeOut = TimeSpan.FromMinutes 5.
60+
ToolPath =
61+
match tryFindFile mstestPaths mstestexe with
62+
| Some path -> path
63+
| None -> ""
64+
ErrorLevel = ErrorLevel.Error
65+
NoIsolation = true }
66+
67+
/// Builds the command line arguments from the given parameter record and the given assemblies.
68+
/// [omit]
69+
let buildMSTestArgs parameters assembly =
70+
let testResultsFile =
71+
if parameters.ResultsDir <> null then
72+
sprintf @"%s\%s.trx" parameters.ResultsDir (DateTime.Now.ToString("yyyyMMdd-HHmmss.ff"))
73+
else null
74+
75+
let builder =
76+
new StringBuilder()
77+
|> appendIfNotNull assembly "/testcontainer:"
78+
|> appendIfNotNull parameters.Category "/category:"
79+
|> appendIfNotNull parameters.TestMetadataPath "/testmetadata:"
80+
|> appendIfNotNull parameters.TestSettingsPath "/testsettings:"
81+
|> appendIfNotNull testResultsFile "/resultsfile:"
82+
|> appendIfTrue parameters.NoIsolation "/noisolation"
83+
84+
parameters.Tests
85+
|> List.iter (fun t -> builder |> appendIfNotNullOrEmpty t "/test:" |> ignore)
86+
87+
builder |> toText
88+
89+
/// Runs MSTest command line tool on a group of assemblies.
90+
/// ## Parameters
91+
///
92+
/// - `setParams` - Function used to manipulate the default MSTestParams value.
93+
/// - `assemblies` - Sequence of one or more assemblies containing Microsoft Visual Studio Unit Test Framework unit tests.
94+
///
95+
/// ## Sample usage
96+
///
97+
/// Target "Test" (fun _ ->
98+
/// !! (testDir + @"\*.Tests.dll")
99+
/// |> MSTest (fun p -> { p with Category = "group1" })
100+
/// )
101+
let MSTest (setParams : MSTestParams -> MSTestParams) (assemblies : string seq) =
102+
let details = assemblies |> separated ", "
103+
use __ = Trace.traceTask "MSTest" details
104+
let parameters = MSTestDefaults |> setParams
105+
let assemblies = assemblies |> Seq.toArray
106+
if Array.isEmpty assemblies then failwith "MSTest: cannot run tests (the assembly list is empty)."
107+
let failIfError assembly exitCode =
108+
if exitCode > 0 && parameters.ErrorLevel <> ErrorLevel.DontFailBuild then
109+
let message = sprintf "%sMSTest test run failed for %s" Environment.NewLine assembly
110+
Trace.traceError message
111+
failwith message
112+
for assembly in assemblies do
113+
let args = buildMSTestArgs parameters assembly
114+
ExecProcess (fun info ->
115+
info.FileName <- parameters.ToolPath
116+
info.WorkingDirectory <- parameters.WorkingDir
117+
info.Arguments <- args) parameters.TimeOut
118+
|> failIfError assembly
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
group netcore
2+
FSharp.NET.Sdk
3+
FSharp.Core
4+
NETStandard.Library

src/app/FakeLib/FakeLib.fsproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@
178178
<Compile Include="..\Fake.DotNet.Testing.NUnit\NUnit3.fs">
179179
<Link>Fake.DotNet.Testing.NUnit/NUnit3.fs</Link>
180180
</Compile>
181+
<Compile Include="..\Fake.DotNet.Testing.MSTest\MSTest.fs">
182+
<Link>Fake.DotNet.Testing.MSTest/MSTest.fs</Link>
183+
</Compile>
181184
<Compile Include="..\Fake.Core.Xml\Xml.fs">
182185
<Link>Fake.Core.Xml/Xml.fs</Link>
183186
</Compile>

src/app/FakeLib/UnitTest/MSTest.fs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,26 @@ open System
55
open System.Text
66

77
/// [omit]
8+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
89
let mstestPaths =
910
[| @"[ProgramFilesX86]\Microsoft Visual Studio 14.0\Common7\IDE";
1011
@"[ProgramFilesX86]\Microsoft Visual Studio 12.0\Common7\IDE";
1112
@"[ProgramFilesX86]\Microsoft Visual Studio 11.0\Common7\IDE";
1213
@"[ProgramFilesX86]\Microsoft Visual Studio 10.0\Common7\IDE" |]
1314

1415
/// [omit]
16+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
1517
let mstestexe =
1618
if isMono then failwith "MSTest is not supported on mono platform"
1719
else "mstest.exe"
1820

1921
// TODO: try to use VSTest.Console.exe as well (VS2012 and up only)
2022
/// Option which allow to specify if a MSTest error should break the build.
23+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
2124
type ErrorLevel = TestRunnerErrorLevel
2225

2326
/// Parameter type to configure the MSTest.exe.
27+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
2428
[<CLIMutable>]
2529
type MSTestParams =
2630
{ /// Test category filter (optional). The test category filter consists of one or more test category names separated by the logical operators '&', '|', '!', '&!'. The logical operators '&' and '|' cannot be used together to create a test category filter.
@@ -33,6 +37,8 @@ type MSTestParams =
3337
TestSettingsPath : string
3438
/// Working directory (optional)
3539
WorkingDir : string
40+
/// List of tests be run (optional)
41+
Tests : string list
3642
/// A timeout for the test runner (optional)
3743
TimeOut : TimeSpan
3844
/// Path to MSTest.exe
@@ -43,12 +49,14 @@ type MSTestParams =
4349
NoIsolation : bool }
4450

4551
/// MSTest default parameters.
52+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
4653
let MSTestDefaults =
4754
{ Category = null
4855
ResultsDir = null
4956
TestMetadataPath = null
5057
TestSettingsPath = null
5158
WorkingDir = null
59+
Tests = []
5260
TimeOut = TimeSpan.FromMinutes 5.
5361
ToolPath =
5462
match tryFindFile mstestPaths mstestexe with
@@ -59,19 +67,26 @@ let MSTestDefaults =
5967

6068
/// Builds the command line arguments from the given parameter record and the given assemblies.
6169
/// [omit]
70+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
6271
let buildMSTestArgs parameters assembly =
6372
let testResultsFile =
6473
if parameters.ResultsDir <> null then
6574
sprintf @"%s\%s.trx" parameters.ResultsDir (DateTime.Now.ToString("yyyyMMdd-HHmmss.ff"))
6675
else null
67-
new StringBuilder()
68-
|> appendIfNotNull assembly "/testcontainer:"
69-
|> appendIfNotNull parameters.Category "/category:"
70-
|> appendIfNotNull parameters.TestMetadataPath "/testmetadata:"
71-
|> appendIfNotNull parameters.TestSettingsPath "/testsettings:"
72-
|> appendIfNotNull testResultsFile "/resultsfile:"
73-
|> appendIfTrue parameters.NoIsolation "/noisolation"
74-
|> toText
76+
77+
let builder =
78+
new StringBuilder()
79+
|> appendIfNotNull assembly "/testcontainer:"
80+
|> appendIfNotNull parameters.Category "/category:"
81+
|> appendIfNotNull parameters.TestMetadataPath "/testmetadata:"
82+
|> appendIfNotNull parameters.TestSettingsPath "/testsettings:"
83+
|> appendIfNotNull testResultsFile "/resultsfile:"
84+
|> appendIfTrue parameters.NoIsolation "/noisolation"
85+
86+
parameters.Tests
87+
|> List.iter (fun t -> builder |> appendIfNotNullOrEmpty t "/test:" |> ignore)
88+
89+
builder |> toText
7590

7691
/// Runs MSTest command line tool on a group of assemblies.
7792
/// ## Parameters
@@ -85,6 +100,7 @@ let buildMSTestArgs parameters assembly =
85100
/// !! (testDir + @"\*.Tests.dll")
86101
/// |> MSTest (fun p -> { p with Category = "group1" })
87102
/// )
103+
[<System.Obsolete("use Fake.DotNet.Testing.MSTest instead")>]
88104
let MSTest (setParams : MSTestParams -> MSTestParams) (assemblies : string seq) =
89105
let details = assemblies |> separated ", "
90106
use __ = traceStartTaskUsing "MSTest" details

0 commit comments

Comments
 (0)