├── .editorconfig
├── .gitignore
├── .travis.yml
├── LICENSE
├── NuGet.Config
├── README.md
├── Rebracer.xml
├── appveyor.yml
├── dotnet-test-nunit.sln
├── global.json
├── scripts
├── set-version.ps1
└── show-dotnet-info.ps1
├── src
└── dotnet-test-nunit
│ ├── ColorConsole.cs
│ ├── ColorConsoleWriter.cs
│ ├── ColorStyle.cs
│ ├── CommandLineOptions.cs
│ ├── Env.cs
│ ├── Extensions
│ ├── SafeAttributeAccess.cs
│ ├── ServiceMessage.cs
│ ├── ServiceMessageAttr.cs
│ ├── ServiceMessageWriter.cs
│ ├── TeamCityEventListener.cs
│ └── TestExtensions.cs
│ ├── Interfaces
│ └── ITestListener.cs
│ ├── Navigation
│ └── NavigationDataProvider.cs
│ ├── Program.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── ResultReporter.cs
│ ├── ReturnCodes.cs
│ ├── Sinks
│ ├── Messages.cs
│ ├── RemoteTestDiscoverySink.cs
│ ├── RemoteTestExecutionSink.cs
│ └── RemoteTestSink.cs
│ ├── TestListeners
│ ├── BaseTestListener.cs
│ ├── TestExecutionListener.cs
│ └── TestExploreListener.cs
│ ├── TestRunner.cs
│ ├── dotnet-test-nunit.xproj
│ └── project.json
└── test
├── dotnet-test-nunit.test.runner
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── dotnet-test-nunit.test.runner.xproj
└── project.json
└── dotnet-test-nunit.test
├── ColorConsoleTests.cs
├── ColorStyleTests.cs
├── CommandLineOptionsTests.cs
├── EnvTests.cs
├── Extensions
└── TestExtensionsTests.cs
├── Mocks
├── MockTestExecutionSink.cs
└── MockTestExplorerSink.cs
├── Navigation
├── NavigationDataProviderTests.cs
└── NavigationTestData.cs
├── Properties
└── AssemblyInfo.cs
├── Sinks
├── BaseSinkTests.cs
├── RemoteTestDiscoverySinkTests.cs
├── RemoteTestExecutionSinkTests.cs
└── RemoteTestSinkTests.cs
├── TestListeners
├── TestExecutionListenerTests.cs
└── TestExplorerListenerTests.cs
├── dotnet-test-nunit.test.xproj
└── project.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and
2 | # maintain consistent coding styles between
3 | # different editors and IDEs
4 |
5 | # http://EditorConfig.org
6 |
7 | # top-most EditorConfig file
8 | root = true
9 |
10 | [*]
11 | end_of_line = crlf
12 | indent_style = space
13 | indent_size = 2
14 | tab_width = 4
15 | trim_trailing_whitespace = true
16 |
17 | [*.cs]
18 | charset = utf-8
19 | indent_style = space
20 | indent_size = 4
21 |
22 | [*.json]
23 | charset = utf-8
24 | indent_style = space
25 | indent_size = 2
26 |
27 | [*.xproj]
28 | charset = utf-8
29 | indent_style = space
30 | indent_size = 2
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | # Visual Studio 2015 cache/options directory
25 | .vs/
26 | # Uncomment if you have tasks that create the project's static files in wwwroot
27 | #wwwroot/
28 |
29 | # MSTest test Results
30 | [Tt]est[Rr]esult*/
31 | [Bb]uild[Ll]og.*
32 |
33 | # NUNIT
34 | *.VisualState.xml
35 | TestResult.xml
36 |
37 | # Build Results of an ATL Project
38 | [Dd]ebugPS/
39 | [Rr]eleasePS/
40 | dlldata.c
41 |
42 | # DNX
43 | project.lock.json
44 | artifacts/
45 |
46 | *_i.c
47 | *_p.c
48 | *_i.h
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.tmp_proj
63 | *.log
64 | *.vspscc
65 | *.vssscc
66 | .builds
67 | *.pidb
68 | *.svclog
69 | *.scc
70 |
71 | # Chutzpah Test files
72 | _Chutzpah*
73 |
74 | # Visual C++ cache files
75 | ipch/
76 | *.aps
77 | *.ncb
78 | *.opendb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 | # NuGet v3's project.json files produces more ignoreable files
154 | *.nuget.props
155 | *.nuget.targets
156 |
157 | # Microsoft Azure Build Output
158 | csx/
159 | *.build.csdef
160 |
161 | # Microsoft Azure Emulator
162 | ecf/
163 | rcf/
164 |
165 | # Microsoft Azure ApplicationInsights config file
166 | ApplicationInsights.config
167 |
168 | # Windows Store app package directory
169 | AppPackages/
170 | BundleArtifacts/
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # RIA/Silverlight projects
190 | Generated_Code/
191 |
192 | # Backup & report files from converting an old project file
193 | # to a newer Visual Studio version. Backup files are not needed,
194 | # because we have git ;-)
195 | _UpgradeReport_Files/
196 | Backup*/
197 | UpgradeLog*.XML
198 | UpgradeLog*.htm
199 |
200 | # SQL Server files
201 | *.mdf
202 | *.ldf
203 |
204 | # Business Intelligence projects
205 | *.rdl.data
206 | *.bim.layout
207 | *.bim_*.settings
208 |
209 | # Microsoft Fakes
210 | FakesAssemblies/
211 |
212 | # GhostDoc plugin setting file
213 | *.GhostDoc.xml
214 |
215 | # Node.js Tools for Visual Studio
216 | .ntvs_analysis.dat
217 |
218 | # Visual Studio 6 build log
219 | *.plg
220 |
221 | # Visual Studio 6 workspace options file
222 | *.opt
223 |
224 | # Visual Studio LightSwitch build output
225 | **/*.HTMLClient/GeneratedArtifacts
226 | **/*.DesktopClient/GeneratedArtifacts
227 | **/*.DesktopClient/ModelManifest.xml
228 | **/*.Server/GeneratedArtifacts
229 | **/*.Server/ModelManifest.xml
230 | _Pvt_Extensions
231 |
232 | # Paket dependency manager
233 | .paket/paket.exe
234 |
235 | # FAKE - F# Make
236 | .fake/
237 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: generic
2 |
3 | addons:
4 | apt:
5 | packages:
6 | - gettext
7 | - libcurl4-openssl-dev
8 | - libicu-dev
9 | - libssl-dev
10 | - libunwind8
11 | - zlib1g
12 |
13 | matrix:
14 | include:
15 | - os: linux
16 | dist: trusty # Ubuntu 14.04
17 | sudo: required
18 | env: CONFIGURATION=Debug
19 | - os: linux
20 | dist: trusty
21 | sudo: required
22 | env: CONFIGURATION=Release
23 | - os: osx
24 | osx_image: xcode7.2 # macOS 10.11
25 | env: CONFIGURATION=Debug
26 | - os: osx
27 | osx_image: xcode7.2
28 | env: CONFIGURATION=Release
29 |
30 | before_install:
31 | # Install OpenSSL
32 | - if test "$TRAVIS_OS_NAME" == "osx"; then
33 | brew install openssl;
34 | brew link --force openssl;
35 | export DOTNET_SDK_URL="https://go.microsoft.com/fwlink/?LinkID=809128";
36 | else
37 | export DOTNET_SDK_URL="https://go.microsoft.com/fwlink/?LinkID=809129";
38 | fi
39 |
40 | - export DOTNET_INSTALL_DIR="$PWD/.dotnetcli"
41 |
42 | # Install .NET CLI
43 | - mkdir $DOTNET_INSTALL_DIR
44 | - curl -L $DOTNET_SDK_URL -o dotnet_package
45 | - tar -xvzf dotnet_package -C $DOTNET_INSTALL_DIR
46 |
47 | # Add dotnet to PATH
48 | - export PATH="$DOTNET_INSTALL_DIR:$PATH"
49 |
50 | install:
51 | # Display dotnet version info
52 | - which dotnet;
53 | if [ $? -eq 0 ]; then
54 | echo "Using dotnet:";
55 | dotnet --info;
56 | else
57 | echo "dotnet.exe not found"
58 | exit 1;
59 | fi
60 |
61 | # [WORKAROUND]
62 | #
63 | # SYNOPSIS:
64 | #
65 | # dotnet-cli has introduced a bug with .NET Core RTM (wasn't there till RC2);
66 | # that is, the dotnet-run command ignores --framework option and therefore
67 | # demands mono PCL reference assemblies to be present on Unix systems, even
68 | # though when we intend to build for netcoreapp or netstandard TxM.
69 | #
70 | # See: https://github.com/dotnet/cli/issues/3658
71 | #
72 | # The workaround is to rewrite the JSON without net451 framework node in the
73 | # runnable (or testable) project's JSON file for CI. This work around must be
74 | # applied before executing dotnet-restore command.
75 | #
76 | # Written in JavaScript to be executable with node.js
77 | # (JavaScript being the most native langauge for JSON processing)
78 | #
79 | # Travis CI job when running under different langauge provides nvm (the node.js version manager)
80 | # but not node.js itself. So we first run:
81 | #
82 | # > $HOME/.nvm/nvm.sh
83 | #
84 | # then install stable node
85 | #
86 | # > nvm install stable && nvm use stable
87 | #
88 | # now, we have node.js in PATH. We will run the following program in evaluation
89 | # mode as one-liner:
90 | #
91 | # ```javascript
92 | # // the file to manipulate
93 | # jsonPath = './test/dotnet-test-nunit.test.runner/project.json';
94 | #
95 | # // read and parse JSON as object (aka CommonJS magic)
96 | # data = require(jsonPath);
97 | #
98 | # // FileSystem API handle
99 | # fs = require('fs');
100 | #
101 | # // delete framework 451 key from the object
102 | # delete data.frameworks.net451;
103 | #
104 | # // write back to file
105 | # fs.writeFileSync(jsonPath, JSON.stringify(data, null, 2));
106 | # ```
107 | # Now the actual one-liner (compressed) version:
108 | #
109 | - if test "$TRAVIS_OS_NAME" == "linux"; then
110 | nvm install stable && nvm use stable;
111 | fi
112 | - node -e "jsonPath='./test/dotnet-test-nunit.test.runner/project.json';data=require(jsonPath);fs=require('fs');delete data.frameworks.net451;fs.writeFileSync(jsonPath, JSON.stringify(data, null, 2))"
113 |
114 | # Restore dependencies
115 | - dotnet restore
116 |
117 | # Build projects
118 | - dotnet build -c $CONFIGURATION -f netcoreapp1.0 ./test/dotnet-test-nunit.test.runner
119 |
120 | script:
121 | # Run tests
122 | - dotnet run -c $CONFIGURATION -f netcoreapp1.0 -p ./test/dotnet-test-nunit.test.runner
123 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 NUnit Project
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NUnit 3 Test Runner for .NET Core
2 |
3 | ## Deprecated
4 |
5 | This project is deprecated. The test adapter API changed when .NET Core switched from
6 | `project.json` to the new `csproj` format. For newer .NET Core and .NET Standard
7 | projects, use the [NUnit 3 Visual Studio Test adapter](https://github.com/nunit/nunit3-vs-adapter)
8 | to run tests at the command line using `dotnet test`, in CI or in Visual Studio.
9 |
10 | For more information on how to test .NET Core, see the
11 | [.NET Core/.NET Standard documentation](https://github.com/nunit/docs/wiki/.NET-Core-and-.NET-Standard).
12 |
13 | If you are reporting **issues**, we are no longer making updates to this project or the use of `dotnet-test-nunit` and `project.json`. Issues should be reported against the [NUnit 3 Visual Studio Test adapter](https://github.com/nunit/nunit3-vs-adapter).
14 |
15 |
16 | [](https://ci.appveyor.com/project/CharliePoole/dotnet-test-nunit/branch/master) [](https://travis-ci.org/nunit/dotnet-test-nunit)
17 |
18 | `dotnet-test-nunit` is the unit test runner for .NET Core for running unit tests with NUnit 3.
19 |
20 | ## Usage
21 |
22 | `dotnet-test-nunit` is still an alpha release, so you need to select `show prereleases` if you are using Visual Studio.
23 |
24 | Your `project.json` in your test project should look like the following;
25 |
26 | ### project.json
27 |
28 | ```json
29 | {
30 | "version": "1.0.0-*",
31 |
32 | "dependencies": {
33 | "NUnit": "3.5.0",
34 | "dotnet-test-nunit": "3.4.0-beta-3"
35 | },
36 |
37 | "testRunner": "nunit",
38 |
39 | "frameworks": {
40 | "netcoreapp1.0": {
41 | "imports": "portable-net45+win8",
42 | "dependencies": {
43 | "Microsoft.NETCore.App": {
44 | "version": "1.0.0-*",
45 | "type": "platform"
46 | }
47 | }
48 | }
49 | }
50 | }
51 | ```
52 |
53 | The lines of interest here are the dependency on `dotnet-test-nunit`. I have added `"testRunner": "nunit"` to specify NUnit 3 as the test adapter. I also had to add to the imports for both the test adapter and NUnit to resolve.
54 |
55 | You can now run your tests using the Visual Studio Test Explorer, or by running `dotnet test` from the command line.
56 |
57 | ```sh
58 | # Restore the NuGet packages
59 | dotnet restore
60 |
61 | # Run the unit tests in the current directory
62 | dotnet test
63 |
64 | # Run the unit tests in a different directory
65 | dotnet test test/NUnitWithDotNetCoreRC2.Test
66 | ```
67 |
68 | ### Notes
69 |
70 | Note that the `dotnet` command line swallows blank lines and does not work with color.
71 | The NUnit test runner's output is in color, but you won't see it. These are known issues with
72 | the `dotnet` CLI and not an NUnit bug.
73 |
--------------------------------------------------------------------------------
/Rebracer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 0
13 | 0
14 | 1
15 | 1
16 | 1
17 | -1
18 | -1
19 | 1
20 | 2
21 | 80
22 | 0
23 | 1
24 | 0
25 | 1
26 | 1
27 | 1
28 | 1
29 | 0
30 | 1
31 | 0
32 | 1
33 | 1
34 | 0
35 | 1
36 | 1
37 | 1
38 | 1
39 | 1
40 | 0
41 | 0
42 | 1
43 | 1
44 | 1
45 | 1
46 | 1
47 | 1
48 | 1
49 | 1
50 | 1
51 | 1
52 | 1
53 | 1
54 | 1
55 | 1
56 | 1
57 | 1
58 | 0
59 | 1
60 | 0
61 | 1
62 | 0
63 | 0
64 | 1
65 | 1
66 | 1
67 | 0
68 | 0
69 | 1
70 | 0
71 | 0
72 | 0
73 | 0
74 | 0
75 | 1
76 | 0
77 | 0
78 | 0
79 | 0
80 | 0
81 | 0
82 | 0
83 | 1
84 | 1
85 | 0
86 | 1
87 | 0
88 | 1
89 | 0
90 | 0
91 | 1
92 | 1
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 3.3.0.{build}
2 | os: Visual Studio 2015
3 | configuration: Release
4 |
5 | assembly_info:
6 | patch: true
7 | file: '**\AssemblyInfo.*'
8 | assembly_version: '{version}'
9 | assembly_file_version: '{version}'
10 |
11 | before_build:
12 | - ps: .\scripts\show-dotnet-info.ps1
13 | - ps: .\scripts\set-version.ps1
14 | - cmd: dotnet --info
15 | - cmd: dotnet restore
16 |
17 | build_script:
18 | - cmd: dotnet build -c Release test\dotnet-test-nunit.test.runner\
19 |
20 | test_script:
21 | - cmd: dotnet run -c Release -p test\dotnet-test-nunit.test.runner\
22 |
23 | after_test:
24 | - cmd: dotnet pack -c Release src\dotnet-test-nunit\
25 |
26 | test: off
27 |
28 | artifacts:
29 | path: 'src\dotnet-test-nunit\bin\Release\*.nupkg'
30 |
--------------------------------------------------------------------------------
/dotnet-test-nunit.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F0FC9C69-996D-43E7-B8A0-35A9311E2B36}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3D935F98-183C-4E6F-99C0-D166B0FC0F33}"
9 | ProjectSection(SolutionItems) = preProject
10 | .editorconfig = .editorconfig
11 | .gitignore = .gitignore
12 | .travis.yml = .travis.yml
13 | appveyor.yml = appveyor.yml
14 | global.json = global.json
15 | NuGet.Config = NuGet.Config
16 | README.md = README.md
17 | Rebracer.xml = Rebracer.xml
18 | EndProjectSection
19 | EndProject
20 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test-nunit", "src\dotnet-test-nunit\dotnet-test-nunit.xproj", "{7FC6DCED-278A-449B-8BB0-95346410C8D2}"
21 | EndProject
22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{93336E7C-25F0-4327-84EA-B190EA537709}"
23 | EndProject
24 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test-nunit.test", "test\dotnet-test-nunit.test\dotnet-test-nunit.test.xproj", "{B3C98A50-D42F-4197-968B-0E25591E83C3}"
25 | EndProject
26 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-test-nunit.test.runner", "test\dotnet-test-nunit.test.runner\dotnet-test-nunit.test.runner.xproj", "{F2025265-8A4E-46DD-AE91-537E302B3F24}"
27 | EndProject
28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{D519507E-757D-4B9F-9B02-8E8E0B64071A}"
29 | ProjectSection(SolutionItems) = preProject
30 | scripts\set-version.ps1 = scripts\set-version.ps1
31 | scripts\show-dotnet-info.ps1 = scripts\show-dotnet-info.ps1
32 | EndProjectSection
33 | EndProject
34 | Global
35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
36 | Debug|Any CPU = Debug|Any CPU
37 | Release|Any CPU = Release|Any CPU
38 | EndGlobalSection
39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
40 | {7FC6DCED-278A-449B-8BB0-95346410C8D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41 | {7FC6DCED-278A-449B-8BB0-95346410C8D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 | {7FC6DCED-278A-449B-8BB0-95346410C8D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {7FC6DCED-278A-449B-8BB0-95346410C8D2}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {B3C98A50-D42F-4197-968B-0E25591E83C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {B3C98A50-D42F-4197-968B-0E25591E83C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {B3C98A50-D42F-4197-968B-0E25591E83C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {B3C98A50-D42F-4197-968B-0E25591E83C3}.Release|Any CPU.Build.0 = Release|Any CPU
48 | {F2025265-8A4E-46DD-AE91-537E302B3F24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 | {F2025265-8A4E-46DD-AE91-537E302B3F24}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 | {F2025265-8A4E-46DD-AE91-537E302B3F24}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {F2025265-8A4E-46DD-AE91-537E302B3F24}.Release|Any CPU.Build.0 = Release|Any CPU
52 | EndGlobalSection
53 | GlobalSection(SolutionProperties) = preSolution
54 | HideSolutionNode = FALSE
55 | EndGlobalSection
56 | GlobalSection(NestedProjects) = preSolution
57 | {7FC6DCED-278A-449B-8BB0-95346410C8D2} = {F0FC9C69-996D-43E7-B8A0-35A9311E2B36}
58 | {B3C98A50-D42F-4197-968B-0E25591E83C3} = {93336E7C-25F0-4327-84EA-B190EA537709}
59 | {F2025265-8A4E-46DD-AE91-537E302B3F24} = {93336E7C-25F0-4327-84EA-B190EA537709}
60 | EndGlobalSection
61 | EndGlobal
62 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "projects": [ "src", "test" ],
3 | "sdk": {
4 | "version": "1.0.0-preview2-003131"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/set-version.ps1:
--------------------------------------------------------------------------------
1 | $ReleaseVersionNumber = $env:APPVEYOR_BUILD_VERSION
2 | $PreReleaseName = ''
3 |
4 | If($env:APPVEYOR_PULL_REQUEST_NUMBER -ne $null) {
5 | $PreReleaseName = '-PR-' + $env:APPVEYOR_PULL_REQUEST_NUMBER
6 | } ElseIf($env:APPVEYOR_REPO_BRANCH -ne 'master' -and -not $env:APPVEYOR_REPO_BRANCH.StartsWith('release')) {
7 | $PreReleaseName = '-' + $env:APPVEYOR_REPO_BRANCH
8 | } Else {
9 | $PreReleaseName = '-CI'
10 | }
11 |
12 | $PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path).FullName
13 | $ScriptDir = Split-Path -Path $PSScriptFilePath -Parent
14 | $SolutionRoot = Split-Path -Path $ScriptDir -Parent
15 |
16 | $ProjectJsonPath = Join-Path -Path $SolutionRoot -ChildPath "src\dotnet-test-nunit\project.json"
17 | $re = [regex]"(?<=`"version`":\s`")[.\w-]*(?=`",)"
18 | $re.Replace([string]::Join("`n", (Get-Content -Path $ProjectJsonPath)), "$ReleaseVersionNumber$PreReleaseName", 1) |
19 | Set-Content -Path $ProjectJsonPath -Encoding UTF8
--------------------------------------------------------------------------------
/scripts/show-dotnet-info.ps1:
--------------------------------------------------------------------------------
1 | if (Get-Command dotnet -errorAction SilentlyContinue) {
2 | Write-Host "Using dotnet '$((Get-Command dotnet).Path)'"
3 | dotnet --version
4 | }
5 | else {
6 | Write-Host "dotnet.exe not found"
7 | }
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/ColorConsole.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 |
26 | namespace NUnit.Runner
27 | {
28 | ///
29 | /// Sets the console color in the constructor and resets it in the dispose
30 | ///
31 | public class ColorConsole : IDisposable
32 | {
33 | private ConsoleColor _originalColor;
34 |
35 | ///
36 | /// Initializes a new instance of the class.
37 | ///
38 | /// The color style to use.
39 | public ColorConsole(ColorStyle style)
40 | {
41 | _originalColor = Console.ForegroundColor;
42 | Console.ForegroundColor = GetColor(style);
43 | }
44 |
45 | ///
46 | /// By using styles, we can keep everything consistent
47 | ///
48 | ///
49 | ///
50 | public static ConsoleColor GetColor(ColorStyle style)
51 | {
52 | ConsoleColor color = GetColorForStyle(style);
53 | ConsoleColor bg = Console.BackgroundColor;
54 |
55 | if (color == bg || color == ConsoleColor.Red && bg == ConsoleColor.Magenta)
56 | return bg == ConsoleColor.Black
57 | ? ConsoleColor.White
58 | : ConsoleColor.Black;
59 |
60 | return color;
61 | }
62 |
63 | private static ConsoleColor GetColorForStyle(ColorStyle style)
64 | {
65 | switch (Console.BackgroundColor)
66 | {
67 | case ConsoleColor.White:
68 | switch (style)
69 | {
70 | case ColorStyle.Header:
71 | return ConsoleColor.Black;
72 | case ColorStyle.SubHeader:
73 | return ConsoleColor.Black;
74 | case ColorStyle.SectionHeader:
75 | return ConsoleColor.Blue;
76 | case ColorStyle.Label:
77 | return ConsoleColor.Black;
78 | case ColorStyle.Value:
79 | return ConsoleColor.Blue;
80 | case ColorStyle.Pass:
81 | return ConsoleColor.Green;
82 | case ColorStyle.Failure:
83 | return ConsoleColor.Red;
84 | case ColorStyle.Warning:
85 | return ConsoleColor.Black;
86 | case ColorStyle.Error:
87 | return ConsoleColor.Red;
88 | case ColorStyle.Output:
89 | return ConsoleColor.Black;
90 | case ColorStyle.Help:
91 | return ConsoleColor.Black;
92 | case ColorStyle.Default:
93 | default:
94 | return ConsoleColor.Black;
95 | }
96 |
97 | case ConsoleColor.Cyan:
98 | case ConsoleColor.Green:
99 | case ConsoleColor.Red:
100 | case ConsoleColor.Magenta:
101 | case ConsoleColor.Yellow:
102 | switch (style)
103 | {
104 | case ColorStyle.Header:
105 | return ConsoleColor.Black;
106 | case ColorStyle.SubHeader:
107 | return ConsoleColor.Black;
108 | case ColorStyle.SectionHeader:
109 | return ConsoleColor.Blue;
110 | case ColorStyle.Label:
111 | return ConsoleColor.Black;
112 | case ColorStyle.Value:
113 | return ConsoleColor.Black;
114 | case ColorStyle.Pass:
115 | return ConsoleColor.Black;
116 | case ColorStyle.Failure:
117 | return ConsoleColor.Red;
118 | case ColorStyle.Warning:
119 | return ConsoleColor.Yellow;
120 | case ColorStyle.Error:
121 | return ConsoleColor.Red;
122 | case ColorStyle.Output:
123 | return ConsoleColor.Black;
124 | case ColorStyle.Help:
125 | return ConsoleColor.Black;
126 | case ColorStyle.Default:
127 | default:
128 | return ConsoleColor.Black;
129 | }
130 |
131 | default:
132 | switch (style)
133 | {
134 | case ColorStyle.Header:
135 | return ConsoleColor.White;
136 | case ColorStyle.SubHeader:
137 | return ConsoleColor.Gray;
138 | case ColorStyle.SectionHeader:
139 | return ConsoleColor.Cyan;
140 | case ColorStyle.Label:
141 | return ConsoleColor.Green;
142 | case ColorStyle.Value:
143 | return ConsoleColor.White;
144 | case ColorStyle.Pass:
145 | return ConsoleColor.Green;
146 | case ColorStyle.Failure:
147 | return ConsoleColor.Red;
148 | case ColorStyle.Warning:
149 | return ConsoleColor.Yellow;
150 | case ColorStyle.Error:
151 | return ConsoleColor.Red;
152 | case ColorStyle.Output:
153 | return ConsoleColor.Gray;
154 | case ColorStyle.Help:
155 | return ConsoleColor.Green;
156 | case ColorStyle.Default:
157 | default:
158 | return ConsoleColor.Green;
159 | }
160 | }
161 | }
162 |
163 | #region Implementation of IDisposable
164 |
165 | ///
166 | /// If color is enabled, restores the console colors to their defaults
167 | ///
168 | public void Dispose()
169 | {
170 | Console.ForegroundColor = _originalColor;
171 | }
172 |
173 | #endregion
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/ColorConsoleWriter.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 | using System.Text;
27 |
28 | namespace NUnit.Runner
29 | {
30 | public class ColorConsoleWriter
31 | {
32 | bool _colorEnabled;
33 | TextWriter _writer;
34 |
35 | ///
36 | /// Construct a ColorConsoleWriter.
37 | ///
38 | public ColorConsoleWriter() : this(true) { }
39 |
40 | ///
41 | /// Construct a ColorConsoleWriter.
42 | ///
43 | /// Flag indicating whether color should be enabled
44 | public ColorConsoleWriter(bool colorEnabled)
45 | {
46 | _writer = Console.Out;
47 | _colorEnabled = colorEnabled;
48 | }
49 |
50 | #region Extended Methods
51 | ///
52 | /// Writes the value with the specified style.
53 | ///
54 | /// The style.
55 | /// The value.
56 | public void Write(ColorStyle style, string value)
57 | {
58 | if (_colorEnabled)
59 | using (new ColorConsole(style))
60 | {
61 | _writer.Write(value);
62 | }
63 | else
64 | _writer.Write(value);
65 | }
66 |
67 | ///
68 | /// Writes the value with the specified style.
69 | ///
70 | /// The style.
71 | /// The value.
72 | public void WriteLine(ColorStyle style, string value)
73 | {
74 | if (_colorEnabled)
75 | using (new ColorConsole(style))
76 | {
77 | _writer.WriteLine(value);
78 | }
79 | else
80 | _writer.WriteLine(value);
81 | }
82 |
83 | ///
84 | /// Writes the label and the option that goes with it.
85 | ///
86 | /// The label.
87 | /// The option.
88 | public void WriteLabel(string label, object option)
89 | {
90 | WriteLabel(label, option, ColorStyle.Value);
91 | }
92 |
93 | ///
94 | /// Writes the label and the option that goes with it followed by a new line.
95 | ///
96 | /// The label.
97 | /// The option.
98 | public void WriteLabelLine(string label, object option)
99 | {
100 | WriteLabelLine(label, option, ColorStyle.Value);
101 | }
102 |
103 | ///
104 | /// Writes the label and the option that goes with it and optionally writes a new line.
105 | ///
106 | /// The label.
107 | /// The option.
108 | /// The color to display the value with
109 | public void WriteLabel(string label, object option, ColorStyle valueStyle)
110 | {
111 | Write(ColorStyle.Label, label);
112 | Write(valueStyle, option.ToString());
113 | }
114 |
115 | ///
116 | /// Writes the label and the option that goes with it followed by a new line.
117 | ///
118 | /// The label.
119 | /// The option.
120 | /// The color to display the value with
121 | public void WriteLabelLine(string label, object option, ColorStyle valueStyle)
122 | {
123 | WriteLabel(label, option, valueStyle);
124 | _writer.WriteLine();
125 | }
126 |
127 | ///
128 | /// Write a single char value
129 | ///
130 | public void Write(char value)
131 | {
132 | _writer.Write(value);
133 | }
134 |
135 | ///
136 | /// Write a string value
137 | ///
138 | public void Write(string value)
139 | {
140 | _writer.Write(value);
141 | }
142 |
143 | ///
144 | /// Writes a NewLine
145 | ///
146 | public void WriteLine()
147 | {
148 | _writer.WriteLine();
149 | }
150 |
151 | ///
152 | /// Write a string value followed by a NewLine
153 | ///
154 | public void WriteLine(string value)
155 | {
156 | _writer.WriteLine(value);
157 | }
158 |
159 | ///
160 | /// Gets the encoding for this ExtendedTextWriter
161 | ///
162 | public Encoding Encoding => _writer.Encoding;
163 |
164 | #endregion
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/ColorStyle.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Runner
25 | {
26 | ///
27 | /// ColorStyle enumerates the various styles used in the console display
28 | ///
29 | public enum ColorStyle
30 | {
31 | ///
32 | /// Color for headers
33 | ///
34 | Header,
35 | ///
36 | /// Color for sub-headers
37 | ///
38 | SubHeader,
39 | ///
40 | /// Color for each of the section headers
41 | ///
42 | SectionHeader,
43 | ///
44 | /// The default color for items that don't fit into the other categories
45 | ///
46 | Default,
47 | ///
48 | /// Test output
49 | ///
50 | Output,
51 | ///
52 | /// Color for help text
53 | ///
54 | Help,
55 | ///
56 | /// Color for labels
57 | ///
58 | Label,
59 | ///
60 | /// Color for values, usually go beside labels
61 | ///
62 | Value,
63 | ///
64 | /// Color for passed tests
65 | ///
66 | Pass,
67 | ///
68 | /// Color for failed tests
69 | ///
70 | Failure,
71 | ///
72 | /// Color for warnings, ignored or skipped tests
73 | ///
74 | Warning,
75 | ///
76 | /// Color for errors and exceptions
77 | ///
78 | Error
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/CommandLineOptions.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Collections.Generic;
26 | using System.IO;
27 | using NUnit.Engine;
28 | using NUnit.Options;
29 |
30 | namespace NUnit.Runner
31 | {
32 | public class CommandLineOptions : OptionSet
33 | {
34 | private bool validated;
35 | private bool noresult;
36 |
37 | #region Constructor
38 |
39 | public CommandLineOptions(params string[] args)
40 | {
41 | ConfigureOptions();
42 | if (args != null)
43 | Parse(args);
44 | }
45 |
46 | #endregion
47 |
48 | #region Properties
49 |
50 | // .Net Core runner options http://dotnet.github.io/docs/core-concepts/core-sdk/cli/dotnet-test-protocol.html
51 | public bool DesignTime { get; private set; }
52 |
53 | public int Port { get; private set; } = -1;
54 | public bool PortSpecified => Port >= 0;
55 |
56 | public bool WaitCommand { get; private set; }
57 |
58 | public bool List { get; private set; }
59 |
60 | public int ParentProcessId { get; private set; }
61 |
62 | // Action to Perform
63 |
64 | public bool Explore { get; private set; }
65 |
66 | public bool ShowHelp { get; private set; }
67 |
68 | public bool ShowVersion { get; private set; }
69 |
70 | // Select tests
71 |
72 | public IList InputFiles { get; } = new List();
73 |
74 | public IList TestList { get; } = new List();
75 |
76 | public string TestParameters { get; private set; }
77 |
78 | public string WhereClause { get; private set; }
79 | public bool WhereClauseSpecified => WhereClause != null;
80 |
81 | public int DefaultTimeout { get; private set; } = -1;
82 | public bool DefaultTimeoutSpecified => DefaultTimeout >= 0;
83 |
84 | public int RandomSeed { get; private set; } = -1;
85 | public bool RandomSeedSpecified => RandomSeed >= 0;
86 |
87 | public string DefaultTestNamePattern { get; private set; }
88 |
89 | #if false
90 | public int NumberOfTestWorkers { get; private set; } = -1;
91 | public bool NumberOfTestWorkersSpecified => NumberOfTestWorkers >= 0;
92 | #endif
93 |
94 | public bool StopOnError { get; private set; }
95 |
96 | public bool WaitBeforeExit { get; private set; }
97 |
98 | public bool TeamCity { get; private set; }
99 |
100 | #if NET451
101 | public bool Debug { get; private set; }
102 | #endif
103 |
104 | // Output Control
105 |
106 | public bool NoHeader { get; private set; }
107 |
108 | public bool NoColor { get; private set; }
109 |
110 | public string DisplayTestLabels { get; private set; }
111 |
112 | string workDirectory = null;
113 | public string WorkDirectory => workDirectory ?? Env.DefaultWorkDirectory;
114 |
115 | public bool WorkDirectorySpecified => workDirectory != null;
116 |
117 | public string InternalTraceLevel { get; private set; }
118 | public bool InternalTraceLevelSpecified => InternalTraceLevel != null;
119 |
120 | private List resultOutputSpecifications = new List();
121 | public IList ResultOutputSpecifications
122 | {
123 | get
124 | {
125 | if (noresult)
126 | return new OutputSpecification[0];
127 |
128 | if (resultOutputSpecifications.Count == 0)
129 | resultOutputSpecifications.Add(new OutputSpecification("TestResult.xml"));
130 |
131 | return resultOutputSpecifications;
132 | }
133 | }
134 |
135 | public IList ExploreOutputSpecifications { get; private set; } = new List();
136 |
137 | // Error Processing
138 |
139 | public IList ErrorMessages { get; private set; } = new List();
140 |
141 | #endregion
142 |
143 | #region Public Methods
144 |
145 | public bool Validate()
146 | {
147 | if (!validated)
148 | {
149 | CheckOptionCombinations();
150 | validated = true;
151 | }
152 | return ErrorMessages.Count == 0;
153 | }
154 |
155 | #endregion
156 |
157 | #region Helper Methods
158 |
159 | void CheckOptionCombinations()
160 | {
161 | // TODO: Fill in any validations
162 | }
163 |
164 | ///
165 | /// Case is ignored when val is compared to validValues. When a match is found, the
166 | /// returned value will be in the canonical case from validValues.
167 | ///
168 | protected string RequiredValue(string val, string option, params string[] validValues)
169 | {
170 | if (string.IsNullOrEmpty(val))
171 | ErrorMessages.Add("Missing required value for option '" + option + "'.");
172 |
173 | bool isValid = true;
174 |
175 | if (validValues != null && validValues.Length > 0)
176 | {
177 | isValid = false;
178 |
179 | foreach (string valid in validValues)
180 | if (string.Compare(valid, val, StringComparison.OrdinalIgnoreCase) == 0)
181 | return valid;
182 |
183 | }
184 |
185 | if (!isValid)
186 | ErrorMessages.Add(string.Format("The value '{0}' is not valid for option '{1}'.", val, option));
187 |
188 | return val;
189 | }
190 |
191 | protected int RequiredInt(string val, string option)
192 | {
193 | // We have to return something even though the value will
194 | // be ignored if an error is reported. The -1 value seems
195 | // like a safe bet in case it isn't ignored due to a bug.
196 | int result = -1;
197 |
198 | if (string.IsNullOrEmpty(val))
199 | ErrorMessages.Add("Missing required value for option '" + option + "'.");
200 | else
201 | {
202 | // NOTE: Don't replace this with TryParse or you'll break the CF build!
203 | try
204 | {
205 | result = int.Parse(val);
206 | }
207 | catch (Exception)
208 | {
209 | ErrorMessages.Add("An int value was expected for option '{0}' but a value of '{1}' was used");
210 | }
211 | }
212 |
213 | return result;
214 | }
215 |
216 | private string ExpandToFullPath(string path)
217 | {
218 | if (path == null) return null;
219 | return Path.GetFullPath(path);
220 | }
221 |
222 | void ConfigureOptions()
223 | {
224 | // NOTE: The order in which patterns are added
225 | // determines the display order for the help.
226 |
227 | // Select Tests
228 | this.Add("test=", "Comma-separated list of {NAMES} of tests to run or explore. This option may be repeated.",
229 | v => ((List)TestList).AddRange(TestNameParser.Parse(RequiredValue(v, "--test"))));
230 |
231 | this.Add("where=", "Test selection {EXPRESSION} indicating what tests will be run. See description below.",
232 | v => WhereClause = RequiredValue(v, "--where"));
233 |
234 | this.Add("params|p=", "Define a test parameter.",
235 | v =>
236 | {
237 | string parameters = RequiredValue(v, "--params");
238 |
239 | foreach (string param in parameters.Split(new[] { ';' }))
240 | {
241 | if (!param.Contains("="))
242 | ErrorMessages.Add("Invalid format for test parameter. Use NAME=VALUE.");
243 | }
244 |
245 | if (TestParameters == null)
246 | TestParameters = parameters;
247 | else
248 | TestParameters += ";" + parameters;
249 | });
250 |
251 | this.Add("timeout=", "Set timeout for each test case in {MILLISECONDS}.",
252 | v => DefaultTimeout = RequiredInt(v, "--timeout"));
253 |
254 | this.Add("seed=", "Set the random {SEED} used to generate test cases.",
255 | v => RandomSeed = RequiredInt(v, "--seed"));
256 | #if false
257 | this.Add("workers=", "Specify the {NUMBER} of worker threads to be used in running tests. If not specified, defaults to 2 or the number of processors, whichever is greater.",
258 | v => numWorkers = RequiredInt(v, "--workers"));
259 | #endif
260 | this.Add("stoponerror", "Stop run immediately upon any test failure or error.",
261 | v => StopOnError = v != null);
262 |
263 | this.Add("wait", "Wait for input before closing console window.",
264 | v => WaitBeforeExit = v != null);
265 |
266 | // Output Control
267 | this.Add("work=", "{PATH} of the directory to use for output files. If not specified, defaults to the current directory.",
268 | v => workDirectory = RequiredValue(v, "--work"));
269 |
270 | this.Add("result=", "An output {SPEC} for saving the test results.\nThis option may be repeated.",
271 | v => resultOutputSpecifications.Add(new OutputSpecification(RequiredValue(v, "--resultxml"))));
272 |
273 | this.Add("explore:", "Display or save test info rather than running tests. Optionally provide an output {SPEC} for saving the test info. This option may be repeated.", v =>
274 | {
275 | Explore = true;
276 | if (v != null)
277 | ExploreOutputSpecifications.Add(new OutputSpecification(v));
278 | });
279 |
280 | this.Add("noresult", "Don't save any test results.",
281 | v => noresult = v != null);
282 |
283 | this.Add("labels=", "Specify whether to write test case names to the output. Values: Off, On, All",
284 | v => DisplayTestLabels = RequiredValue(v, "--labels", "Off", "On", "All"));
285 |
286 | this.Add("test-name-format=", "Non-standard naming pattern to use in generating test names.",
287 | v => DefaultTestNamePattern = RequiredValue(v, "--test-name-format"));
288 |
289 | this.Add("trace=", "Set internal trace {LEVEL}.\nValues: Off, Error, Warning, Info, Verbose (Debug)",
290 | v => InternalTraceLevel = RequiredValue(v, "--trace", "Off", "Error", "Warning", "Info", "Verbose", "Debug"));
291 |
292 | this.Add("noheader|noh", "Suppress display of program information at start of run.",
293 | v => NoHeader = v != null);
294 |
295 | this.Add("nocolor|noc", "Displays console output without color.",
296 | v => NoColor = v != null);
297 |
298 | this.Add("teamcity|tc", "Enables teamcity tests processing messages.",
299 | v => TeamCity = v != null);
300 |
301 | this.Add("help|h|?", "Display this message and exit.",
302 | v => ShowHelp = v != null);
303 |
304 | this.Add("version|V", "Display the header and exit.",
305 | v => ShowVersion = v != null);
306 |
307 | #if NET451
308 | this.Add("debug", "Attaches the debugger on launch",
309 | v => Debug = v != null);
310 | #endif
311 |
312 | // .NET Core runner options
313 | this.Add("designtime", "Used to indicate that the runner is being launched by an IDE",
314 | v => DesignTime = v != null);
315 |
316 | this.Add("port=", "Used by IDEs to specify a port number to listen for a connection",
317 | v => Port = RequiredInt(v, "--port"));
318 |
319 | this.Add("wait-command", "Used by IDEs to indicate that the runner should connect to the port and wait for commands, instead of going ahead and executing the tests",
320 | v => WaitCommand = v != null);
321 |
322 | this.Add("list", "Used by IDEs to request a list of tests that can be run",
323 | v => List = v != null);
324 |
325 | this.Add("parentProcessId", "Used by IDEs to indicate the Parent PID",
326 | v => ParentProcessId = RequiredInt(v, "--parentProcessId"));
327 |
328 | // Default
329 | this.Add("<>", v =>
330 | {
331 | if (v.StartsWith("-", StringComparison.Ordinal) || v.StartsWith("/", StringComparison.Ordinal) && Path.DirectorySeparatorChar != '/')
332 | ErrorMessages.Add("Invalid argument: " + v);
333 | else
334 | InputFiles.Add(v);
335 | });
336 | }
337 |
338 | #endregion
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Env.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 |
27 | namespace NUnit.Runner
28 | {
29 | ///
30 | /// Env is a static class that provides some of the features of
31 | /// System.Environment that are not available under all runtimes
32 | ///
33 | public class Env
34 | {
35 | static Env()
36 | {
37 | #if NETSTANDARD1_5 || NETCOREAPP1_0
38 | DocumentFolder = ".";
39 | string drive = Environment.GetEnvironmentVariable("HOMEDRIVE");
40 | string path = Environment.GetEnvironmentVariable("HOMEPATH");
41 | if (drive != null && path != null)
42 | {
43 | DocumentFolder = Path.Combine(drive, path, "documents");
44 | }
45 | else if (path != null)
46 | {
47 | DocumentFolder = Path.Combine(path, "documents");
48 | }
49 | else
50 | {
51 | string profile = Environment.GetEnvironmentVariable("USERPROFILE");
52 | if (profile != null)
53 | DocumentFolder = Path.Combine(profile, "documents");
54 | }
55 | DefaultWorkDirectory = Directory.GetCurrentDirectory();
56 | #else
57 | DocumentFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
58 | DefaultWorkDirectory = Environment.CurrentDirectory;
59 | #endif
60 | }
61 |
62 | ///
63 | /// Path to the 'My Documents' folder
64 | ///
65 | public static string DocumentFolder;
66 |
67 | ///
68 | /// Directory used for file output if not specified on commandline.
69 | ///
70 | public static readonly string DefaultWorkDirectory;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/SafeAttributeAccess.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System.Xml;
25 |
26 | namespace NUnit.Engine.Listeners
27 | {
28 | ///
29 | /// SafeAttributeAccess provides an extension method for accessing XML attributes.
30 | ///
31 | public static class SafeAttributeAccess
32 | {
33 | ///
34 | /// Gets the value of the given attribute.
35 | ///
36 | /// The result.
37 | /// The name.
38 | ///
39 | public static string GetAttribute(this XmlNode result, string name)
40 | {
41 | XmlAttribute attr = result.Attributes[name];
42 |
43 | return attr == null ? null : attr.Value;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/ServiceMessage.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2015 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Engine.Listeners
25 | {
26 | using System;
27 | using System.Collections.Generic;
28 | using System.Collections.ObjectModel;
29 |
30 | internal struct ServiceMessage
31 | {
32 | public ServiceMessage(string name, params ServiceMessageAttr[] attributes)
33 | : this()
34 | {
35 | // ReSharper disable once UseNameofExpression
36 | if (name == null) throw new ArgumentNullException("name");
37 | // ReSharper disable once UseNameofExpression
38 | if (attributes == null) throw new ArgumentNullException("attributes");
39 |
40 | Name = name;
41 | Attributes = new ReadOnlyCollection(attributes);
42 | }
43 |
44 | public string Name { get; private set; }
45 |
46 | public IEnumerable Attributes { get; private set; }
47 |
48 | public static class Names
49 | {
50 | public const string TestStdOut = "testStdOut";
51 | public const string TestSuiteStarted = "testSuiteStarted";
52 | public const string TestSuiteFinished = "testSuiteFinished";
53 | public const string FlowStarted = "flowStarted";
54 | public const string FlowFinished = "flowFinished";
55 | public const string TestStarted = "testStarted";
56 | public const string TestFinished = "testFinished";
57 | public const string TestFailed = "testFailed";
58 | public const string TestIgnored = "testIgnored";
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/ServiceMessageAttr.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2015 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Engine.Listeners
25 | {
26 | using System;
27 | using System.Diagnostics.CodeAnalysis;
28 |
29 | [SuppressMessage("ReSharper", "UseNameofExpression")]
30 | internal struct ServiceMessageAttr
31 | {
32 | public ServiceMessageAttr(string name, string value)
33 | : this()
34 | {
35 | if (name == null) throw new ArgumentNullException("name");
36 | if (value == null) throw new ArgumentNullException("value");
37 |
38 | Name = name;
39 | Value = value;
40 | }
41 |
42 | public string Value { get; private set; }
43 |
44 | public string Name { get; private set; }
45 |
46 | public static class Names
47 | {
48 | public const string Name = "name";
49 | public const string FlowId = "flowId";
50 | public const string Message = "message";
51 | public const string Out = "out";
52 | public const string TcTags = "tc:tags";
53 | public const string Parent = "parent";
54 | public const string CaptureStandardOutput = "captureStandardOutput";
55 | public const string Duration = "duration";
56 | public const string Details = "details";
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/ServiceMessageWriter.cs:
--------------------------------------------------------------------------------
1 | namespace NUnit.Engine.Listeners
2 | {
3 | using System;
4 | using System.Diagnostics.CodeAnalysis;
5 | using System.Globalization;
6 | using System.IO;
7 |
8 | [SuppressMessage("ReSharper", "UseNameofExpression")]
9 | internal class ServiceMessageWriter
10 | {
11 | private const string Header = "##teamcity[";
12 | private const string Footer = "]";
13 |
14 | public void Write(TextWriter writer, ServiceMessage serviceMessage)
15 | {
16 | if (writer == null) throw new ArgumentNullException("writer");
17 |
18 | writer.Write(Header);
19 | writer.Write(serviceMessage.Name);
20 | foreach (var attribute in serviceMessage.Attributes)
21 | {
22 | writer.Write(' ');
23 | Write(writer, attribute);
24 | }
25 |
26 | writer.Write(Footer);
27 | }
28 |
29 |
30 | private void Write(TextWriter writer, ServiceMessageAttr attribute)
31 | {
32 | writer.Write(attribute.Name);
33 | writer.Write("='");
34 | writer.Write(EscapeString(attribute.Value));
35 | writer.Write('\'');
36 | }
37 |
38 | private static string EscapeString(string value)
39 | {
40 | return value != null
41 | ? value.Replace("|", "||")
42 | .Replace("'", "|'")
43 | .Replace("\n", "|n")
44 | .Replace("\r", "|r")
45 | .Replace(char.ConvertFromUtf32(int.Parse("0086", NumberStyles.HexNumber)), "|x")
46 | .Replace(char.ConvertFromUtf32(int.Parse("2028", NumberStyles.HexNumber)), "|l")
47 | .Replace(char.ConvertFromUtf32(int.Parse("2029", NumberStyles.HexNumber)), "|p")
48 | .Replace("[", "|[")
49 | .Replace("]", "|]")
50 | : null;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/TeamCityEventListener.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2015 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 | using System.Xml;
27 | using System.Collections.Generic;
28 | using System.Globalization;
29 |
30 | namespace NUnit.Engine.Listeners
31 | {
32 | using System.Diagnostics.CodeAnalysis;
33 | using System.Text;
34 |
35 | // Note: Setting mimimum engine version in this case is
36 | // purely documentary since engines prior to 3.4 do not
37 | // check the EngineVersion property and will try to
38 | // load this extension anyway.
39 | [SuppressMessage("ReSharper", "UseNameofExpression")]
40 | public class TeamCityEventListener
41 | {
42 | private static readonly ServiceMessageWriter ServiceMessageWriter = new ServiceMessageWriter();
43 | private readonly TextWriter _outWriter;
44 | private readonly Dictionary _refs = new Dictionary();
45 | private readonly Dictionary _blockCounters = new Dictionary();
46 |
47 | public TeamCityEventListener() : this(Console.Out) { }
48 |
49 | public TeamCityEventListener(TextWriter outWriter)
50 | {
51 | if (outWriter == null) throw new ArgumentNullException("outWriter");
52 |
53 | _outWriter = outWriter;
54 | }
55 |
56 | #region ITestEventListener Implementation
57 |
58 | public void OnTestEvent(string report)
59 | {
60 | var doc = new XmlDocument();
61 | doc.LoadXml(report);
62 |
63 | var testEvent = doc.FirstChild;
64 | RegisterMessage(testEvent);
65 | }
66 |
67 | #endregion
68 |
69 | public void RegisterMessage(XmlNode testEvent)
70 | {
71 | if (testEvent == null) throw new ArgumentNullException("testEvent");
72 |
73 | var messageName = testEvent.Name;
74 | if (string.IsNullOrEmpty(messageName))
75 | {
76 | return;
77 | }
78 |
79 | messageName = messageName.ToLowerInvariant();
80 | if (messageName == "start-run")
81 | {
82 | _refs.Clear();
83 | return;
84 | }
85 |
86 | var fullName = testEvent.GetAttribute("fullname");
87 | if (string.IsNullOrEmpty(fullName))
88 | {
89 | return;
90 | }
91 |
92 | var id = testEvent.GetAttribute("id");
93 | if (id == null)
94 | {
95 | id = string.Empty;
96 | }
97 |
98 | var parentId = testEvent.GetAttribute("parentId");
99 | var flowId = ".";
100 | if (parentId != null)
101 | {
102 | // NUnit 3 case
103 | string rootId;
104 | flowId = TryFindRootId(parentId, out rootId) ? rootId : id;
105 | }
106 | else
107 | {
108 | // NUnit 2 case
109 | if (!string.IsNullOrEmpty(id))
110 | {
111 | var idParts = id.Split('-');
112 | if (idParts.Length == 2)
113 | {
114 | flowId = idParts[0];
115 | }
116 | }
117 | }
118 |
119 | string testFlowId;
120 | if (id != flowId && parentId != null)
121 | {
122 | testFlowId = id;
123 | }
124 | else
125 | {
126 | testFlowId = flowId;
127 | if (testFlowId == null)
128 | {
129 | testFlowId = id;
130 | }
131 | }
132 |
133 | switch (messageName.ToLowerInvariant())
134 | {
135 | case "start-suite":
136 | _refs[id] = parentId;
137 | StartSuiteCase(parentId, flowId, fullName);
138 | break;
139 |
140 | case "test-suite":
141 | _refs.Remove(id);
142 | TestSuiteCase(parentId, flowId, fullName);
143 | break;
144 |
145 | case "start-test":
146 | _refs[id] = parentId;
147 | CaseStartTest(id, flowId, parentId, testFlowId, fullName);
148 | break;
149 |
150 | case "test-case":
151 | try
152 | {
153 | if (!_refs.Remove(id))
154 | {
155 | // When test without starting
156 | CaseStartTest(id, flowId, parentId, testFlowId, fullName);
157 | }
158 |
159 | var result = testEvent.GetAttribute("result");
160 | if (string.IsNullOrEmpty(result))
161 | {
162 | break;
163 | }
164 |
165 | switch (result.ToLowerInvariant())
166 | {
167 | case "passed":
168 | OnTestFinished(testFlowId, testEvent, fullName);
169 | break;
170 |
171 | case "inconclusive":
172 | OnTestInconclusive(testFlowId, testEvent, fullName);
173 | break;
174 |
175 | case "skipped":
176 | OnTestSkipped(testFlowId, testEvent, fullName);
177 | break;
178 |
179 | case "failed":
180 | OnTestFailed(testFlowId, testEvent, fullName);
181 | break;
182 | }
183 | }
184 | finally
185 | {
186 | if (id != flowId && parentId != null)
187 | {
188 | OnFlowFinished(id);
189 | }
190 | }
191 |
192 | break;
193 | }
194 | }
195 |
196 | private void CaseStartTest(string id, string flowId, string parentId, string testFlowId, string fullName)
197 | {
198 | if (id != flowId && parentId != null)
199 | {
200 | OnFlowStarted(id, flowId);
201 | }
202 |
203 | OnTestStart(testFlowId, fullName);
204 | }
205 |
206 | private void TestSuiteCase(string parentId, string flowId, string fullName)
207 | {
208 | // NUnit 3 case
209 | if (parentId == string.Empty)
210 | {
211 | OnRootSuiteFinish(flowId, fullName);
212 | }
213 |
214 | // NUnit 2 case
215 | if (parentId == null)
216 | {
217 | if (ChangeBlockCounter(flowId, -1) == 0)
218 | {
219 | OnRootSuiteFinish(flowId, fullName);
220 | }
221 | }
222 | }
223 |
224 | private void StartSuiteCase(string parentId, string flowId, string fullName)
225 | {
226 | // NUnit 3 case
227 | if (parentId == string.Empty)
228 | {
229 | OnRootSuiteStart(flowId, fullName);
230 | }
231 |
232 | // NUnit 2 case
233 | if (parentId == null)
234 | {
235 | if (ChangeBlockCounter(flowId, 1) == 1)
236 | {
237 | OnRootSuiteStart(flowId, fullName);
238 | }
239 | }
240 | }
241 |
242 | private int ChangeBlockCounter(string flowId, int changeValue)
243 | {
244 | int currentBlockCounter;
245 | if (!_blockCounters.TryGetValue(flowId, out currentBlockCounter))
246 | {
247 | currentBlockCounter = 0;
248 | }
249 |
250 | currentBlockCounter += changeValue;
251 | _blockCounters[flowId] = currentBlockCounter;
252 | return currentBlockCounter;
253 | }
254 |
255 | private bool TryFindParentId(string id, out string parentId)
256 | {
257 | if (id == null)
258 | {
259 | throw new ArgumentNullException("id");
260 | }
261 |
262 | return _refs.TryGetValue(id, out parentId) && !string.IsNullOrEmpty(parentId);
263 | }
264 |
265 | private bool TryFindRootId(string id, out string rootId)
266 | {
267 | if (id == null)
268 | {
269 | throw new ArgumentNullException("id");
270 | }
271 |
272 | while (TryFindParentId(id, out rootId) && id != rootId)
273 | {
274 | id = rootId;
275 | }
276 |
277 | rootId = id;
278 | return !string.IsNullOrEmpty(id);
279 | }
280 |
281 | private void TrySendOutput(string flowId, XmlNode message, string fullName)
282 | {
283 | if (message == null) throw new ArgumentNullException("message");
284 |
285 | var output = message.SelectSingleNode("output");
286 | if (output == null)
287 | {
288 | return;
289 | }
290 |
291 | SendOutput(flowId, fullName, output.InnerText);
292 | }
293 |
294 | private void TrySendReasonMessage(string flowId, XmlNode message, string fullName)
295 | {
296 | if (message == null) throw new ArgumentNullException("message");
297 |
298 | var reasonMessageElement = message.SelectSingleNode("reason/message");
299 | if (reasonMessageElement == null)
300 | {
301 | return;
302 | }
303 |
304 | var reasonMessage = reasonMessageElement.InnerText;
305 | if (string.IsNullOrEmpty(reasonMessage))
306 | {
307 | return;
308 | }
309 |
310 | SendOutput(flowId, fullName, "Assert.Pass message: " + reasonMessage);
311 | }
312 |
313 | private void SendOutput(string flowId, string fullName, string outputStr)
314 | {
315 | if (string.IsNullOrEmpty(outputStr))
316 | {
317 | return;
318 | }
319 |
320 | Write(new ServiceMessage(ServiceMessage.Names.TestStdOut,
321 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
322 | new ServiceMessageAttr(ServiceMessageAttr.Names.Out, outputStr),
323 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId),
324 | new ServiceMessageAttr(ServiceMessageAttr.Names.TcTags, "tc:parseServiceMessagesInside")));
325 | }
326 |
327 | private void OnRootSuiteStart(string flowId, string assemblyName)
328 | {
329 | assemblyName = Path.GetFileName(assemblyName);
330 |
331 | Write(new ServiceMessage(ServiceMessage.Names.TestSuiteStarted,
332 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, assemblyName),
333 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
334 | }
335 |
336 | private void OnRootSuiteFinish(string flowId, string assemblyName)
337 | {
338 | assemblyName = Path.GetFileName(assemblyName);
339 |
340 | Write(new ServiceMessage(ServiceMessage.Names.TestSuiteFinished,
341 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, assemblyName),
342 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
343 | }
344 |
345 | private void OnFlowStarted(string flowId, string parentFlowId)
346 | {
347 | Write(new ServiceMessage(ServiceMessage.Names.FlowStarted,
348 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId),
349 | new ServiceMessageAttr(ServiceMessageAttr.Names.Parent, parentFlowId)));
350 | }
351 |
352 | private void OnFlowFinished(string flowId)
353 | {
354 | Write(new ServiceMessage(ServiceMessage.Names.FlowFinished,
355 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
356 | }
357 |
358 | private void OnTestStart(string flowId, string fullName)
359 | {
360 | Write(new ServiceMessage(ServiceMessage.Names.TestStarted,
361 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
362 | new ServiceMessageAttr(ServiceMessageAttr.Names.CaptureStandardOutput, "false"),
363 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
364 | }
365 |
366 | private void OnTestFinished(string flowId, XmlNode message, string fullName)
367 | {
368 | if (message == null)
369 | {
370 | throw new ArgumentNullException("message");
371 | }
372 |
373 | var durationStr = message.GetAttribute(ServiceMessageAttr.Names.Duration);
374 | double durationDecimal;
375 | int durationMilliseconds = 0;
376 | if (durationStr != null && double.TryParse(durationStr, NumberStyles.Any, CultureInfo.InvariantCulture, out durationDecimal))
377 | {
378 | durationMilliseconds = (int)(durationDecimal * 1000d);
379 | }
380 |
381 | TrySendOutput(flowId, message, fullName);
382 | TrySendReasonMessage(flowId, message, fullName);
383 |
384 | Write(new ServiceMessage(ServiceMessage.Names.TestFinished,
385 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
386 | new ServiceMessageAttr(ServiceMessageAttr.Names.Duration, durationMilliseconds.ToString()),
387 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
388 | }
389 |
390 | private void OnTestFailed(string flowId, XmlNode message, string fullName)
391 | {
392 | if (message == null)
393 | {
394 | throw new ArgumentNullException("message");
395 | }
396 |
397 | var errorMessage = message.SelectSingleNode("failure/message");
398 | var stackTrace = message.SelectSingleNode("failure/stack-trace");
399 |
400 | Write(new ServiceMessage(ServiceMessage.Names.TestFailed,
401 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
402 | new ServiceMessageAttr(ServiceMessageAttr.Names.Message, errorMessage == null ? string.Empty : errorMessage.InnerText),
403 | new ServiceMessageAttr(ServiceMessageAttr.Names.Details, stackTrace == null ? string.Empty : stackTrace.InnerText),
404 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
405 |
406 | OnTestFinished(flowId, message, fullName);
407 | }
408 |
409 | private void OnTestSkipped(string flowId, XmlNode message, string fullName)
410 | {
411 | if (message == null)
412 | {
413 | throw new ArgumentNullException("message");
414 | }
415 |
416 | TrySendOutput(flowId, message, fullName);
417 | var reason = message.SelectSingleNode("reason/message");
418 |
419 | Write(new ServiceMessage(ServiceMessage.Names.TestIgnored,
420 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
421 | new ServiceMessageAttr(ServiceMessageAttr.Names.Message, reason == null ? string.Empty : reason.InnerText),
422 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
423 | }
424 |
425 | private void OnTestInconclusive(string flowId, XmlNode message, string fullName)
426 | {
427 | if (message == null)
428 | {
429 | throw new ArgumentNullException("message");
430 | }
431 |
432 | TrySendOutput(flowId, message, fullName);
433 |
434 | Write(new ServiceMessage(ServiceMessage.Names.TestIgnored,
435 | new ServiceMessageAttr(ServiceMessageAttr.Names.Name, fullName),
436 | new ServiceMessageAttr(ServiceMessageAttr.Names.Message, "Inconclusive"),
437 | new ServiceMessageAttr(ServiceMessageAttr.Names.FlowId, flowId)));
438 | }
439 |
440 | private void Write(ServiceMessage serviceMessage)
441 | {
442 | var sb = new StringBuilder();
443 | using (var writer = new StringWriter(sb))
444 | {
445 | ServiceMessageWriter.Write(writer, serviceMessage);
446 | }
447 |
448 | _outWriter.WriteLine(sb.ToString());
449 | }
450 | }
451 | }
452 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Extensions/TestExtensions.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Globalization;
26 | using System.Linq;
27 | using System.Security.Cryptography;
28 | using System.Text;
29 | using System.Xml.Linq;
30 | using Microsoft.Extensions.Testing.Abstractions;
31 |
32 | namespace NUnit.Runner.Extensions
33 | {
34 | ///
35 | /// Converts between the Microsoft.Testing.Abstractions classes and the
36 | /// equivilent NUnit xml
37 | ///
38 | public static class TestExtensions
39 | {
40 | const double MIN_DURATION = 0.001d;
41 |
42 | static SHA1 SHA { get; } = SHA1.Create();
43 |
44 | ///
45 | /// Takes a string, signs it with a SHA1 algorithm and converts the
46 | /// resulting hash to a
47 | ///
48 | ///
49 | ///
50 | /// The SHA1 hash algorithm results in a 140 bit digest, but a
51 | /// Guid only stores 128 bits. Therefore, we are tossing out
52 | /// the last 12 bits of the SHA1 hash in order to convert the
53 | /// result to a Guid.
54 | ///
55 | ///
56 | ///
57 | ///
58 | public static Guid GetSignatureAsGuid(this string attribute)
59 | {
60 | var hash = SHA.ComputeHash(Encoding.Unicode.GetBytes(attribute));
61 | var b = new byte[16];
62 | Array.Copy(hash, b, 16);
63 | return new Guid(b);
64 | }
65 |
66 | ///
67 | /// Takes an NUnit id attribute and converts it to a Guid Id
68 | ///
69 | ///
70 | ///
71 | public static Guid ConvertToGuid(this XAttribute attribute)
72 | {
73 | if (attribute == null)
74 | return Guid.Empty;
75 |
76 | var hash = SHA.ComputeHash(Encoding.UTF8.GetBytes(attribute.Value));
77 | var guid = new byte[16];
78 | Array.Copy(hash, guid, 16);
79 | return new Guid(guid);
80 | }
81 |
82 | public static DateTimeOffset ConvertToDateTime(this XAttribute attribute)
83 | {
84 | var result = DateTimeOffset.UtcNow;
85 |
86 | if (attribute != null)
87 | DateTimeOffset.TryParse(attribute.Value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out result);
88 |
89 | return result;
90 | }
91 |
92 | ///
93 | /// Converts an NUnit XML duration in seconds into a TimeSpan
94 | ///
95 | ///
96 | ///
97 | public static TimeSpan ConvertToTimeSpan(this XAttribute attribute, TestOutcome outcome)
98 | {
99 | double duration = MIN_DURATION; // Some runners cannot handle a duration of 0
100 |
101 | if (outcome == TestOutcome.Skipped)
102 | return TimeSpan.FromTicks(1);
103 |
104 | if (attribute != null)
105 | double.TryParse(attribute.Value, out duration);
106 |
107 | return TimeSpan.FromSeconds(Math.Max(duration, MIN_DURATION));
108 | }
109 |
110 | public static TestOutcome ConvertToTestOutcome(this XAttribute attribute)
111 | {
112 | if (attribute == null)
113 | return TestOutcome.None;
114 |
115 | if(attribute.Value.StartsWith("Passed", StringComparison.Ordinal))
116 | return TestOutcome.Passed;
117 | if (attribute.Value.StartsWith("Failed", StringComparison.Ordinal))
118 | return TestOutcome.Failed;
119 | if (attribute.Value.StartsWith("Skipped", StringComparison.Ordinal))
120 | return TestOutcome.Skipped;
121 | if (attribute.Value.StartsWith("Inconclusive", StringComparison.Ordinal))
122 | return TestOutcome.Skipped;
123 |
124 | return TestOutcome.None;
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Interfaces/ITestListener.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Runner.Interfaces
25 | {
26 | public interface ITestListener
27 | {
28 | void OnTestEvent(string xml);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Navigation/NavigationDataProvider.cs:
--------------------------------------------------------------------------------
1 | // ****************************************************************
2 | // Copyright (c) 2016 NUnit Software. All rights reserved.
3 | // ****************************************************************
4 |
5 | using System.IO;
6 | using System.Linq;
7 | using System.Reflection;
8 | using Microsoft.DotNet.ProjectModel;
9 | using Microsoft.Extensions.Testing.Abstractions;
10 |
11 | namespace NUnit.Runner.Navigation
12 | {
13 | public class NavigationDataProvider
14 | {
15 | public static NavigationDataProvider GetNavigationDataProvider(string assemblyPath)
16 | {
17 | var directory = Path.GetDirectoryName(assemblyPath);
18 | var assembly = Path.GetFileNameWithoutExtension(assemblyPath);
19 | var pdbPath = Path.Combine(directory, assembly + FileNameSuffixes.DotNet.ProgramDatabase);
20 |
21 | if (!File.Exists(pdbPath)) return null;
22 |
23 | return new NavigationDataProvider(assemblyPath, pdbPath);
24 | }
25 |
26 | ISourceInformationProvider _provider;
27 | Assembly _assembly;
28 |
29 | NavigationDataProvider(string assembyPath, string pdbPath)
30 | : this(assembyPath, new SourceInformationProvider(pdbPath))
31 | {
32 | }
33 |
34 | NavigationDataProvider(string assemblyPath, ISourceInformationProvider provider)
35 | {
36 | _assembly = LoadAssembly(assemblyPath);
37 | _provider = provider;
38 | }
39 |
40 | public SourceInformation GetSourceData(string className, string methodName)
41 | {
42 | var type = _assembly.DefinedTypes.FirstOrDefault(t => t.FullName == className);
43 | var method = type?.DeclaredMethods.FirstOrDefault(m => m.Name == methodName);
44 | if (method == null) return null;
45 |
46 | return _provider.GetSourceInformation(method);
47 | }
48 |
49 | static Assembly LoadAssembly(string assemblyPath)
50 | {
51 | #if NET451
52 | return Assembly.LoadFrom(assemblyPath);
53 | #else
54 | var assembyName = Path.GetFileNameWithoutExtension(assemblyPath);
55 | return Assembly.Load(new AssemblyName(assembyName));
56 | // I think dotnet/coreclr#5060 is causing the following to fail because of . in the name?
57 | //return System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
58 | #endif
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Program.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 |
26 | namespace NUnit.Runner
27 | {
28 | public class Program
29 | {
30 | public static int Main(string[] args)
31 | {
32 | using (var testRunner = new TestRunner())
33 | return testRunner.Run(args);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyCompany("NUnit Software")]
9 | [assembly: AssemblyProduct("dotnet_test_nunit")]
10 | [assembly: AssemblyCopyright("Copyright (C) 2016 NUnit Project")]
11 | [assembly: AssemblyTrademark("NUnit is a trademark of NUnit Software")]
12 |
13 | #if DEBUG
14 | [assembly: AssemblyConfiguration("Debug")]
15 | #else
16 | [assembly: AssemblyConfiguration("")]
17 | #endif
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/ResultReporter.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System.Globalization;
25 | using System.Linq;
26 | using System.Xml.Linq;
27 | using NUnit.Engine;
28 |
29 | namespace NUnit.Runner
30 | {
31 | public class ResultReporter
32 | {
33 | ColorConsoleWriter _writer;
34 | CommandLineOptions _options;
35 | XElement _result;
36 | int _reportIndex = 0;
37 | string _overallResult;
38 |
39 | public ResultReporter(ResultSummary summary, ColorConsoleWriter writer, CommandLineOptions options)
40 | {
41 | _writer = writer;
42 | _options = options;
43 |
44 | Summary = summary;
45 |
46 | TestResults = Summary.GetTestResults();
47 |
48 | _result = TestResults.FirstNode as XElement;
49 |
50 | _overallResult = Summary.Result;
51 | if (_overallResult == "Skipped")
52 | _overallResult = "Warning";
53 | }
54 |
55 | public ResultSummary Summary { get; }
56 |
57 | public XDocument TestResults { get; }
58 |
59 | ///
60 | /// Reports the results to the console
61 | ///
62 | public void ReportResults()
63 | {
64 | _writer.WriteLine();
65 |
66 | if (Summary.ExplicitCount + Summary.SkipCount + Summary.IgnoreCount > 0)
67 | WriteNotRunReport();
68 |
69 | if (_overallResult == "Failed")
70 | WriteErrorsAndFailuresReport();
71 |
72 | WriteRunSettingsReport();
73 |
74 | WriteSummaryReport();
75 | }
76 |
77 | #region Summary Report
78 |
79 | public void WriteRunSettingsReport()
80 | {
81 | var firstSuite = _result.Element("test-suite");
82 | if (firstSuite != null)
83 | {
84 | var settings = firstSuite.Element("settings")?.Elements("setting");
85 |
86 | if (settings != null && settings.Count() > 0)
87 | {
88 | _writer.WriteLine(ColorStyle.SectionHeader, "Run Settings");
89 |
90 | foreach (XElement node in settings)
91 | {
92 | string name = node.Attribute("name")?.Value;
93 | string val = node.Attribute("value")?.Value;
94 | _writer.WriteLabelLine($" {name}: ", val);
95 | }
96 | _writer.WriteLine();
97 | }
98 | }
99 | }
100 |
101 | public void WriteSummaryReport()
102 | {
103 | ColorStyle overall = _overallResult == "Passed"
104 | ? ColorStyle.Pass
105 | : _overallResult == "Failed"
106 | ? ColorStyle.Failure
107 | : _overallResult == "Warning"
108 | ? ColorStyle.Warning
109 | : ColorStyle.Output;
110 |
111 | _writer.WriteLine(ColorStyle.SectionHeader, "Test Run Summary");
112 | _writer.WriteLabelLine(" Overall result: ", _overallResult, overall);
113 |
114 | WriteSummaryCount(" Test Count: ", Summary.TestCount);
115 | WriteSummaryCount(", Passed: ", Summary.PassCount);
116 | WriteSummaryCount(", Failed: ", Summary.FailedCount, ColorStyle.Failure);
117 | WriteSummaryCount(", Inconclusive: ", Summary.InconclusiveCount);
118 | WriteSummaryCount(", Skipped: ", Summary.TotalSkipCount);
119 | _writer.WriteLine();
120 |
121 | if (Summary.FailedCount > 0)
122 | {
123 | WriteSummaryCount(" Failed Tests - Failures: ", Summary.FailureCount);
124 | WriteSummaryCount(", Errors: ", Summary.ErrorCount, ColorStyle.Error);
125 | WriteSummaryCount(", Invalid: ", Summary.InvalidCount);
126 | _writer.WriteLine();
127 | }
128 | if (Summary.TotalSkipCount > 0)
129 | {
130 | WriteSummaryCount(" Skipped Tests - Ignored: ", Summary.IgnoreCount);
131 | WriteSummaryCount(", Explicit: ", Summary.ExplicitCount);
132 | WriteSummaryCount(", Other: ", Summary.SkipCount);
133 | _writer.WriteLine();
134 | }
135 |
136 | _writer.WriteLabelLine(" Start time: ", Summary.StartTime.ToString("u"));
137 | _writer.WriteLabelLine(" End time: ", Summary.EndTime.ToString("u"));
138 | _writer.WriteLabelLine(" Duration: ", $"{Summary.Duration.ToString("0.000")} seconds");
139 | _writer.WriteLine();
140 | }
141 |
142 | #endregion
143 |
144 | #region Errors and Failures Report
145 |
146 | public void WriteErrorsAndFailuresReport()
147 | {
148 | _reportIndex = 0;
149 | _writer.WriteLine(ColorStyle.SectionHeader, "Errors and Failures");
150 | _writer.WriteLine();
151 | WriteErrorsAndFailures(_result);
152 |
153 | if (_options.StopOnError)
154 | {
155 | _writer.WriteLine(ColorStyle.Failure, "Execution terminated after first error");
156 | _writer.WriteLine();
157 | }
158 | }
159 |
160 | void WriteErrorsAndFailures(XElement result)
161 | {
162 | string resultState = result.Attribute("result")?.Value;
163 |
164 | switch (result.Name?.ToString())
165 | {
166 | case "test-case":
167 | if (resultState == "Failed")
168 | WriteSingleResult(result, ColorStyle.Failure);
169 | return;
170 |
171 | case "test-run":
172 | foreach (XElement childResult in result.Elements())
173 | WriteErrorsAndFailures(childResult);
174 | break;
175 |
176 | case "test-suite":
177 | if (resultState == "Failed")
178 | {
179 | if (result.Attribute("type")?.Value == "Theory")
180 | {
181 | WriteSingleResult(result, ColorStyle.Failure);
182 | }
183 | else
184 | {
185 | var site = result.Attribute("site")?.Value;
186 | if (site != "Parent" && site != "Child")
187 | WriteSingleResult(result, ColorStyle.Failure);
188 | if (site == "SetUp") return;
189 | }
190 | }
191 |
192 | foreach (XElement childResult in result.Elements())
193 | WriteErrorsAndFailures(childResult);
194 |
195 | break;
196 | }
197 | }
198 |
199 | #endregion
200 |
201 | #region Not Run Report
202 |
203 | public void WriteNotRunReport()
204 | {
205 | _reportIndex = 0;
206 | _writer.WriteLine(ColorStyle.SectionHeader, "Tests Not Run");
207 | _writer.WriteLine();
208 | WriteNotRunResults(_result);
209 | }
210 |
211 | void WriteNotRunResults(XElement result)
212 | {
213 | switch (result.Name?.ToString())
214 | {
215 | case "test-case":
216 | string status = result.Attribute("result")?.Value;
217 |
218 | if (status == "Skipped")
219 | {
220 | string label = result.Attribute("label")?.Value;
221 |
222 | var colorStyle = label == "Ignored"
223 | ? ColorStyle.Warning
224 | : ColorStyle.Output;
225 |
226 | WriteSingleResult(result, colorStyle);
227 | }
228 | break;
229 |
230 | case "test-suite":
231 | case "test-run":
232 | foreach (XElement childResult in result.Elements())
233 | WriteNotRunResults(childResult);
234 |
235 | break;
236 | }
237 | }
238 |
239 | #endregion
240 |
241 | #region Helper Methods
242 |
243 | void WriteSummaryCount(string label, int count)
244 | {
245 | _writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture));
246 | }
247 |
248 | void WriteSummaryCount(string label, int count, ColorStyle color)
249 | {
250 | _writer.WriteLabel(label, count.ToString(CultureInfo.CurrentUICulture), count > 0 ? color : ColorStyle.Value);
251 | }
252 |
253 | static readonly char[] EOL_CHARS = { '\r', '\n' };
254 |
255 | void WriteSingleResult(XElement result, ColorStyle colorStyle)
256 | {
257 | string status = result.Attribute("label")?.Value;
258 | if (status == null)
259 | status = result.Attribute("result")?.Value;
260 |
261 | if (status == "Failed" || status == "Error")
262 | {
263 | var site = result.Attribute("site")?.Value;
264 | if (site == "SetUp" || site == "TearDown")
265 | status = site + " " + status;
266 | }
267 |
268 | string fullName = result.Attribute("fullname")?.Value;
269 |
270 | _writer.WriteLine(colorStyle, $"{++_reportIndex}) {status} : {fullName}");
271 |
272 | XElement failureNode = result.Element("failure");
273 | if (failureNode != null)
274 | {
275 | string message = failureNode.Element("message")?.Value;
276 | string stacktrace = failureNode.Element("stack-trace")?.Value;
277 |
278 | // In order to control the format, we trim any line-end chars
279 | // from end of the strings we write and supply them via calls
280 | // to WriteLine(). Newlines within the strings are retained.
281 |
282 | if (message != null)
283 | _writer.WriteLine(colorStyle, message.TrimEnd(EOL_CHARS));
284 |
285 | if (stacktrace != null)
286 | _writer.WriteLine(colorStyle, stacktrace.TrimEnd(EOL_CHARS));
287 | }
288 |
289 | XElement reasonNode = result.Element("reason");
290 | if (reasonNode != null)
291 | {
292 | string message = reasonNode.Element("message")?.Value;
293 |
294 | if (message != null)
295 | _writer.WriteLine(colorStyle, message.TrimEnd(EOL_CHARS));
296 | }
297 |
298 | _writer.WriteLine(); // Skip after each item
299 | }
300 |
301 | #endregion
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/ReturnCodes.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Runner
25 | {
26 | class ReturnCodes
27 | {
28 | #region Console Runner Return Codes
29 |
30 | public static readonly int OK = 0;
31 | public static readonly int INVALID_ARG = -1;
32 | public static readonly int INVALID_ASSEMBLY = -2;
33 | public static readonly int INVALID_TEST_FIXTURE = -4;
34 | public static readonly int UNEXPECTED_ERROR = -100;
35 |
36 | #endregion
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Sinks/Messages.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | namespace NUnit.Runner.Sinks
25 | {
26 | ///
27 | /// Defines for messages
28 | ///
29 | public static class Messages
30 | {
31 | // ITestSink
32 | public const string TestCompleted = "TestRunner.TestCompleted";
33 | public const string WaitingCommand = "TestRunner.WaitingCommand";
34 |
35 | // ITestDiscoverySink
36 | public const string TestFound = "TestDiscovery.TestFound";
37 |
38 | // ITestExecutionSink
39 | public const string TestStarted = "TestExecution.TestStarted";
40 | public const string TestResult = "TestExecution.TestResult";
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Sinks/RemoteTestDiscoverySink.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 |
28 | namespace NUnit.Runner.Sinks
29 | {
30 | public class RemoteTestDiscoverySink : RemoteTestSink, ITestDiscoverySink
31 | {
32 | public RemoteTestDiscoverySink(BinaryWriter binaryWriter) : base(binaryWriter)
33 | {
34 | }
35 |
36 | public void SendTestFound(Test test)
37 | {
38 | if (test == null)
39 | throw new ArgumentNullException(nameof(test));
40 |
41 | SendMessage(Messages.TestFound, test);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Sinks/RemoteTestExecutionSink.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 |
28 | namespace NUnit.Runner.Sinks
29 | {
30 | public class RemoteTestExecutionSink : RemoteTestSink, ITestExecutionSink
31 | {
32 | public RemoteTestExecutionSink(BinaryWriter binaryWriter) : base(binaryWriter)
33 | {
34 | }
35 |
36 | public void SendTestStarted(Test test)
37 | {
38 | if (test == null)
39 | throw new ArgumentNullException(nameof(test));
40 |
41 | SendMessage(Messages.TestStarted, test);
42 | }
43 |
44 | public void SendTestResult(TestResult testResult)
45 | {
46 | if (testResult == null)
47 | throw new ArgumentNullException(nameof(testResult));
48 |
49 | SendMessage(Messages.TestResult, testResult);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/Sinks/RemoteTestSink.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System.IO;
25 | using Microsoft.Extensions.Testing.Abstractions;
26 | using Newtonsoft.Json;
27 | using Newtonsoft.Json.Linq;
28 |
29 | namespace NUnit.Runner.Sinks
30 | {
31 | public class RemoteTestSink : ITestSink
32 | {
33 | protected BinaryWriter BinaryWriter { get; }
34 |
35 | protected RemoteTestSink(BinaryWriter binaryWriter)
36 | {
37 | BinaryWriter = binaryWriter;
38 | }
39 |
40 | public void SendTestCompleted()
41 | {
42 | SendMessage(Messages.TestCompleted);
43 | }
44 |
45 | public void SendWaitingCommand()
46 | {
47 | SendMessage(Messages.WaitingCommand);
48 | }
49 |
50 | protected void SendMessage(string messageType, object payload = null)
51 | {
52 | var msg = new Message
53 | {
54 | MessageType = messageType,
55 | Payload = payload != null ? JToken.FromObject(payload) : null
56 | };
57 | var json = JsonConvert.SerializeObject(msg);
58 | BinaryWriter.Write(json);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/TestListeners/BaseTestListener.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Xml.Linq;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 | using NUnit.Runner.Extensions;
28 | using NUnit.Runner.Interfaces;
29 | using NUnit.Runner.Navigation;
30 |
31 | namespace NUnit.Runner.TestListeners
32 | {
33 | public abstract class BaseTestListener : ITestListener
34 | {
35 | readonly string _assemblyPath;
36 | readonly NavigationDataProvider _provider;
37 |
38 | protected CommandLineOptions Options { get; }
39 |
40 | ///
41 | /// Constructs a
42 | ///
43 | /// The command line options passed into this run
44 | /// The full path of the assembly that is being executed or explored
45 | public BaseTestListener(CommandLineOptions options, string assemblyPath)
46 | {
47 | Options = options;
48 | _assemblyPath = assemblyPath;
49 | _provider = NavigationDataProvider.GetNavigationDataProvider(assemblyPath);
50 | }
51 |
52 | public abstract void OnTestEvent(string xml);
53 |
54 | protected Test ParseTest(XElement xml)
55 | {
56 | var className = xml.Attribute("classname")?.Value;
57 | var methodName = xml.Attribute("methodname")?.Value;
58 | var sourceData = _provider?.GetSourceData(className, methodName);
59 |
60 | //use the _assemblyPath, the test case Id attribute,
61 | //and the fullName attribute to generate a unique signature
62 | //for this test.
63 | //
64 | //Originally, just the id was used, but the id from the
65 | //xml attribute is not sufficient, because different
66 | //projects in the same solution will generate the same
67 | //id. In "Design" mode, this causes a conflict within
68 | //Visual Studio and causes tests to get all whacked up.
69 | //This is a fix for dotnet-test-nunit#58
70 | //
71 | //However, another issue was discovered (dotnet-test-nunit#87)
72 | //Turns out, the assembly name and test id is also not sufficient.
73 | //During the discovery process, Visual Studio will not
74 | //update the internal value for FulluyQualifiedName for
75 | //a test if the Guid does not change. Therefore, if you
76 | //change the values of a TestCase, and they have the same
77 | //test ID, then visual Studio will ignore the new
78 | //FullyQualifiedName returned during test discovery.
79 | //While it ignores the new FullyQualifiedName, it will
80 | //update the DisplayName, which made debugging this
81 | //very frustrating. Nonetheless, to force a new
82 | //guid, we use the fullname of the testcase in the
83 | //Guid/signature generation.
84 | string uniqueName = xml.Attribute("id")
85 | + "|"
86 | + _assemblyPath
87 | + "|"
88 | + xml.Attribute("fullname")?.Value ?? "";
89 | Guid testSignature = uniqueName.GetSignatureAsGuid();
90 |
91 | var test = new Test
92 | {
93 | Id = testSignature,
94 | DisplayName = xml.Attribute("name")?.Value ?? "",
95 | FullyQualifiedName = xml.Attribute("fullname")?.Value ?? "",
96 | CodeFilePath = sourceData?.Filename,
97 | LineNumber = sourceData?.LineNumber
98 | };
99 | // Add properties
100 | var properties = xml.Descendants("property");
101 | foreach(var property in properties)
102 | {
103 | var name = property.Attribute("name")?.Value ?? "";
104 | var value = property.Attribute("value")?.Value ?? "";
105 | // TODO: When there is a way to support multiple categories, look
106 | // for the Category key and append them.
107 | test.Properties[name] = value;
108 | }
109 | return test;
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/TestListeners/TestExecutionListener.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Text.RegularExpressions;
26 | using System.Linq;
27 | using System.Xml.Linq;
28 | using Microsoft.Extensions.Testing.Abstractions;
29 | using NUnit.Runner.Extensions;
30 |
31 | namespace NUnit.Runner.TestListeners
32 | {
33 | public class TestEventArgs : EventArgs
34 | {
35 | public string TestName { get; }
36 |
37 | public string TestOutput { get; }
38 |
39 | public TestEventArgs(string testName, string testOutput)
40 | {
41 | TestName = testName;
42 | TestOutput = testOutput;
43 | }
44 | }
45 | public class TestOutputEventArgs : TestEventArgs
46 | {
47 | public string Stream { get; }
48 |
49 | public TestOutputEventArgs(string testName, string testOutput, string stream)
50 | : base(testName, testOutput)
51 | {
52 | Stream = stream;
53 | }
54 | }
55 |
56 | public class TestExecutionListener : BaseTestListener
57 | {
58 | public event EventHandler TestStarted;
59 | public event EventHandler TestFinished;
60 | public event EventHandler SuiteFinished;
61 | public event EventHandler TestOutput;
62 |
63 | readonly ITestExecutionSink _sink;
64 |
65 | public TestExecutionListener(ITestExecutionSink sink, CommandLineOptions options, string assemblyPath)
66 | : base(options, assemblyPath)
67 | {
68 | _sink = sink;
69 | }
70 |
71 | public override void OnTestEvent(string xml)
72 | {
73 | var element = XElement.Parse(xml);
74 | switch (element?.Name?.LocalName)
75 | {
76 | case "start-suite":
77 | break;
78 | case "test-suite":
79 | OnTestSuite(element);
80 | break;
81 | case "start-test":
82 | OnStartTest(element);
83 | break;
84 | case "test-case":
85 | OnTestCase(element);
86 | break;
87 | case "test-output":
88 | OnTestOutput(element);
89 | break;
90 | default:
91 | //Console.WriteLine(xml);
92 | break;
93 | }
94 | }
95 |
96 | void OnStartTest(XElement xml)
97 | {
98 | var test = ParseTest(xml);
99 |
100 | TestStarted?.Invoke(this, new TestEventArgs(test.FullyQualifiedName, null));
101 |
102 | if (Options.DesignTime)
103 | _sink?.SendTestStarted(test);
104 | }
105 |
106 | void OnTestCase(XElement xml)
107 | {
108 | var testResult = ParseTestResult(xml);
109 |
110 | string output = null;
111 |
112 | if (testResult.Messages.Count > 0)
113 | output = testResult.Messages[0];
114 | else if (testResult.Outcome != TestOutcome.None)
115 | output = testResult.Outcome.ToString();
116 |
117 | TestFinished?.Invoke(this, new TestEventArgs(testResult.Test.FullyQualifiedName, output));
118 |
119 | if (Options.DesignTime)
120 | _sink?.SendTestResult(testResult);
121 | }
122 |
123 | void OnTestSuite(XElement xml)
124 | {
125 | var testName = xml.Attribute("fullname")?.Value;
126 | var output = xml.Elements("output").FirstOrDefault()?.Value;
127 |
128 | SuiteFinished?.Invoke(this, new TestEventArgs(testName, output));
129 | }
130 |
131 | void OnTestOutput(XElement xml)
132 | {
133 | var testName = xml.Attribute("testname")?.Value;
134 | var stream = xml.Attribute("stream")?.Value;
135 | var output = xml.Value;
136 | TestOutput?.Invoke(this, new TestOutputEventArgs(testName, output, stream));
137 | }
138 |
139 | protected TestResult ParseTestResult(XElement xml)
140 | {
141 | var test = ParseTest(xml);
142 | var outcomeAttr = xml.Attribute("result").ConvertToTestOutcome();
143 |
144 | var testResult = new TestResult(test)
145 | {
146 | StartTime = xml.Attribute("start-time").ConvertToDateTime(),
147 | EndTime = xml.Attribute("end-time").ConvertToDateTime(),
148 | Outcome = outcomeAttr,
149 | Duration = xml.Attribute("duration").ConvertToTimeSpan(outcomeAttr),
150 | ComputerName = Environment.MachineName
151 | };
152 | // Output, Messages and stack traces
153 | testResult.ErrorMessage = GetErrorMessage(xml);
154 | testResult.ErrorStackTrace = xml.Element("failure")?.Element("stack-trace")?.Value;
155 | string messages = xml.Element("output")?.Value;
156 | if (!string.IsNullOrWhiteSpace(messages))
157 | testResult.Messages.Add(messages);
158 | return testResult;
159 | }
160 |
161 | string GetErrorMessage(XElement xml)
162 | {
163 | var message = xml.Element("failure")?.Element("message")?.Value;
164 | if(!string.IsNullOrWhiteSpace(message))
165 | {
166 | // If we're running in the IDE, remove any caret line from the message
167 | // since it will be displayed using a variable font and won't make sense.
168 | if (Options.DesignTime)
169 | {
170 | string pattern = Environment.NewLine + " -*\\^" + Environment.NewLine;
171 | message = Regex.Replace(message, pattern, Environment.NewLine, RegexOptions.Multiline);
172 | }
173 | }
174 | else
175 | {
176 | message = xml.Element("reason")?.Element("message")?.Value;
177 | }
178 | return message;
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/TestListeners/TestExploreListener.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Xml.Linq;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 |
28 | namespace NUnit.Runner.TestListeners
29 | {
30 | public class TestExploreListener : BaseTestListener
31 | {
32 | readonly ITestDiscoverySink _sink;
33 |
34 | public TestExploreListener(ITestDiscoverySink sink, CommandLineOptions options, string assemblyPath)
35 | : base(options, assemblyPath)
36 | {
37 | _sink = sink;
38 | }
39 |
40 | public override void OnTestEvent(string xml)
41 | {
42 | var element = XElement.Parse(xml);
43 | var tests = element.Descendants("test-case");
44 | foreach(var test in tests)
45 | {
46 | OnTestCaseFound(test);
47 | }
48 | }
49 |
50 | void OnTestCaseFound(XElement testCase)
51 | {
52 | var test = ParseTest(testCase);
53 | if(Options.DesignTime)
54 | _sink.SendTestFound(test);
55 | else
56 | Console.WriteLine(test.FullyQualifiedName);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/dotnet-test-nunit.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | 7fc6dced-278a-449b-8bb0-95346410c8d2
10 | NUnit.Runner
11 | .\obj
12 | .\bin\
13 | v4.6.1
14 |
15 |
16 | 2.0
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/dotnet-test-nunit/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "copyright": "Copyright (C) 2016 NUnit Project",
3 | "authors": [ "Rob Prouse" ],
4 | "title": "NUnit .NET Core Runner",
5 | "description": "NUnit console and Visual Studio runner for .NET Core and .NET 4.5.1+",
6 | "name": "dotnet-test-nunit",
7 | "version": "3.3.0",
8 | "buildOptions": {
9 | "emitEntryPoint": true,
10 | "preserveCompilationContext": true,
11 | "warningsAsErrors": true
12 | },
13 | "packOptions": {
14 | "requireLicenseAcceptance": false,
15 | "tags": [ "testing", "tdd", "dotnet", "core", "nunit" ],
16 | "iconUrl": "https://cdn.rawgit.com/nunit/resources/master/images/icon/nunit_256.png",
17 | "licenseUrl": "https://raw.githubusercontent.com/nunit/dotnet-test-nunit/master/LICENSE",
18 | "projectUrl": "https://github.com/nunit/dotnet-test-nunit",
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/nunit/dotnet-test-nunit"
22 | }
23 | },
24 |
25 | "dependencies": {
26 | "Microsoft.Extensions.Testing.Abstractions": "1.0.0-preview2-003121",
27 | "Microsoft.Extensions.DependencyModel": "1.0.0",
28 | "NUnit.Portable.Agent": "3.4.0-beta-3",
29 | "NUnit.Result.Writer.V2": "1.0.0"
30 | },
31 |
32 | "frameworks": {
33 | "netcoreapp1.0": {
34 | "dependencies": {
35 | "Microsoft.NETCore.App": {
36 | "version": "1.0.0",
37 | "type": "platform"
38 | },
39 | "System.Xml.XmlDocument": "4.0.1",
40 | "System.Xml.XPath.XmlDocument": "4.0.1"
41 | }
42 | },
43 | "net451": {
44 | "dependencies": {
45 | "Microsoft.NETCore.Platforms": "1.0.1"
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test.runner/Program.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Reflection;
26 | using NUnit.Common;
27 | using NUnit.Runner.Test.Sinks;
28 | using NUnitLite;
29 |
30 | namespace NUnit.Runner.Test.Runner
31 | {
32 | public class Program
33 | {
34 | // TODO: Once dotnet-test-nunit is capable of testing itself, remove this test runner
35 | public static int Main(string[] args)
36 | {
37 | var result = new AutoRun(typeof(RemoteTestDiscoverySinkTests).GetTypeInfo().Assembly)
38 | .Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
39 | return result;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test.runner/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("NUnit Software")]
10 | [assembly: AssemblyProduct("dotnet_test_nunit.test.runner")]
11 | [assembly: AssemblyCopyright("Copyright (C) 2016 NUnit Project")]
12 | [assembly: AssemblyTrademark("NUnit is a trademark of NUnit Software")]
13 |
14 | // Setting ComVisible to false makes the types in this assembly not visible
15 | // to COM components. If you need to access a type in this assembly from
16 | // COM, set the ComVisible attribute to true on that type.
17 | [assembly: ComVisible(false)]
18 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test.runner/dotnet-test-nunit.test.runner.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | f2025265-8a4e-46dd-ae91-537e302b3f24
10 | NUnit.Runner.Test.Runner
11 | .\obj
12 | .\bin\
13 | v4.6.1
14 |
15 |
16 | 2.0
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test.runner/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "copyright": "Copyright (C) 2016 NUnit Project",
3 | "authors": [ "Rob Prouse" ],
4 | "title": "NUnit .NET Core Runner Test Runner",
5 | "name": "dotnet-test-nunit.test.runner",
6 | "version": "3.4.0-*",
7 | "buildOptions": {
8 | "emitEntryPoint": true,
9 | "preserveCompilationContext": true,
10 | "warningsAsErrors": true
11 | },
12 |
13 | "dependencies": {
14 | "NUnitLite": "3.5.0",
15 | "dotnet-test-nunit": {
16 | "target": "project"
17 | },
18 | "dotnet-test-nunit.test": {
19 | "target": "project"
20 | }
21 | },
22 |
23 | "frameworks": {
24 | "netcoreapp1.0": {
25 | "imports": "dotnet5.6",
26 | "dependencies": {
27 | "Microsoft.NETCore.App": {
28 | "type": "platform",
29 | "version": "1.0.0"
30 | },
31 | "System.IO.FileSystem": "4.0.1",
32 | "System.Console": "4.0.0"
33 | }
34 | },
35 | "net451": {}
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/ColorConsoleTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using NUnit.Framework;
26 |
27 | namespace NUnit.Runner.Test
28 | {
29 | [TestFixture]
30 | public class ColorConsoleTests
31 | {
32 | private ColorStyle _testStyle;
33 |
34 | [SetUp]
35 | public void SetUp()
36 | {
37 | // Find a test color that is different than the console color
38 | if (Console.ForegroundColor != ColorConsole.GetColor(ColorStyle.Error))
39 | _testStyle = ColorStyle.Error;
40 | else if (Console.ForegroundColor != ColorConsole.GetColor(ColorStyle.Pass))
41 | _testStyle = ColorStyle.Pass;
42 | else
43 | Assert.Inconclusive("Could not find a color to test with");
44 |
45 | // Set to an unknown, unlikely color so that we can test for change
46 | Console.ForegroundColor = ConsoleColor.Magenta;
47 |
48 | Assume.That(Console.ForegroundColor, Is.EqualTo(ConsoleColor.Magenta), "Color tests cannot be run because the current console does not support color");
49 | }
50 |
51 | [TearDown]
52 | public void TearDown()
53 | {
54 | Console.ResetColor();
55 | }
56 |
57 | [Test]
58 | public void TestConstructor()
59 | {
60 | ConsoleColor expected = ColorConsole.GetColor(_testStyle);
61 | using (new ColorConsole(_testStyle))
62 | {
63 | Assert.That(Console.ForegroundColor, Is.EqualTo(expected));
64 | }
65 | Assert.That(Console.ForegroundColor, Is.Not.EqualTo(expected));
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/ColorStyleTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using NUnit.Framework;
26 |
27 | namespace NUnit.Runner.Test
28 | {
29 | [TestFixture]
30 | public class ColorStyleTests
31 | {
32 | // We can only test colors that are the same for all console backgrounds
33 | [TestCase(ColorStyle.Pass, ConsoleColor.Green)]
34 | [TestCase(ColorStyle.Failure, ConsoleColor.Red)]
35 | [TestCase(ColorStyle.Error, ConsoleColor.Red)]
36 | public void TestGetColor(ColorStyle style, ConsoleColor expected)
37 | {
38 | Assert.That(ColorConsole.GetColor(style), Is.EqualTo(expected));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/EnvTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using NUnit.Framework;
25 |
26 | namespace NUnit.Runner.Test
27 | {
28 | [TestFixture]
29 | public class EnvTests
30 | {
31 | [Test]
32 | public void DocumentFolderIsNotNull()
33 | {
34 | Assert.That(Env.DocumentFolder, Is.Not.Null.Or.Empty);
35 | }
36 |
37 | [Test]
38 | public void DefaultWorkDirectoryIsNotNull()
39 | {
40 | Assert.That(Env.DefaultWorkDirectory, Is.Not.Null.Or.Empty);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Extensions/TestExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.Xml.Linq;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 | using NUnit.Framework;
28 | using NUnit.Runner.Extensions;
29 |
30 | namespace NUnit.Runner.Test.Extensions
31 | {
32 | [TestFixture]
33 | public class TestExtensionsTests
34 | {
35 | [Test]
36 | public void CanConvertIdToGuid()
37 | {
38 | var attr = new XAttribute("id", "10");
39 | var guid = attr.ConvertToGuid();
40 | Assert.That(guid, Is.Not.EqualTo(Guid.Empty));
41 | }
42 |
43 | [Test]
44 | public void NullIdConvertsToEmpty()
45 | {
46 | XAttribute attr = null;
47 | var guid = attr.ConvertToGuid();
48 | Assert.That(guid, Is.EqualTo(Guid.Empty));
49 | }
50 |
51 | [Test]
52 | public void CanConvertToDateTime()
53 | {
54 | var attr = new XAttribute("start-time", "2016-05-26 19:43:09Z");
55 | var date = attr.ConvertToDateTime();
56 | Assert.That(date.Year, Is.EqualTo(2016));
57 | Assert.That(date.Month, Is.EqualTo(5));
58 | Assert.That(date.Day, Is.EqualTo(26));
59 | Assert.That(date.Hour, Is.EqualTo(19));
60 | Assert.That(date.Minute, Is.EqualTo(43));
61 | Assert.That(date.Second, Is.EqualTo(9));
62 | Assert.That(date.Offset.TotalHours, Is.EqualTo(0d));
63 | }
64 |
65 | [Test]
66 | public void NullDateTimeConvertsToNow()
67 | {
68 | XAttribute attr = null;
69 | var date = attr.ConvertToDateTime();
70 | var now = DateTime.UtcNow;
71 | Assert.That(date.Year, Is.EqualTo(now.Year));
72 | Assert.That(date.Month, Is.EqualTo(now.Month));
73 | Assert.That(date.Day, Is.EqualTo(now.Day));
74 | Assert.That(date.Hour, Is.EqualTo(now.Hour));
75 | Assert.That(date.Minute, Is.EqualTo(now.Minute));
76 | }
77 |
78 | [TestCase("1", 1d)]
79 | [TestCase("0.1", 0.1d)]
80 | [TestCase("0.001", 0.001d)]
81 | [TestCase("0.017533", 0.017533d)]
82 | [TestCase("0.0001", 0.001d, Description = "Minimum TimeSpan of 1 ms")]
83 | [TestCase("", 0.001d, Description = "Default TimeSpan of 1 ms")]
84 | public void CanConvertDurations(string duration, double expected)
85 | {
86 | var durationAttr = new XAttribute("duration", duration);
87 | var outcomeAttr = TestOutcome.Passed;
88 |
89 | var ts = durationAttr.ConvertToTimeSpan(outcomeAttr);
90 | Assert.That(ts.TotalSeconds, Is.EqualTo(expected).Within(0.001d));
91 | }
92 |
93 | [TestCase("1", 0.0000001d)]
94 | [TestCase("", 0.0000001d)]
95 | public void IgnoredTestsHaveDurationOf1Tick(string duration, double expected)
96 | {
97 | var durationAttr = new XAttribute("duration", duration);
98 | var outcomeAttr = TestOutcome.Skipped;
99 |
100 | var ts = durationAttr.ConvertToTimeSpan(outcomeAttr);
101 | Assert.That(ts.TotalSeconds, Is.EqualTo(expected).Within(0.001d));
102 | }
103 |
104 | [TestCase("Passed", TestOutcome.Passed)]
105 | [TestCase("Failed", TestOutcome.Failed)]
106 | [TestCase("Skipped", TestOutcome.Skipped)]
107 | [TestCase("Inconclusive", TestOutcome.Skipped)]
108 | [TestCase("", TestOutcome.None)]
109 | public void CanConvertTestOutcomes(string status, TestOutcome expected)
110 | {
111 | var attr = new XAttribute("status", status);
112 | var outcome = attr.ConvertToTestOutcome();
113 | Assert.That(outcome, Is.EqualTo(expected));
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Mocks/MockTestExecutionSink.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using Microsoft.Extensions.Testing.Abstractions;
25 | using MsTest = Microsoft.Extensions.Testing.Abstractions.Test;
26 | using MsTestResult = Microsoft.Extensions.Testing.Abstractions.TestResult;
27 |
28 | namespace NUnit.Runner.Test.Mocks
29 | {
30 | public class MockTestExecutionSink : ITestExecutionSink
31 | {
32 | public bool WaitingCommandReceived { get; private set; }
33 |
34 | public MsTest TestStarted { get; private set; }
35 |
36 | public bool TestCompletedReceived { get; private set; }
37 |
38 | public MsTestResult TestResult { get; private set; }
39 |
40 | public void SendWaitingCommand()
41 | {
42 | WaitingCommandReceived = true;
43 | }
44 |
45 | public void SendTestStarted(MsTest test)
46 | {
47 | TestStarted = test;
48 | }
49 |
50 | public void SendTestCompleted()
51 | {
52 | TestCompletedReceived = true;
53 | }
54 |
55 | public void SendTestResult(MsTestResult testResult)
56 | {
57 | TestResult = testResult;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Mocks/MockTestExplorerSink.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using Microsoft.Extensions.Testing.Abstractions;
25 | using MsTest = Microsoft.Extensions.Testing.Abstractions.Test;
26 |
27 | namespace NUnit.Runner.Test.Mocks
28 | {
29 | public class MockTestExplorerSink : ITestDiscoverySink
30 | {
31 | public bool WaitingCommandReceived { get; private set; }
32 |
33 | public bool TestCompletedReceived { get; private set; }
34 |
35 | public MsTest TestFound { get; set; }
36 |
37 | public void SendWaitingCommand()
38 | {
39 | WaitingCommandReceived = true;
40 | }
41 |
42 | public void SendTestCompleted()
43 | {
44 | TestCompletedReceived = true;
45 | }
46 |
47 | public void SendTestFound(MsTest test)
48 | {
49 | TestFound = test;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Navigation/NavigationDataProviderTests.cs:
--------------------------------------------------------------------------------
1 | // ****************************************************************
2 | // Copyright (c) 2016 NUnit Software. All rights reserved.
3 | // ****************************************************************
4 |
5 | using System.Reflection;
6 | using NUnit.Framework;
7 | using NUnit.Runner.Navigation;
8 |
9 | namespace NUnit.Runner.Test.Navigation
10 | {
11 | [TestFixture]
12 | public class NavigationDataProviderTests
13 | {
14 | const string Prefix = "NUnit.Runner.Test.Navigation.NavigationTestData";
15 |
16 | NavigationDataProvider _provider;
17 |
18 | [SetUp]
19 | public void SetUp()
20 | {
21 | var path = typeof(NavigationDataProviderTests).GetTypeInfo().Assembly.Location;
22 | //string path = Path.Combine(Directory.GetCurrentDirectory(), "dotnet-test-nunit.test.dll");
23 | _provider = NavigationDataProvider.GetNavigationDataProvider(path);
24 | Assert.That(_provider, Is.Not.Null, $"Could not create the NavigationDataProvider for {path}");
25 | }
26 |
27 | [TestCase("", "EmptyMethod_OneLine", 9, 9)]
28 | [TestCase("", "EmptyMethod_TwoLines", 12, 13)]
29 | [TestCase("", "EmptyMethod_ThreeLines", 16, 17)]
30 | [TestCase("", "EmptyMethod_LotsOfLines", 20, 23)]
31 | [TestCase("", "SimpleMethod_Void_NoArgs", 26, 28)]
32 | [TestCase("", "SimpleMethod_Void_OneArg", 32, 33)]
33 | [TestCase("", "SimpleMethod_Void_TwoArgs", 38, 39)]
34 | [TestCase("", "SimpleMethod_ReturnsInt_NoArgs", 44, 46)]
35 | [TestCase("", "SimpleMethod_ReturnsString_OneArg", 50, 51)]
36 | // Generic method uses simple name
37 | [TestCase("", "GenericMethod_ReturnsString_OneArg", 55, 56)]
38 | [TestCase("", "AsyncMethod_Void", 60, 62)]
39 | [TestCase("", "AsyncMethod_Task", 67, 69)]
40 | [TestCase("", "AsyncMethod_ReturnsInt", 74, 76)]
41 | [TestCase("+NestedClass", "SimpleMethod_Void_NoArgs", 83, 85)]
42 | [TestCase("+ParameterizedFixture", "SimpleMethod_ReturnsString_OneArg", 101, 102)]
43 | // Generic Fixture requires ` plus type arg count
44 | [TestCase("+GenericFixture`2", "Matches", 116, 117)]
45 | [TestCase("+GenericFixture`2+DoublyNested", "WriteBoth", 132, 133)]
46 | [TestCase("+GenericFixture`2+DoublyNested`1", "WriteAllThree", 151, 152)]
47 | public void VerifyNavigationData(string suffix, string methodName, int debugLineNumber, int releaseLineNumber)
48 | {
49 | // Get the navigation data - ensure names are spelled correctly!
50 | var className = Prefix + suffix;
51 | var data = _provider.GetSourceData(className, methodName);
52 | Assert.NotNull(data, "Unable to retrieve navigation data");
53 |
54 | // Verify the navigation data
55 | // Note that different line numbers are returned for our
56 | // debug and release builds, as follows:
57 | //
58 | // DEBUG
59 | // Min line: Opening curly brace.
60 | // Max line: Closing curly brace.
61 | //
62 | // RELEASE
63 | // Min line: First non-comment code line or closing
64 | // curly brace if the method is empty.
65 | // Max line: Last code line if that line is an
66 | // unconditional return statement, otherwise
67 | // the closing curly brace.
68 | Assert.That(data.Filename, Does.EndWith("NavigationTestData.cs"));
69 | #if DEBUG
70 | Assert.That(data.LineNumber, Is.EqualTo(debugLineNumber));
71 | #else
72 | Assert.That(data.LineNumber, Is.EqualTo(releaseLineNumber));
73 | #endif
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Navigation/NavigationTestData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Threading.Tasks;
4 | namespace NUnit.Runner.Test.Navigation
5 | {
6 | // Contains methods used in testing use of DiaSession.
7 | class NavigationTestData
8 | {
9 | public void EmptyMethod_OneLine() { } // minLineDebug = minLineRelease = maxLineDebug = maxLineRelease = 8
10 |
11 | public void EmptyMethod_TwoLines()
12 | { // minLineDebug = 12
13 | } // minLineRelease = maxLineDebug = maxLineRelease = 13
14 |
15 | public void EmptyMethod_ThreeLines()
16 | { // minLineDebug = 16
17 | } // minLineRelease = maxLineDebug = maxLineRelease = 17
18 |
19 | public void EmptyMethod_LotsOfLines()
20 | { // minLineDebug = 20
21 |
22 |
23 | } // minLineRelease = maxLineDebug = maxLineRelease = 23
24 |
25 | public void SimpleMethod_Void_NoArgs()
26 | {// minLineDebug = 26
27 | const int answer = 42;
28 | Console.Write(answer); // minLineRelease = 28
29 | } // maxLineDebug = maxLineRelease = 29
30 |
31 | public void SimpleMethod_Void_OneArg(int x)
32 | { // minLineDebug = 32
33 | var answer = x; // minLineRelease = 33
34 | Console.Write(answer);
35 | } // maxLineDebug = maxLineRelease = 35
36 |
37 | public void SimpleMethod_Void_TwoArgs(int x, int y)
38 | { // minLineDebug = 38
39 | var answer = x + y; // minLineRelease = 39
40 | Console.Write(answer);
41 | } // maxLineDebug = maxLineRelease = 41
42 |
43 | public int SimpleMethod_ReturnsInt_NoArgs()
44 | {// minLineDebug = 44
45 | const int answer = 42;
46 | return answer; // minLineRelease = maxLineRelease = 46
47 | } // maxLineDebug = 47
48 |
49 | public string SimpleMethod_ReturnsString_OneArg(int x)
50 | { // minLineDebug = 50
51 | return x.ToString(CultureInfo.InvariantCulture); // minLineRelease = maxLineRelease = 51
52 | } // maxLineDebug = 52
53 |
54 | public string GenericMethod_ReturnsString_OneArg(T x)
55 | { // minLineDebug = 55
56 | return x.ToString(); // minLineRelease = maxLineRelease = 56
57 | } // maxLineDebug = 57
58 |
59 | public async void AsyncMethod_Void()
60 | { // minLineDebug = 60
61 | const int answer = 42;
62 | await Task.Delay(0); // minLineRelease = 62
63 | Console.Write(answer);
64 | } // maxLineDebug = maxLineRelease = 64
65 |
66 | public async Task AsyncMethod_Task()
67 | { // minLineDebug = 67
68 | const int answer = 42;
69 | await Task.Delay(0); // minLineRelease = 69
70 | Console.Write(answer);
71 | } // maxLineDebug = maxLineRelease = 71
72 |
73 | public async Task AsyncMethod_ReturnsInt()
74 | { // minLineDebug = 74
75 | const int answer = 42;
76 | await Task.Delay(0); // minLinerelease = 76
77 | return answer;
78 | } // maxLineDebug = maxLineRelease = 78
79 |
80 | public class NestedClass
81 | {
82 | public void SimpleMethod_Void_NoArgs()
83 | {// minLineDebug = 83
84 | const int answer = 42;
85 | Console.Write(answer); // minLineRelease = 85
86 | } // maxLineDebug = maxLineRelease = 86
87 | }
88 |
89 | public class ParameterizedFixture
90 | {
91 | private readonly double x;
92 | private readonly string s;
93 |
94 | public ParameterizedFixture(double x, string s)
95 | {
96 | this.x = x;
97 | this.s = s;
98 | }
99 |
100 | public string SimpleMethod_ReturnsString_OneArg(int i)
101 | { // minLineDebug = 101
102 | return s + x * i; // minLineRelease = maxLineRelease = 102
103 | } // maxLineDebug = 103
104 | }
105 |
106 | public class GenericFixture
107 | {
108 | private readonly T1 x;
109 |
110 | public GenericFixture(T1 x)
111 | {
112 | this.x = x;
113 | }
114 |
115 | public bool Matches(T2 y)
116 | { // minLineDebug = 116
117 | return x.Equals(y); // minLineRelease = maxLineRelease = 117
118 | } // maxLineDebug = 118
119 |
120 | public class DoublyNested
121 | {
122 | public T1 X;
123 | public T2 Y;
124 |
125 | public DoublyNested(T1 x, T2 y)
126 | {
127 | X = x;
128 | Y = y;
129 | }
130 |
131 | public void WriteBoth()
132 | { // minLineDebug = 132
133 | Console.Write(X + Y.ToString()); // minLineRelease = 133
134 | } // maxLineDebug = maxLineRelease = 134
135 | }
136 |
137 | public class DoublyNested
138 | {
139 | public T1 X;
140 | public T2 Y;
141 | public T3 Z;
142 |
143 | public DoublyNested(T1 x, T2 y, T3 z)
144 | {
145 | X = x;
146 | Y = y;
147 | Z = z;
148 | }
149 |
150 | public void WriteAllThree()
151 | { // minLineDebug = 151
152 | Console.Write(X + Y.ToString() + Z); // minLineRelease = 152
153 | } // maxLineDebug = maxLineRelease = 153
154 | }
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("NUnit Software")]
10 | [assembly: AssemblyProduct("dotnet_test_nunit.test")]
11 | [assembly: AssemblyCopyright("Copyright (C) 2016 NUnit Project")]
12 | [assembly: AssemblyTrademark("NUnit is a trademark of NUnit Software")]
13 |
14 | // Setting ComVisible to false makes the types in this assembly not visible
15 | // to COM components. If you need to access a type in this assembly from
16 | // COM, set the ComVisible attribute to true on that type.
17 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Sinks/BaseSinkTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using System.IO;
26 | using Microsoft.Extensions.Testing.Abstractions;
27 | using Newtonsoft.Json;
28 | using NUnit.Framework;
29 | using MsTest = Microsoft.Extensions.Testing.Abstractions.Test;
30 | using MsTestResult = Microsoft.Extensions.Testing.Abstractions.TestResult;
31 |
32 | namespace NUnit.Runner.Test.Sinks
33 | {
34 | [TestFixture]
35 | public class BaseSinkTests
36 | {
37 | MemoryStream _stream;
38 |
39 | protected BinaryWriter BinaryWriter { get; private set; }
40 |
41 | [SetUp]
42 | public virtual void SetUp()
43 | {
44 | _stream = new MemoryStream();
45 | BinaryWriter = new BinaryWriter(_stream);
46 | }
47 |
48 | [TearDown]
49 | public virtual void TearDown()
50 | {
51 | BinaryWriter.Dispose();
52 | _stream.Dispose();
53 | }
54 |
55 | protected Message GetMessage()
56 | {
57 | _stream.Position = 0;
58 | var reader = new BinaryReader(_stream);
59 | var json = reader.ReadString();
60 | return JsonConvert.DeserializeObject(json);
61 | }
62 |
63 | protected T GetPayload(Message message)
64 | {
65 | Assert.That(message, Is.Not.Null);
66 | Assert.That(message.Payload, Is.Not.Null);
67 | return message.Payload.ToObject();
68 | }
69 |
70 | protected static MsTest CreateMockTest() =>
71 | new MsTest
72 | {
73 | Id = Guid.NewGuid(),
74 | DisplayName = "NUnitTest",
75 | FullyQualifiedName = "NUnit.Runner.Test.NUnitTest",
76 | CodeFilePath = @"C:\src\NUnitTest.cs",
77 | LineNumber = 123
78 | };
79 |
80 | protected static MsTestResult CreateMockTestResult()
81 | {
82 | var test = CreateMockTest();
83 | var endTime = DateTime.UtcNow;
84 | return new MsTestResult(test)
85 | {
86 | StartTime = endTime.AddSeconds(-2),
87 | EndTime = endTime,
88 | Duration = TimeSpan.FromSeconds(2),
89 | ComputerName = "MyComputer",
90 | ErrorMessage = "An error occured",
91 | ErrorStackTrace = "Stack trace",
92 | Outcome = TestOutcome.Failed
93 | };
94 | }
95 |
96 | protected static void AssertAreEqual(MsTest expected, MsTest actual)
97 | {
98 | Assert.That(actual, Is.Not.Null);
99 | Assert.AreEqual(expected.Id, actual.Id);
100 | Assert.AreEqual(expected.DisplayName, actual.DisplayName);
101 | Assert.AreEqual(expected.FullyQualifiedName, actual.FullyQualifiedName);
102 | Assert.AreEqual(expected.CodeFilePath, actual.CodeFilePath);
103 | Assert.AreEqual(expected.LineNumber, actual.LineNumber);
104 | }
105 |
106 | protected static void AssertAreEqual(MsTestResult expected, MsTestResult actual)
107 | {
108 | Assert.That(actual, Is.Not.Null);
109 | Assert.AreEqual(expected.StartTime, actual.StartTime);
110 | Assert.AreEqual(expected.EndTime, actual.EndTime);
111 | Assert.AreEqual(expected.Duration, actual.Duration);
112 | Assert.AreEqual(expected.DisplayName, actual.DisplayName);
113 | Assert.AreEqual(expected.ComputerName, actual.ComputerName);
114 | Assert.AreEqual(expected.ErrorMessage, actual.ErrorMessage);
115 | Assert.AreEqual(expected.ErrorStackTrace, actual.ErrorStackTrace);
116 | Assert.AreEqual(expected.Outcome, actual.Outcome);
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Sinks/RemoteTestDiscoverySinkTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using Microsoft.Extensions.Testing.Abstractions;
25 | using NUnit.Framework;
26 | using NUnit.Runner.Sinks;
27 | using MsTest = Microsoft.Extensions.Testing.Abstractions.Test;
28 |
29 | namespace NUnit.Runner.Test.Sinks
30 | {
31 | [TestFixture]
32 | public class RemoteTestDiscoverySinkTests : BaseSinkTests
33 | {
34 | ITestDiscoverySink _testSink;
35 |
36 | [SetUp]
37 | public override void SetUp()
38 | {
39 | base.SetUp();
40 | _testSink = new RemoteTestDiscoverySink(BinaryWriter);
41 | }
42 |
43 | [Test]
44 | public void SendTestFound()
45 | {
46 | var test = CreateMockTest();
47 | _testSink.SendTestFound(test);
48 | var message = GetMessage();
49 | Assert.That(message, Is.Not.Null);
50 | Assert.That(message.MessageType, Is.EqualTo(Messages.TestFound));
51 | AssertAreEqual(test, GetPayload(message));
52 | }
53 |
54 | [Test]
55 | public void SendTestFoundThrowsWithNullTest()
56 | {
57 | Assert.That(() => _testSink.SendTestFound(null), Throws.ArgumentNullException);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Sinks/RemoteTestExecutionSinkTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using Microsoft.Extensions.Testing.Abstractions;
25 | using NUnit.Framework;
26 | using NUnit.Runner.Sinks;
27 | using MsTest = Microsoft.Extensions.Testing.Abstractions.Test;
28 | using MsTestResult = Microsoft.Extensions.Testing.Abstractions.TestResult;
29 |
30 | namespace NUnit.Runner.Test.Sinks
31 | {
32 | public class RemoteTestExecutionSinkTests : BaseSinkTests
33 | {
34 | ITestExecutionSink _testSink;
35 |
36 | [SetUp]
37 | public override void SetUp()
38 | {
39 | base.SetUp();
40 | _testSink = new RemoteTestExecutionSink(BinaryWriter);
41 | }
42 |
43 | [Test]
44 | public void SendTestStarted()
45 | {
46 | var test = CreateMockTest();
47 | _testSink.SendTestStarted(test);
48 | var message = GetMessage();
49 | Assert.That(message, Is.Not.Null);
50 | Assert.That(message.MessageType, Is.EqualTo(Messages.TestStarted));
51 | AssertAreEqual(test, GetPayload(message));
52 | }
53 |
54 | [Test]
55 | public void SendTestStartedThrowsWithNullTest()
56 | {
57 | Assert.That(() => _testSink.SendTestStarted(null), Throws.ArgumentNullException);
58 | }
59 |
60 | [Test]
61 | public void SendTestResult()
62 | {
63 | var testResult = CreateMockTestResult();
64 | _testSink.SendTestResult(testResult);
65 | var message = GetMessage();
66 | Assert.That(message, Is.Not.Null);
67 | Assert.That(message.MessageType, Is.EqualTo(Messages.TestResult));
68 | AssertAreEqual(testResult, GetPayload(message));
69 | }
70 |
71 | [Test]
72 | public void SendTestResultThrowsWithNullTestResult()
73 | {
74 | Assert.That(() => _testSink.SendTestResult(null), Throws.ArgumentNullException);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/Sinks/RemoteTestSinkTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using Microsoft.Extensions.Testing.Abstractions;
25 | using NUnit.Framework;
26 | using NUnit.Runner.Sinks;
27 |
28 | namespace NUnit.Runner.Test.Sinks
29 | {
30 | [TestFixture]
31 | public class RemoteTestSinkTests : BaseSinkTests
32 | {
33 | ITestSink _testSink;
34 |
35 | [SetUp]
36 | public override void SetUp()
37 | {
38 | base.SetUp();
39 | _testSink = new RemoteTestDiscoverySink(BinaryWriter);
40 | }
41 |
42 | [Test]
43 | public void SendTestCompleted()
44 | {
45 | _testSink.SendTestCompleted();
46 | var message = GetMessage();
47 | Assert.That(message, Is.Not.Null);
48 | Assert.That(message.MessageType, Is.EqualTo(Messages.TestCompleted));
49 | }
50 |
51 | [Test]
52 | public void SendWaitingCommand()
53 | {
54 | _testSink.SendWaitingCommand();
55 | var message = GetMessage();
56 | Assert.That(message, Is.Not.Null);
57 | Assert.That(message.MessageType, Is.EqualTo(Messages.WaitingCommand));
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/TestListeners/TestExecutionListenerTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using Microsoft.Extensions.Testing.Abstractions;
26 | using NUnit.Framework;
27 | using NUnit.Runner.TestListeners;
28 |
29 | namespace NUnit.Runner.Test.TestListeners
30 | {
31 | [TestFixture]
32 | public class TestExecutionListenerTests
33 | {
34 | const string STARTED_TEST_CASE_XML =
35 | "";
36 |
37 | const string SUCCESS_TEST_CASE_XML =
38 | "";
39 |
40 | const string IGNORE_TEST_CASE_XML =
41 | "" +
42 | " " +
43 | " " +
44 | " " +
45 | " " +
46 | " " +
47 | " " +
48 | "";
49 |
50 | const string EXPLICIT_TEST_CASE_XML =
51 | "" +
52 | " " +
53 | " " +
54 | " " +
55 | " " +
56 | " " +
57 | " " +
58 | "";
59 |
60 | const string ERROR_TEST_CASE_XML =
61 | "" +
62 | " " +
63 | " " +
64 | " " +
65 | " " +
66 | "";
67 |
68 | const string FAILED_TEST_CASE_XML =
69 | "" +
70 | " " +
71 | " " +
74 | " " +
76 | " " +
77 | "";
78 |
79 | const string TESTCONTEXT_OUTPUT_TEST_CASE_XML =
80 | "" +
81 | " " +
83 | "";
84 |
85 |
86 | const string TEST_SUITE_XML =
87 | "" +
88 | " " +
89 | " " +
90 | " " +
91 | " " +
92 | " " +
93 | " " +
94 | "";
95 |
96 | const string TEST_OUTPUT =
97 | "This is the test output";
98 |
99 | const string TEST_OUTPUT_WITH_CDATA =
100 | "";
101 |
102 | Mocks.MockTestExecutionSink _sink;
103 | TestExecutionListener _listener;
104 |
105 | [OneTimeSetUp]
106 | public void OneTimeSetUp()
107 | {
108 | _sink = new Mocks.MockTestExecutionSink();
109 | _listener = new TestExecutionListener(_sink, new CommandLineOptions("--designtime"), @"\src");
110 | }
111 |
112 | [Test]
113 | public void CanParseSuccess()
114 | {
115 | var eventHandler =
116 | new EventHandler((sender, args) => Assert.That(args.TestOutput, Is.EqualTo("Passed")));
117 | _listener.TestFinished += eventHandler;
118 |
119 | _listener.OnTestEvent(SUCCESS_TEST_CASE_XML);
120 |
121 | var testResult = _sink.TestResult;
122 | Assert.That(testResult, Is.Not.Null);
123 | Assert.That(testResult.ErrorMessage, Is.Null.Or.Empty);
124 | Assert.That(testResult.ErrorStackTrace, Is.Null.Or.Empty);
125 | Assert.That(testResult.Outcome, Is.EqualTo(TestOutcome.Passed));
126 | Assert.That(testResult.StartTime.Hour, Is.EqualTo(23));
127 | Assert.That(testResult.EndTime.Minute, Is.EqualTo(31));
128 | Assert.That(testResult.Duration.TotalSeconds, Is.EqualTo(0.000001d).Within(0.001d));
129 |
130 | _listener.TestFinished -= eventHandler;
131 | }
132 |
133 | [Test]
134 | public void CanParseIgnoredTests()
135 | {
136 | var eventHandler =
137 | new EventHandler((sender, args) => Assert.That(args.TestOutput, Is.EqualTo("Skipped")));
138 | _listener.TestFinished += eventHandler;
139 |
140 | _listener.OnTestEvent(IGNORE_TEST_CASE_XML);
141 | var testResult = _sink.TestResult;
142 | Assert.That(testResult, Is.Not.Null);
143 | Assert.That(testResult.ErrorMessage, Is.EqualTo("Ignored Test"));
144 | Assert.That(testResult.ErrorStackTrace, Is.Null.Or.Empty);
145 | Assert.That(testResult.Outcome, Is.EqualTo(TestOutcome.Skipped));
146 | Assert.That(testResult.StartTime.Hour, Is.EqualTo(23));
147 | Assert.That(testResult.EndTime.Minute, Is.EqualTo(45));
148 | Assert.That(testResult.Duration.TotalSeconds, Is.EqualTo(0.000001d).Within(0.001d));
149 |
150 | _listener.TestFinished -= eventHandler;
151 | }
152 |
153 | [Test]
154 | public void CanParseExplicitTests()
155 | {
156 | var eventHandler =
157 | new EventHandler((sender, args) => Assert.That(args.TestOutput, Is.EqualTo("Skipped")));
158 | _listener.TestFinished += eventHandler;
159 |
160 | _listener.OnTestEvent(EXPLICIT_TEST_CASE_XML);
161 | var testResult = _sink.TestResult;
162 | Assert.That(testResult, Is.Not.Null);
163 | Assert.That(testResult.ErrorMessage, Is.EqualTo("Explicit Test"));
164 | Assert.That(testResult.ErrorStackTrace, Is.Null.Or.Empty);
165 | Assert.That(testResult.Outcome, Is.EqualTo(TestOutcome.Skipped));
166 | Assert.That(testResult.StartTime.Hour, Is.EqualTo(23));
167 | Assert.That(testResult.EndTime.Minute, Is.EqualTo(45));
168 | Assert.That(testResult.Duration.TotalSeconds, Is.EqualTo(0.000001d).Within(0.001d));
169 |
170 | _listener.TestFinished -= eventHandler;
171 | }
172 |
173 | [Test]
174 | public void CanParseTestErrors()
175 | {
176 | var eventHandler =
177 | new EventHandler((sender, args) => Assert.That(args.TestOutput, Is.EqualTo("Failed")));
178 | _listener.TestFinished += eventHandler;
179 |
180 | _listener.OnTestEvent(ERROR_TEST_CASE_XML);
181 | var testResult = _sink.TestResult;
182 | Assert.That(testResult, Is.Not.Null);
183 | Assert.That(testResult.ErrorMessage?.Trim(), Does.StartWith("System.ArgumentException"));
184 | Assert.That(testResult.ErrorStackTrace?.Trim(), Does.StartWith("at NUnitWithDotNetCoreRC2.Test.CalculatorTests.ErrorTest()"));
185 | Assert.That(testResult.Outcome, Is.EqualTo(TestOutcome.Failed));
186 | Assert.That(testResult.StartTime.Hour, Is.EqualTo(19));
187 | Assert.That(testResult.EndTime.Minute, Is.EqualTo(57));
188 | Assert.That(testResult.Duration.TotalSeconds, Is.EqualTo(0.023031).Within(0.001d));
189 |
190 | _listener.TestFinished -= eventHandler;
191 | }
192 |
193 | [Test]
194 | public void CanParseTestFailures()
195 | {
196 | var eventHandler =
197 | new EventHandler((sender, args) => Assert.That(args.TestOutput, Is.EqualTo("Failed")));
198 | _listener.TestFinished += eventHandler;
199 |
200 | _listener.OnTestEvent(FAILED_TEST_CASE_XML);
201 | var testResult = _sink.TestResult;
202 | Assert.That(testResult, Is.Not.Null);
203 | Assert.That(testResult.ErrorMessage?.Trim(), Does.StartWith("Expected: 3"));
204 | Assert.That(testResult.ErrorStackTrace?.Trim(), Does.StartWith("at NUnitWithDotNetCoreRC2.Test.CalculatorTests.FailedTest()"));
205 | Assert.That(testResult.Outcome, Is.EqualTo(TestOutcome.Failed));
206 | Assert.That(testResult.StartTime.Hour, Is.EqualTo(19));
207 | Assert.That(testResult.EndTime.Minute, Is.EqualTo(57));
208 | Assert.That(testResult.Duration.TotalSeconds, Is.EqualTo(0.017533).Within(0.001d));
209 |
210 | _listener.TestFinished -= eventHandler;
211 | }
212 |
213 | [Test]
214 | public void CanParseTestOutput()
215 | {
216 | _listener.OnTestEvent(TESTCONTEXT_OUTPUT_TEST_CASE_XML);
217 | var testResult = _sink.TestResult;
218 | Assert.That(testResult, Is.Not.Null);
219 | Assert.That(testResult.Messages.Count, Is.EqualTo(1));
220 | Assert.That(testResult.Messages[0], Does.StartWith("Test context output"));
221 | }
222 |
223 | [Test]
224 | public void FiresTestFinished()
225 | {
226 | string test = null;
227 | string output = null;
228 | _listener.TestFinished += (sender, args) =>
229 | {
230 | test = args.TestName;
231 | output = args.TestOutput;
232 | };
233 |
234 | _listener.OnTestEvent(TESTCONTEXT_OUTPUT_TEST_CASE_XML);
235 |
236 | Assert.That(test, Is.Not.Null);
237 | Assert.That(test, Is.EqualTo("NUnitWithDotNetCoreRC2.Test.CalculatorTests.TestWithTestContextOutput"));
238 |
239 | Assert.That(output, Is.Not.Null);
240 | Assert.That(output, Does.StartWith("Test context output"));
241 | }
242 |
243 | [Test]
244 | public void FiresSuiteFinished()
245 | {
246 | string test = null;
247 | _listener.SuiteFinished += (sender, args) => test = args.TestName;
248 |
249 | _listener.OnTestEvent(TEST_SUITE_XML);
250 |
251 | Assert.That(test, Is.Not.Null);
252 | Assert.That(test, Is.EqualTo("NUnit.Framework.Internal.CultureSettingAndDetectionTests.LoadWithFrenchCanadianCulture"));
253 | }
254 |
255 | [TestCase(TEST_OUTPUT, "NUnit.Output.Test", "This is the test output")]
256 | [TestCase(TEST_OUTPUT_WITH_CDATA, "NUnit.Output.CDataTest", "Test CData output")]
257 | public void FiresTestOutput(string xml, string expectedTest, string expectedOutput)
258 | {
259 | string test = null;
260 | string stream = null;
261 | string output = null;
262 | _listener.TestOutput += (sender, args) =>
263 | {
264 | test = args.TestName;
265 | stream = args.Stream;
266 | output = args.TestOutput;
267 | };
268 |
269 | _listener.OnTestEvent(xml);
270 |
271 | Assert.That(test, Is.Not.Null);
272 | Assert.That(test, Is.EqualTo(expectedTest));
273 |
274 | Assert.That(output, Is.Not.Null);
275 | Assert.That(output, Is.EqualTo(expectedOutput));
276 |
277 | Assert.That(stream, Is.Not.Null);
278 | Assert.That(stream, Is.EqualTo("theStream"));
279 | }
280 |
281 | [Test]
282 | public void TestStarted()
283 | {
284 | bool raised = false;
285 |
286 | var eventHandler =
287 | new EventHandler((sender, args) => raised = true);
288 | _listener.TestStarted += eventHandler;
289 |
290 | _listener.OnTestEvent(STARTED_TEST_CASE_XML);
291 |
292 | Assert.That(raised, Is.True);
293 |
294 | _listener.TestFinished -= eventHandler;
295 | }
296 | }
297 | }
298 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/TestListeners/TestExplorerListenerTests.cs:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Copyright (c) 2016 NUnit Project
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining
5 | // a copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to
9 | // permit persons to whom the Software is furnished to do so, subject to
10 | // the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be
13 | // included in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | // ***********************************************************************
23 |
24 | using System;
25 | using NUnit.Framework;
26 | using NUnit.Runner.TestListeners;
27 |
28 | namespace NUnit.Runner.Test.TestListeners
29 | {
30 | [TestFixture]
31 | public class TestExplorerListenerTests
32 | {
33 | const string TEST_CASE_XML_WITH_PROPERTIES =
34 | "" +
35 | " " +
36 | " " +
37 | " " +
38 | " " +
39 | " " +
40 | " " +
41 | "";
42 |
43 | const string TEST_CASE_XML_WITH_MULTIPLE_CATEGORIES =
44 | "" +
45 | " " +
46 | " " +
47 | " " +
48 | " " +
49 | " " +
50 | " " +
51 | "";
52 |
53 | Mocks.MockTestExplorerSink _sink;
54 | TestExploreListener _listener;
55 |
56 | [OneTimeSetUp]
57 | public void OneTimeSetUp()
58 | {
59 | _sink = new Mocks.MockTestExplorerSink();
60 | _listener = new TestExploreListener(_sink, new CommandLineOptions("--designtime"), @"\src");
61 | }
62 |
63 | [Test]
64 | public void CanParseTestsWithProperties()
65 | {
66 | _listener.OnTestEvent(TEST_CASE_XML_WITH_PROPERTIES);
67 | var test = _sink.TestFound;
68 | Assert.That(test, Is.Not.Null);
69 | Assert.That(test.DisplayName, Is.EqualTo("LoadWithFrenchCanadianCulture"));
70 | Assert.That(test.FullyQualifiedName, Is.EqualTo("NUnit.Framework.Internal.CultureSettingAndDetectionTests.LoadWithFrenchCanadianCulture"));
71 | Assert.That(test.Id, Is.Not.EqualTo(Guid.Empty));
72 | Assert.That(test.Properties.Count, Is.EqualTo(2));
73 | Assert.That(test.Properties["SetCulture"], Is.EqualTo("fr-CA"));
74 | Assert.That(test.Properties["UICulture"], Is.EqualTo("en-CA"));
75 | }
76 |
77 | [Test]
78 | public void CanParseTestsWithMultipleCategories()
79 | {
80 | _listener.OnTestEvent(TEST_CASE_XML_WITH_MULTIPLE_CATEGORIES);
81 | var test = _sink.TestFound;
82 | Assert.That(test, Is.Not.Null);
83 | Assert.That(test.DisplayName, Is.EqualTo("MultipleCategoryTest"));
84 | Assert.That(test.FullyQualifiedName, Is.EqualTo("NUnitWithDotNetCoreRC2.Test.CalculatorTests.MultipleCategoryTest"));
85 | Assert.That(test.Id, Is.Not.EqualTo(Guid.Empty));
86 | // TODO: Visual Studio currently only supports a single category
87 | Assert.That(test.Properties.Count, Is.EqualTo(1));
88 | Assert.That(test.Properties["Category"], Is.EqualTo("Two"));
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/dotnet-test-nunit.test.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | b3c98a50-d42f-4197-968b-0e25591e83c3
10 | NUnit.Runner.Test
11 | .\obj
12 | .\bin\
13 | v4.6.1
14 |
15 |
16 | 2.0
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/dotnet-test-nunit.test/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "copyright": "Copyright (C) 2016 NUnit Project",
3 | "authors": [ "Rob Prouse" ],
4 | "title": "NUnit .NET Core Runner Tests",
5 | "name": "dotnet-test-nunit.test",
6 | "version": "3.3.0-*",
7 | "buildOptions": {
8 | "preserveCompilationContext": true,
9 | "warningsAsErrors": true
10 | },
11 |
12 | "dependencies": {
13 | "NUnit": "3.5.0",
14 | "dotnet-test-nunit": {
15 | "target": "project"
16 | }
17 | },
18 | "testRunner": "nunit",
19 |
20 | "frameworks": {
21 | "netcoreapp1.0": {
22 | "imports": "dotnet5.6",
23 | "dependencies": {
24 | "Microsoft.NETCore.App": {
25 | "version": "1.0.0",
26 | "type": "platform"
27 | }
28 | }
29 | },
30 | "net451": {}
31 | }
32 | }
33 |
--------------------------------------------------------------------------------