OLD | NEW |
| (Empty) |
1 /* | |
2 Copyright 2011 Google Inc | |
3 | |
4 Licensed under the Apache License, Version 2.0 (the "License"); | |
5 you may not use this file except in compliance with the License. | |
6 You may obtain a copy of the License at | |
7 | |
8 http://www.apache.org/licenses/LICENSE-2.0 | |
9 | |
10 Unless required by applicable law or agreed to in writing, software | |
11 distributed under the License is distributed on an "AS IS" BASIS, | |
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 See the License for the specific language governing permissions and | |
14 limitations under the License. | |
15 */ | |
16 | |
17 using System; | |
18 using System.Collections.Generic; | |
19 using System.IO; | |
20 using System.Linq; | |
21 using NUnit.Core; | |
22 using NUnit.Core.Filters; | |
23 | |
24 namespace Google.Build.Tester | |
25 { | |
26 /// <summary> | |
27 /// A simple unit tester class. | |
28 /// </summary> | |
29 [Serializable] | |
30 public class UnitTester : EventListener, IDisposable | |
31 { | |
32 static UnitTester() | |
33 { | |
34 CoreExtensions.Host.InitializeService(); | |
35 } | |
36 | |
37 private readonly RemoteTestRunner runner; | |
38 private readonly AppDomain domain; | |
39 private Results resultsSandbox; | |
40 private List<Results.Message> messagesSandbox; | |
41 ········ | |
42 [Serializable] | |
43 public class Results | |
44 { | |
45 /// <summary> | |
46 /// The total numbers of tests run. | |
47 /// </summary> | |
48 public int Total { get { return Passed Failed; } } | |
49 | |
50 /// <summary> | |
51 /// Passed unit tests. | |
52 /// </summary> | |
53 public int Passed { get; set; } | |
54 | |
55 /// <summary> | |
56 /// Failed unit tests. | |
57 /// </summary> | |
58 public int Failed { get; set; } | |
59 | |
60 [Serializable] | |
61 public struct Message | |
62 { | |
63 public bool IsError; | |
64 public string Text; | |
65 } | |
66 | |
67 /// <summary> | |
68 /// Messages | |
69 /// </summary> | |
70 public Message[] Messages { get; set; } | |
71 } | |
72 | |
73 /// <summary> | |
74 /// Creates a unit tester for the specified assembly. | |
75 /// </summary> | |
76 /// <returns>Number of failed unit tests.</returns> | |
77 public static int Run(string testAssembly) | |
78 { | |
79 string tempFolder = Path.Combine(Path.GetTempPath(), "UnitTest" te
stAssembly.GetHashCode()); | |
80 while (Directory.Exists(tempFolder)) | |
81 { | |
82 tempFolder = "_"; | |
83 } | |
84 | |
85 Directory.CreateDirectory(tempFolder); | |
86 try | |
87 { | |
88 // Copy over all assemblies. | |
89 Utils.CopyFiles(Path.GetDirectoryName(testAssembly), tempFolder)
; | |
90 | |
91 // Copy over the nunit dlls. | |
92 foreach (string dll in (from a in AppDomain.CurrentDomain.GetAss
emblies()· | |
93 where a.GetName().Name.StartsWith("nunit
.") || a == typeof(UnitTester).Assembly | |
94 select new Uri(a.CodeBase).LocalPath)) | |
95 { | |
96 File.Copy(dll, Path.Combine(tempFolder, Path.GetFileName(dll
))); | |
97 } | |
98 | |
99 // Create and run the unit tester | |
100 using (UnitTester tester = new UnitTester(Path.Combine(tempFolde
r, Path.GetFileName(testAssembly)))) | |
101 { | |
102 Results results = tester.Run(); | |
103 foreach (var msg in results.Messages) | |
104 { | |
105 (msg.IsError ? Console.Error : Console.Out).WriteLine(ms
g.Text); | |
106 } | |
107 if (results.Total > 0) | |
108 { | |
109 Console.WriteLine("PASSED: " results.Passed); | |
110 | |
111 if (results.Failed > 0) | |
112 { | |
113 Console.Error.WriteLine("FAILED: " results.Failed)
; | |
114 } | |
115 } | |
116 return results.Failed; | |
117 } | |
118 } | |
119 finally | |
120 { | |
121 Directory.Delete(tempFolder, true); | |
122 } | |
123 } | |
124 ········ | |
125 private UnitTester(string testAssembly) | |
126 { | |
127 var testPackage = new TestPackage(Path.GetFileNameWithoutExtension(t
estAssembly)); | |
128 testPackage.Assemblies.Add(testAssembly); | |
129 | |
130 // Create a new appdomain with the appropriate working directory. | |
131 // This is required so that we don't accidentially load the wrong de
pendencies. | |
132 var setup = new AppDomainSetup(); | |
133 setup.ApplicationBase = Path.GetDirectoryName(testAssembly); | |
134 domain = AppDomain.CreateDomain("TestDomain", null, setup); | |
135 ············ | |
136 runner = RemoteTestRunner.CreateInstance(domain, 0); | |
137 runner.Load(testPackage); | |
138 } | |
139 | |
140 /// <summary> | |
141 /// Runs all unit tests on this assembly. | |
142 /// </summary> | |
143 /// <returns>Number of failed tests.</returns> | |
144 public Results Run() | |
145 { | |
146 runner.Run(this); | |
147 return domain.GetData("Results") as Results; | |
148 } | |
149 | |
150 private void Log(bool error, string msg, params object[] args) | |
151 { | |
152 messagesSandbox.Add(new Results.Message() { IsError = error, Text =
string.Format(msg, args) }); | |
153 } | |
154 | |
155 public void RunStarted(string name, int testCount) | |
156 { | |
157 resultsSandbox = new Results(); | |
158 resultsSandbox.Passed = 0; | |
159 resultsSandbox.Failed = 0; | |
160 messagesSandbox = new List<Results.Message>(); | |
161 | |
162 if (testCount == 0) | |
163 { | |
164 Log(false, "Assembly does not contain any unit tests."); | |
165 } | |
166 else | |
167 { | |
168 Log(false, "Running {0} tests for [{1}] ...", testCount, name); | |
169 } | |
170 Console.Out.Flush(); | |
171 } | |
172 | |
173 public void RunFinished(TestResult result) | |
174 { | |
175 resultsSandbox.Messages = messagesSandbox.ToArray(); | |
176 AppDomain.CurrentDomain.SetData("Results", resultsSandbox); | |
177 } | |
178 | |
179 public void RunFinished(Exception exception) | |
180 { | |
181 Console.Error.WriteLine(exception.ToString()); | |
182 Console.Out.Flush(); | |
183 } | |
184 | |
185 public void TestStarted(TestName testName) | |
186 { | |
187 Log(false, " Testing '{0}'", testName.FullName); | |
188 Console.Out.Flush(); | |
189 } | |
190 | |
191 public void TestFinished(TestResult result) | |
192 { | |
193 if (!result.IsSuccess) | |
194 { | |
195 Log(true, " [{0}]: FAILED!", result.Name); | |
196 foreach (string line in result.Message.Split(new[]{Environment.N
ewLine}, 0)) | |
197 { | |
198 Log(true," {0}", line); | |
199 } | |
200 resultsSandbox.Failed ; | |
201 } | |
202 else | |
203 { | |
204 resultsSandbox.Passed ; | |
205 } | |
206 } | |
207 | |
208 public void SuiteStarted(TestName testName) {} | |
209 | |
210 public void SuiteFinished(TestResult result) {} | |
211 | |
212 public void UnhandledException(Exception exception) | |
213 { | |
214 Log(true, " Exception: " exception.Message); | |
215 } | |
216 | |
217 public void TestOutput(TestOutput testOutput) { } | |
218 | |
219 public void Dispose() | |
220 { | |
221 runner.Dispose(); | |
222 AppDomain.Unload(domain); | |
223 } | |
224 } | |
225 } | |
OLD | NEW |