зеркало из
1
0
Форкнуть 0

Initial implementation of separate teamcity extension solution

This commit is contained in:
Charlie Poole 2016-07-22 11:55:19 -07:00
Родитель b6730d9be8
Коммит 9eae5fb62b
12 изменённых файлов: 1385 добавлений и 0 удалений

179
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,179 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
.vs/
tools/Cake
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
# =========================
# NUnit Specific
# =========================
.~
*.userprefs
*.StyleCop
*.sdf
GeneratedAssemblyInfo.cs
StyleCop.Cache
local.settings.include
InternalTrace.txt
TestResult.xml
testCaseCollection.xml
deploy
lib
test-results
package
images
MockAssemblyResult.xml
PortabilityAnalysis*.html

9
NuGet.config Normal file
Просмотреть файл

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NUnit AppVeyor CI" value="https://ci.appveyor.com/nuget/nunit" />
<add key="NUNit MyGet Feed" value="https://www.myget.org/F/nunit/api/v2" />
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>

Просмотреть файл

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("teamcity-event-listener")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("teamcity-event-listener")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a867079b-a172-4dae-9549-63b331092a23")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]

Просмотреть файл

@ -0,0 +1,53 @@
// ***********************************************************************
// Copyright (c) 2016 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.Xml;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
sealed class ExtensionAttribute : Attribute { }
}
namespace NUnit.Engine.Listeners
{
/// <summary>
/// SafeAttributeAccess provides an extension method for accessing XML attributes.
/// </summary>
public static class SafeAttributeAccess
{
/// <summary>
/// Gets the value of the given attribute.
/// </summary>
/// <param name="result">The result.</param>
/// <param name="name">The name.</param>
/// <returns></returns>
public static string GetAttribute(this XmlNode result, string name)
{
XmlAttribute attr = result.Attributes[name];
return attr == null ? null : attr.Value;
}
}
}

Просмотреть файл

