I am using MSBuild and am getting all test projects using a regex on the project name, like this.
<RegexMatch Input="@(AllProjects)" Expression="(.)*Test(.)*">
<Output TaskParameter="Output" ItemName="UnitTestProjects"/>
</RegexMatch>
I now want to use @(UnitTestProjects) and pass them all to NCover to check that the tests are all giving 100% coverage.
To do this on a single project, I do something like this:
<Target Name="Coverage">
<NCover TestRunnerExe="C:\Program Files\NUnit 2.5.8\bin\net-2.0\nunit-console.exe"
TestRunnerArgs=""C:\SomeProject\bin\SomeProject.dll" "C:\SomeProject\bin\SomeProjectTest.dll""
WorkingDirectory="C:\SomeProject\bin\"
AppendTrendTo="coverage.trend"
OnlyAssembliesWithSource="True"
ProjectName="SomeProjectCoverage" />
</Target>
How do I effectively use @(UnitTestProjects) in the context of this NCover target?
For batching your @(UnitTestProjects)
your Target will have to use it like this:
<Target Name="Coverage">
<NCover TestRunnerExe="C:\Program Files\NUnit 2.5.8\bin\net-2.0\nunit-console.exe"
TestRunnerArgs=""%(UnitTestProjects.Identity)" "%(UnitTestProjects.Identity)""
<!--
If you receive the Task Output (*Test.dll) you will have to extract
the working dir path
-->
WorkingDirectory="C:\SomeProject\bin\"
AppendTrendTo="coverage.trend"
OnlyAssembliesWithSource="True"
<!--
... the same thing applies to finding out the current project name
from your Task Ouput.
-->
ProjectName="SomeProjectCoverage" />
</Target>
A more reliable solution would be, to provide a list of TaskItems, holding metadata about your (Test)project.
<ItemGroup>
<TestProject Include="MyProject1.Test.dll">
<TestProjectName>MyProject1</TestProjectName>
<MyTestProjectWorkingDir>C:\MyProject1\bin</MyTestProjectWorkingDir>
</TestProject>
<TestProject Include="MyProject2.Test.dll">
<TestProjectName>MyProject2</TestProjectName>
<MyTestProjectWorkingDir>C:\MyProject2\bin</MyTestProjectWorkingDir>
</TestProject>
</ItemGroup>
<Target Name="Coverage">
<NCover TestRunnerExe="C:\Program Files\NUnit 2.5.8\bin\net-2.0\nunit-console.exe"
TestRunnerArgs=""%(TestProject.Identity)" "%(TestProject.Identity)""
WorkingDirectory="%(TestProject.MyTestProjectWorkingDir)"
AppendTrendTo="coverage.trend"
OnlyAssembliesWithSource="True"
ProjectName="%(TestProject.MyTestProjectName)" />
</Target>
Your question suggests that you are looking for an automated approach which will allow you to add new test projects without having to maintain a configuration list of TaskItems.
Since it would be quite difficult, to extract all the information needed to feed your NCover Task maybe a semi-automated approach might work for you.
You could add an import to your test project which will feed your global test project ItemGroup:
<ItemGroup>
<!-- add existing ItemGroup -->
<TestProject Include="@(TestProject)" />
<!-- add project itself -->
<TestProject Include="MyProject1.Test.dll">
<TestProjectName>MyProject1</TestProjectName>
<MyTestProjectWorkingDir>C:\MyProject1\bin</MyTestProjectWorkingDir>
</TestProject>
</ItemGroup>
The usage in your NCover Task will be the same as above.
This way your master build script doesn't need to know about any specific test project; it just processes your ItemGroup "TestProject".