@ -0,0 +1,427 @@
// ***********************************************************************
// Copyright (c) 2015 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Globalization;
using NUnit.Engine.Extensibility;
namespace NUnit.Engine.Listeners
{
// Note: Setting mimimum engine version in this case is
// purely documentary since engines prior to 3.4 do not
// check the EngineVersion property and will try to
// load this extension anyway.
[Extension(Enabled = false, EngineVersion = "3.4")]
public class TeamCityEventListener : ITestEventListener
{
private readonly TextWriter _outWriter;
private readonly Dictionary<string, string> _refs = new Dictionary<string, string>();
private int _blockCounter;
private string _rootFlowId;
public TeamCityEventListener() : this(Console.Out) { }
public TeamCityEventListener(TextWriter outWriter)
{
if (outWriter == null)
{
throw new ArgumentNullException("outWriter");
}
_outWriter = outWriter;
}
#region ITestEventListener Implementation
public void OnTestEvent(string report)
{
var doc = new XmlDocument();
doc.LoadXml(report);
var testEvent = doc.FirstChild;
RegisterMessage(testEvent);
}
#endregion
public void RegisterMessage(XmlNode testEvent)
{
if (testEvent == null)
{
throw new ArgumentNullException("message");
}
var messageName = testEvent.Name;
if (string.IsNullOrEmpty(messageName))
{
return;
}
messageName = messageName.ToLowerInvariant();
if (messageName == "start-run")
{
_refs.Clear();
return;
}
var fullName = testEvent.GetAttribute("fullname");
if (string.IsNullOrEmpty(fullName))
{
return;
}
var id = testEvent.GetAttribute("id");
var parentId = testEvent.GetAttribute("parentId");
string flowId;
if (parentId != null)
{
// NUnit 3 case
string rootId;
flowId = TryFindRootId(parentId, out rootId) ? rootId : id;
}
else
{
// NUnit 2 case
flowId = _rootFlowId;
}
string testFlowId;
if (id != flowId && parentId != null)
{
testFlowId = id;
}
else
{
testFlowId = flowId;
if (testFlowId == null)
{
testFlowId = id;
}
}
switch (messageName.ToLowerInvariant())
{
case "start-suite":
_refs[id] = parentId;
StartSuiteCase(id, parentId, flowId, fullName);
break;
case "test-suite":
_refs.Remove(id);
TestSuiteCase(id, parentId, flowId, fullName);
break;
case "start-test":
_refs[id] = parentId;
CaseStartTest(id, flowId, parentId, testFlowId, fullName);
break;
case "test-case":
try
{
if (!_refs.Remove(id))
{
// When test without starting
CaseStartTest(id, flowId, parentId, testFlowId, fullName);
}
var result = testEvent.GetAttribute("result");
if (string.IsNullOrEmpty(result))
{
break;
}
switch (result.ToLowerInvariant())
{
case "passed":
OnTestFinished(testFlowId, testEvent, fullName);
break;
case "inconclusive":
OnTestInconclusive(testFlowId, testEvent, fullName);
break;
case "skipped":
OnTestSkipped(testFlowId, testEvent, fullName);
break;
case "failed":
OnTestFailed(testFlowId, testEvent, fullName);
break;
}
}
finally
{
if (id != flowId && parentId != null)
{
OnFlowFinished(id);
}
}
break;
}
}
private void CaseStartTest(string id, string flowId, string parentId, string testFlowId, string fullName)
{
if (id != flowId && parentId != null)
{
OnFlowStarted(id, flowId);
}
OnTestStart(testFlowId, fullName);
}
private void TestSuiteCase(string id, string parentId, string flowId, string fullName)
{
// NUnit 3 case
if (parentId == string.Empty)
{
OnRootSuiteFinish(flowId, fullName);
}
// NUnit 2 case
if (parentId == null)
{
if (--_blockCounter == 0)
{
_rootFlowId = null;
OnRootSuiteFinish(id, fullName);
}
}
}
private void StartSuiteCase(string id, string parentId, string flowId, string fullName)
{
// NUnit 3 case
if (parentId == string.Empty)
{
OnRootSuiteStart(flowId, fullName);
}
// NUnit 2 case
if (parentId == null)
{
if (_blockCounter++ == 0)
{
_rootFlowId = id;
OnRootSuiteStart(id, fullName);
}
}
}
private bool TryFindParentId(string id, out string parentId)
{
if (id == null)
{
throw new ArgumentNullException("id");
}
return _refs.TryGetValue(id, out parentId) && !string.IsNullOrEmpty(parentId);
}
private bool TryFindRootId(string id, out string rootId)
{
if (id == null)
{
throw new ArgumentNullException("id");
}
while (TryFindParentId(id, out rootId) && id != rootId)
{
id = rootId;
}
rootId = id;
return !string.IsNullOrEmpty(id);
}
private void TrySendOutput(string flowId, XmlNode message, string fullName)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
var output = message.SelectSingleNode("output");
if (output == null)
{
return;
}
var outputStr = output.InnerText;
if (string.IsNullOrEmpty(outputStr))
{
return;
}
WriteLine("##teamcity[testStdOut name='{0}' out='{1}' flowId='{2}']", fullName, outputStr, flowId);
}
private void OnRootSuiteStart(string flowId, string assemblyName)
{
assemblyName = Path.GetFileName(assemblyName);
WriteLine("##teamcity[testSuiteStarted name='{0}' flowId='{1}']", assemblyName, flowId);
}
private void OnRootSuiteFinish(string flowId, string assemblyName)
{
assemblyName = Path.GetFileName(assemblyName);
WriteLine("##teamcity[testSuiteFinished name='{0}' flowId='{1}']", assemblyName, flowId);
}
private void OnFlowStarted(string flowId, string parentFlowId)
{
WriteLine("##teamcity[flowStarted flowId='{0}' parent='{1}']", flowId, parentFlowId);
}
private void OnFlowFinished(string flowId)
{
WriteLine("##teamcity[flowFinished flowId='{0}']", flowId);
}
private void OnTestStart(string flowId, string fullName)
{
WriteLine("##teamcity[testStarted name='{0}' captureStandardOutput='false' flowId='{1}']", fullName, flowId);
}
private void OnTestFinished(string flowId, XmlNode message, string fullName)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
var durationStr = message.GetAttribute("duration");
double durationDecimal;
int durationMilliseconds = 0;
if (durationStr != null && double.TryParse(durationStr, NumberStyles.Any, CultureInfo.InvariantCulture, out durationDecimal))
{
durationMilliseconds = (int)(durationDecimal * 1000d);
}
TrySendOutput(flowId, message, fullName);
WriteLine(
"##teamcity[testFinished name='{0}' duration='{1}' flowId='{2}']",
fullName,
durationMilliseconds.ToString(),
flowId);
}
private void OnTestFailed(string flowId, XmlNode message, string fullName)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
var errorMmessage = message.SelectSingleNode("failure/message");
var stackTrace = message.SelectSingleNode("failure/stack-trace");
WriteLine(
"##teamcity[testFailed name='{0}' message='{1}' details='{2}' flowId='{3}']",
fullName,
errorMmessage == null ? string.Empty : errorMmessage.InnerText,
stackTrace == null ? string.Empty : stackTrace.InnerText,
flowId);
OnTestFinished(flowId, message, fullName);
}
private void OnTestSkipped(string flowId, XmlNode message, string fullName)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
TrySendOutput(flowId, message, fullName);
var reason = message.SelectSingleNode("reason/message");
WriteLine(
"##teamcity[testIgnored name='{0}' message='{1}' flowId='{2}']",
fullName,
reason == null ? string.Empty : reason.InnerText,
flowId);
}
private void OnTestInconclusive(string flowId, XmlNode message, string fullName)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
TrySendOutput(flowId, message, fullName);
WriteLine(
"##teamcity[testIgnored name='{0}' message='{1}' flowId='{2}']",
fullName,
"Inconclusive",
flowId);
}
private void WriteLine(string format, params string[] arg)
{
if (format == null)
{
throw new ArgumentNullException("format");
}
if (arg == null)
{
throw new ArgumentNullException("arg");
}
var argObjects = new object[arg.Length];
for (var i = 0; i < arg.Length; i++)
{
var str = arg[i];
if (str != null)
{
str = Escape(str);
}
argObjects[i] = str;
}
var message = string.Format(format, argObjects);
_outWriter.WriteLine(message);
}
private static string Escape(string input)
{
return input != null
? input.Replace("|", "||")
.Replace("'", "|'")
.Replace("\n", "|n")
.Replace("\r", "|r")
.Replace(char.ConvertFromUtf32(int.Parse("0086", NumberStyles.HexNumber)), "|x")
.Replace(char.ConvertFromUtf32(int.Parse("2028", NumberStyles.HexNumber)), "|l")
.Replace(char.ConvertFromUtf32(int.Parse("2029", NumberStyles.HexNumber)), "|p")
.Replace("[", "|[")
.Replace("]", "|]")
: null;
}
}
}

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit.Engine.Api" version="3.5.0-CI-3064-master" targetFramework="net20" />
</packages>

Просмотреть файл

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A867079B-A172-4DAE-9549-63B331092A23}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>teamcity_event_listener</RootNamespace>
<AssemblyName>teamcity-event-listener</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\bin\Debug\addins\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\bin\Release\addins\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.engine.api, Version=3.0.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\..\packages\NUnit.Engine.Api.3.5.0-CI-3064-master\lib\nunit.engine.api.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TeamCityEventListener.cs" />
<Compile Include="SafeAttributeAccess.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("tests")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("709aff60-b15e-43d5-830a-f22e4701d8b8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -0,0 +1,479 @@
// ***********************************************************************
// Copyright (c) 2015 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
using System.IO;
using System.Text;
using System.Xml;
using NUnit.Framework;
using NUnit.Engine.Extensibility;
namespace NUnit.Engine.Listeners
{
using System;
[TestFixture]
public class TeamCityEventListenerTests
{
private StringBuilder _output;
private StringWriter _outputWriter;
[SetUp]
public void SetUp()
{
_output = new StringBuilder();
_outputWriter = new StringWriter(_output);
}
[TearDown]
public void TearDown()
{
_outputWriter.Dispose();
}
[Test]
public void CheckExtensionAttribute()
{
Assert.That(typeof(TeamCityEventListener),
Has.Attribute<ExtensionAttribute>()
.With.Property("EngineVersion").EqualTo("3.4")
.And.Property("Enabled").EqualTo(false));
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenParallelizedTestsFromNUnit3()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", "", "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
publisher.RegisterMessage(CreateStartSuite("1-2", "1-1", "Assembly1.Namespace1"));
publisher.RegisterMessage(CreateStartSuite("1-3", "1-2", "Assembly1.Namespace1.1"));
// Assembly 2
publisher.RegisterMessage(CreateStartSuite("1-6", "", "ddd" + Path.DirectorySeparatorChar + "Assembly2"));
publisher.RegisterMessage(CreateStartSuite("1-7", "1-6", "Assembly2.Namespace2"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-4", "1-3", "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-4", "1-3", "Assembly1.Namespace1.1.Test1", "0.1", "Text output"));
// Test Assembly2.Namespace2.1.Test1
publisher.RegisterMessage(CreateStartTest("1-8", "1-7", "Assembly2.Namespace2.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-8", "1-8", "Assembly2.Namespace2.1.Test1", "0.1", "Text output"));
// Test Assembly1.Namespace1.1.Test2
publisher.RegisterMessage(CreateStartTest("1-5", "1-3", "Assembly1.Namespace1.1.Test2"));
publisher.RegisterMessage(CreateTestCaseFailed("1-5", "1-3", "Assembly1.Namespace1.1.Test2", "0.2", "Error output", "Stack trace"));
publisher.RegisterMessage(CreateFinishSuite("1-7", "1-6", "Assembly2.Namespace2"));
publisher.RegisterMessage(CreateFinishSuite("1-6", "", "Assembly2"));
publisher.RegisterMessage(CreateFinishSuite("1-3", "1-2", "Assembly1.Namespace1.1"));
publisher.RegisterMessage(CreateFinishSuite("1-2", "1-1", "Assembly1.Namespace1"));
publisher.RegisterMessage(CreateFinishSuite("1-1", "", "Assembly1"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testSuiteStarted name='Assembly2' flowId='1-6']" + Environment.NewLine
+ "##teamcity[flowStarted flowId='1-4' parent='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-4']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-4']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-4']" + Environment.NewLine
+ "##teamcity[flowFinished flowId='1-4']" + Environment.NewLine
+ "##teamcity[flowStarted flowId='1-8' parent='1-6']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly2.Namespace2.1.Test1' captureStandardOutput='false' flowId='1-8']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly2.Namespace2.1.Test1' out='Text output' flowId='1-8']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly2.Namespace2.1.Test1' duration='100' flowId='1-8']" + Environment.NewLine
+ "##teamcity[flowFinished flowId='1-8']" + Environment.NewLine
+ "##teamcity[flowStarted flowId='1-5' parent='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test2' captureStandardOutput='false' flowId='1-5']" + Environment.NewLine
+ "##teamcity[testFailed name='Assembly1.Namespace1.1.Test2' message='Error output' details='Stack trace' flowId='1-5']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test2' duration='200' flowId='1-5']" + Environment.NewLine
+ "##teamcity[flowFinished flowId='1-5']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly2' flowId='1-6']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenHas1SuiteFromNUnit3()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", "", "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-2", "1-1", "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-2", "1-1", "Assembly1.Namespace1.1.Test1", "0.1", "Text output"));
publisher.RegisterMessage(CreateFinishSuite("1-1", "", "Assembly1"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[flowStarted flowId='1-2' parent='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-2']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-2']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-2']" + Environment.NewLine
+ "##teamcity[flowFinished flowId='1-2']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenHasNoSuiteFromNUnit3()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-1", "", "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-1", "", "Assembly1.Namespace1.1.Test1", "0.1", "Text output"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenOutputIsEmpty()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-1", "", "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-1", "", "Assembly1.Namespace1.1.Test1", "0.1", ""));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenHasNoOutput()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-1", "", "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-1", "", "Assembly1.Namespace1.1.Test1", "10", null));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='10000' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenTestsFromNUnit2()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", null, "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
publisher.RegisterMessage(CreateStartSuite("1-2", null, "Assembly1.Namespace1"));
publisher.RegisterMessage(CreateStartSuite("1-3", null, "Assembly1.Namespace1.1"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-4", null, "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-4", null, "Assembly1.Namespace1.1.Test1", "0.1", "Text output"));
// Test Assembly1.Namespace1.1.Test2
publisher.RegisterMessage(CreateStartTest("1-5", null, "Assembly1.Namespace1.1.Test2"));
publisher.RegisterMessage(CreateTestCaseFailed("1-5", null, "Assembly1.Namespace1.1.Test2", "0.2", "Error output", "Stack trace"));
publisher.RegisterMessage(CreateFinishSuite("1-3", null, "Assembly1.Namespace1.1"));
publisher.RegisterMessage(CreateFinishSuite("1-2", null, "Assembly1.Namespace1"));
publisher.RegisterMessage(CreateFinishSuite("1-1", null, "Assembly1"));
// Assembly 2
publisher.RegisterMessage(CreateStartSuite("1-6", null, "ddd//Assembly2"));
publisher.RegisterMessage(CreateStartSuite("1-7", null, "Assembly2.Namespace2"));
// Test Assembly2.Namespace2.1.Test1
publisher.RegisterMessage(CreateStartTest("1-8", null, "Assembly2.Namespace2.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-8", null, "Assembly2.Namespace2.1.Test1", "0.3", "Text output"));
publisher.RegisterMessage(CreateFinishSuite("1-7", null, "Assembly2.Namespace2"));
publisher.RegisterMessage(CreateFinishSuite("1-6", null, "Assembly2"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test2' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFailed name='Assembly1.Namespace1.1.Test2' message='Error output' details='Stack trace' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test2' duration='200' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testSuiteStarted name='Assembly2' flowId='1-6']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly2.Namespace2.1.Test1' captureStandardOutput='false' flowId='1-6']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly2.Namespace2.1.Test1' out='Text output' flowId='1-6']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly2.Namespace2.1.Test1' duration='300' flowId='1-6']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly2' flowId='1-6']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenHas1SuiteFromNUnit2()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", null, "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-2", null, "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-2", null, "Assembly1.Namespace1.1.Test1", "1.3", "Text output"));
publisher.RegisterMessage(CreateFinishSuite("1-1", null, "Assembly1"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='1300' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWithValidFlowIdWhenHasNoSuiteFromNUnit2()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateStartTest("1-1", null, "Assembly1.Namespace1.1.Test1"));
publisher.RegisterMessage(CreateTestCaseSuccessful("1-1", null, "Assembly1.Namespace1.1.Test1", "0.1", "Text output"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStdOut name='Assembly1.Namespace1.1.Test1' out='Text output' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWhenOneTimeSetUpFailedFromNUnit3()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", "", "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateTestCaseFailed("1-2", "1-1", "Assembly1.Namespace1.1.Test1", "0.1", "Error output", "Stack trace"));
publisher.RegisterMessage(CreateFinishSuite("1-1", "", "Assembly1"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[flowStarted flowId='1-2' parent='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-2']" + Environment.NewLine
+ "##teamcity[testFailed name='Assembly1.Namespace1.1.Test1' message='Error output' details='Stack trace' flowId='1-2']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-2']" + Environment.NewLine
+ "##teamcity[flowFinished flowId='1-2']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
[Test]
public void ShouldSendMessagesWhenOneTimeSetUpFailedFromNUnit2()
{
// Given
var publisher = CreateInstance();
// When
publisher.RegisterMessage(CreateStartRun(1));
// Assembly 1
publisher.RegisterMessage(CreateStartSuite("1-1", null, "aaa" + Path.DirectorySeparatorChar + "Assembly1"));
// Test Assembly1.Namespace1.1.Test1
publisher.RegisterMessage(CreateTestCaseFailed("1-2", null, "Assembly1.Namespace1.1.Test1", "0.1", "Error output", "Stack trace"));
publisher.RegisterMessage(CreateFinishSuite("1-1", null, "Assembly1"));
publisher.RegisterMessage(CreateTestRun());
// Then
Assert.AreEqual(
"##teamcity[testSuiteStarted name='Assembly1' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testStarted name='Assembly1.Namespace1.1.Test1' captureStandardOutput='false' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFailed name='Assembly1.Namespace1.1.Test1' message='Error output' details='Stack trace' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testFinished name='Assembly1.Namespace1.1.Test1' duration='100' flowId='1-1']" + Environment.NewLine
+ "##teamcity[testSuiteFinished name='Assembly1' flowId='1-1']" + Environment.NewLine,
_output.ToString());
}
private static XmlNode CreateMessage(string text)
{
var doc = new XmlDocument();
doc.LoadXml(text);
return doc.FirstChild;
}
private static XmlNode CreateStartRun(int count)
{
return CreateMessage(string.Format("<start-run count='{0}'/>", count));
}
private static XmlNode CreateTestRun()
{
return CreateMessage("<test-run></test-run>");
}
private static XmlNode CreateStartSuite(string id, string parentId, string name)
{
return CreateMessage(string.Format("<start-suite id=\"{0}\" {1} name=\"{2}\" fullname=\"{2}\"/>", id, GetNamedAttr("parentId", parentId), name));
}
private static XmlNode CreateFinishSuite(string id, string parentId, string name)
{
return CreateMessage(string.Format("<test-suite id=\"{0}\" {1} name=\"{2}\" fullname=\"{2}\" runstate=\"Runnable\" testcasecount=\"3\" result=\"Failed\" duration=\"0.251125\" total=\"3\" passed=\"0\" failed=\"0\" inconclusive=\"0\" skipped=\"0\" asserts=\"0\"><failure><message><![CDATA[One or more child tests had errors]]></message></failure></test-suite>", id, GetNamedAttr("parentId", parentId), name));
}
private static XmlNode CreateStartTest(string id, string parentId, string name)
{
return CreateMessage(string.Format("<start-test id=\"{0}\" {1} name=\"{2}\" fullname=\"{2}\"/>", id, GetNamedAttr("parentId", parentId), name));
}
private static XmlNode CreateTestCaseSuccessful(string id, string parentId, string name, string duration, string output)
{
return CreateMessage(string.Format("<test-case id=\"{0}\" {1} name=\"{2}\" fullname=\"{2}\" runstate=\"Runnable\" result=\"Passed\" duration=\"{3}\" asserts=\"0\">{4}</test-case>", id, GetNamedAttr("parentId", parentId), name, duration, GetNamedElement("output", output)));
}
private static XmlNode CreateTestCaseFailed(string id, string parentId, string name, string duration, string message, string stackTrace)
{
return CreateMessage(string.Format("<test-case id=\"{0}\" {1} name=\"{2}\" fullname=\"{2}\" runstate=\"Runnable\" result=\"Failed\" duration=\"{3}\" asserts=\"0\"><properties><property name=\"_CATEGORIES\" value=\"F\" /></properties><failure><message><![CDATA[{4}]]></message><stack-trace><![CDATA[{5}]]></stack-trace></failure></test-case>", id, GetNamedAttr("parentId", parentId), name, duration, message, stackTrace));
}
private TeamCityEventListener CreateInstance()
{
return new TeamCityEventListener(_outputWriter);
}
private static string GetNamedAttr(string attrName, string attrValue)
{
if (attrValue == null)
{
return string.Empty;
}
return string.Format("{0}=\"{1}\"", attrName, attrValue);
}
private static string GetNamedElement(string elementName, string elementValue)
{
if (elementValue == null)
{
return string.Empty;
}
return string.Format("<{0}>{1}</{0}>", elementName, elementValue);
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.4.1" targetFramework="net20" />
<package id="NUnit.Engine.Api" version="3.5.0-CI-3064-master" targetFramework="net20" />
</packages>

Просмотреть файл

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{709AFF60-B15E-43D5-830A-F22E4701D8B8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>tests</RootNamespace>
<AssemblyName>tests</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.engine.api, Version=3.0.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\..\packages\NUnit.Engine.Api.3.5.0-CI-3064-master\lib\nunit.engine.api.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\..\packages\NUnit.3.4.1\lib\net20\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NUnit.System.Linq, Version=0.2.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\..\packages\NUnit.3.4.1\lib\net20\NUnit.System.Linq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TeamCityEventListenerTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\extension\teamcity-event-listener.csproj">
<Project>{a867079b-a172-4dae-9549-63b331092a23}</Project>
<Name>teamcity-event-listener</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "teamcity-event-listener", "src\extension\teamcity-event-listener.csproj", "{A867079B-A172-4DAE-9549-63B331092A23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "teamcity-event-listener.tests", "src\tests\teamcity-event-listener.tests.csproj", "{709AFF60-B15E-43D5-830A-F22E4701D8B8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A867079B-A172-4DAE-9549-63B331092A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A867079B-A172-4DAE-9549-63B331092A23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A867079B-A172-4DAE-9549-63B331092A23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A867079B-A172-4DAE-9549-63B331092A23}.Release|Any CPU.Build.0 = Release|Any CPU
{709AFF60-B15E-43D5-830A-F22E4701D8B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{709AFF60-B15E-43D5-830A-F22E4701D8B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{709AFF60-B15E-43D5-830A-F22E4701D8B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{709AFF60-B15E-43D5-830A-F22E4701D8B8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal