<source id="4vppl"><ins id="4vppl"></ins></source>
<u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
<object id="4vppl"></object>
  • <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

    <object id="4vppl"></object>
    <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

      <i id="4vppl"><thead id="4vppl"></thead></i>

      <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>

      當(dāng)前位置:首頁 > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 設(shè)計(jì)軟件教程 > 基于 D 2.0 編譯時(shí)反射的單元測試框架

      基于 D 2.0 編譯時(shí)反射的單元測試框架
      2010-01-13 22:49:47  作者:  來源:
      一個(gè)模仿 Ruby Test::Unit 的 Quick & Dirty 單元測試框架,托 __traits 的福,看起來已經(jīng)有那么點(diǎn)意思了。提取行號(hào)在目前還沒法實(shí)現(xiàn),估計(jì)等 macro 出來就能解決這個(gè)問題。

      SVN里的最新版在下面的鏈接處:
      dotmars.googlecode.com/svn/trunk/sandbox/2.0/test.d

      D2.0 代碼

       

       
      1. /**
      2. A D 2.0 unit test framework inspired by Ruby's Unit::Test
      3.  
      4. // Written in the D programming language 2.0
      5.  
      6. Authors: Wei Li (oldrev@gmail.com)
      7. License: BSD
      8. Copyright: Copyright (C) 2007 by Wei Li.
      9. */
      10.  
      11. import std.stdio;
      12.  
      13. ////////////////////////////////////////////////////////////////////////////////
      14.  
      15. struct Failure
      16. {
      17. string location;
      18. string message;
      19. string testName;
      20. }
      21.  
      22. ////////////////////////////////////////////////////////////////////////////////
      23.  
      24. struct Error
      25. {
      26. Exception exception;
      27. string testName;
      28. }
      29.  
      30. ////////////////////////////////////////////////////////////////////////////////
      31.  
      32. class TestResult
      33. {
      34. private Error[] m_errors;
      35. private Failure[] m_fails;
      36. private int m_runCount;
      37. private int m_assertionCount;
      38. private int m_testCount;
      39.  
      40. const(Error)[] errors() {
      41. return m_errors;
      42. }
      43.  
      44. const(Failure)[] failures() {
      45. return m_fails;
      46. }
      47.  
      48. void addFailure(const string loc, const string msg, const string name)
      49. {
      50. Failure f;
      51. with(f) {
      52. location = loc;
      53. message = msg;
      54. testName = name;
      55. }
      56. m_fails ~= f;
      57. }
      58.  
      59. void addError(Exception ex, const string name)
      60. {
      61. Error e;
      62. with(e) {
      63. exception = ex;
      64. testName = name;
      65. }
      66. m_errors ~= e;
      67. }
      68.  
      69. void addAssertion() {
      70. m_assertionCount++;
      71. }
      72.  
      73. void addTest() {
      74. m_testCount++;
      75. }
      76.  
      77. void addRun() {
      78. m_runCount++;
      79. }
      80.  
      81. bool hasPassed() {
      82. return m_errors.length == 0 && m_fails.length == 0;
      83. }
      84.  
      85. int errorCount() {
      86. return cast(int)m_errors.length;
      87. }
      88.  
      89. int failureCount() {
      90. return cast(int)m_fails.length;
      91. }
      92.  
      93. int runCount() {
      94. return m_runCount;
      95. }
      96.  
      97. int testCount() {
      98. return m_testCount;
      99. }
      100.  
      101. int assertionCount() {
      102. return m_assertionCount;
      103. }
      104. }
      105.  
      106.  
      107. ////////////////////////////////////////////////////////////////////////////////
      108.  
      109.  
      110. abstract class TestBase
      111. {
      112. protected this() {
      113. }
      114.  
      115. abstract void run(TestResult result);
      116.  
      117. abstract const bool isRunning();
      118. }
      119.  
      120.  
      121. ////////////////////////////////////////////////////////////////////////////////
      122.  
      123.  
      124. abstract class TestCase(Subclass) : TestBase
      125. {
      126. alias typeof(this) SelfType;
      127.  
      128. struct TestMethod
      129. {
      130. string name;
      131. void delegate() method;
      132. }
      133.  
      134. public const string name = Subclass.classinfo.name;
      135.  
      136. private TestResult m_result;
      137. private TestMethod[] m_methods;
      138. private size_t m_currentMethod;
      139. private bool m_isFailed;
      140. private bool m_running = false;
      141.  
      142. this() {
      143. }
      144.  
      145. private static const(string) ctfMakeString(T)()
      146. {
      147. string ret;
      148. foreach(str; __traits(allMembers, T)) {
      149. if(str[0..4] == "test")
      150. ret ~= `addTestMethod(TestMethod("` ~ str ~ `", &sc.` ~ str ~ `)); ` ~ "\n";
      151. }
      152. return ret;
      153. }
      154.  
      155. private void initial(const Subclass sc) {
      156. mixin(ctfMakeString!(Subclass)());
      157. }
      158.  
      159. void addTestMethod(TestMethod tm) {
      160. m_methods ~= tm;
      161. }
      162.  
      163. static Subclass createChild() {
      164. auto o = new Subclass;
      165. o.initial(o);
      166. return o;
      167. }
      168.  
      169. void setup() {}
      170.  
      171. void teardown() {}
      172.  
      173. override const bool isRunning() {
      174. return m_running;
      175. }
      176.  
      177. override void run(TestResult result)
      178. {
      179. m_result = result;
      180. m_result.addRun();
      181.  
      182. foreach(size_t i, TestMethod tm; m_methods)
      183. {
      184. m_isFailed = false;
      185. m_currentMethod = i;
      186. m_result.addTest();
      187. setup();
      188. m_running = true;
      189.  
      190. try {
      191. tm.method();
      192. }
      193. catch(Exception ex) {
      194. m_result.addError(ex, currentMethodName);
      195. }
      196. finally {
      197. m_running = false;
      198. }
      199.  
      200. teardown();
      201. }
      202. }
      203.  
      204. const string currentMethodName() {
      205. return name ~ "." ~ m_methods[m_currentMethod].name;
      206. }
      207.  
      208. private void addFailure(const string message = null)
      209. {
      210. if(!m_isFailed)
      211. {
      212. m_isFailed = true;
      213. m_result.addFailure(name, message, currentMethodName);
      214. }
      215. }
      216.  
      217. //////////////////////////// Assertion Functions ///////////////////////////
      218.  
      219. void assertTrue(bool x, const string message = null)
      220. {
      221. m_result.addAssertion();
      222. if(!x) {
      223. addFailure(message);
      224. }
      225. }
      226.  
      227. void assertNull(T)(const T value, const string message = null)
      228. {
      229. m_result.addAssertion();
      230. if(value !is null) {
      231. addFailure(message);
      232. }
      233. }
      234.  
      235. void assertNotNull(T)(const T value, const string message = null)
      236. {
      237. m_result.addAssertion();
      238. if(value is null) {
      239. addFailure(message);
      240. }
      241. }
      242.  
      243. void assertEqual(T)(const T expected, const T actual, const string message = null)
      244. {
      245. m_result.addAssertion();
      246. if(expected != actual) {
      247. addFailure(message);
      248. }
      249. }
      250.  
      251. void assertNotEqual(T)(const T expected, const T actual, const T delta, const string message = null)
      252. {
      253. m_result.addAssertion();
      254. if(expected == actual) {
      255. addFailure(message);
      256. }
      257. }
      258.  
      259. void flunk(const string message = "Flunked")
      260. {
      261. m_result.addAssertion();
      262. addFailure(message);
      263. }
      264.  
      265. }
      266.  
      267.  
      268. ////////////////////////////////////////////////////////////////////////////////
      269.  
      270. class TestSuit(Subclass, Tests...) : TestBase
      271. {
      272. alias typeof(this) SelfType;
      273.  
      274. public const string name = Subclass.classinfo.name;
      275. private TestBase[] m_tests;
      276. private bool m_running = false;
      277.  
      278. this()
      279. {
      280. m_running = false;
      281.  
      282. foreach(T; Tests)
      283. {
      284. T test = T.createChild();
      285. addTest(test);
      286. }
      287. }
      288.  
      289. static Subclass createChild() {
      290. return new Subclass;
      291. }
      292.  
      293. const(TestBase)[] tests() {
      294. return m_tests;
      295. }
      296.  
      297. void addTest(TestBase tb)
      298. in {
      299. assert(tb !is null);
      300. }
      301. body {
      302. m_tests ~= tb;
      303. }
      304.  
      305. const bool empty() {
      306. return Tests.length == 0;
      307. }
      308.  
      309. override const bool isRunning() {
      310. return m_running;
      311. }
      312.  
      313. override void run(TestResult result) {
      314. m_running = true;
      315. foreach(test; m_tests) {
      316. test.run(result);
      317. }
      318. m_running = false;
      319. }
      320. }
      321.  
      322.  
      323. static class ConsoleRunner
      324. {
      325. static void showFailures(TestResult tr)
      326. {
      327. foreach(fail; tr.failures)
      328. {
      329. writefln("Failure: %s [%s]", fail.testName, fail.location);
      330. writefln("%s", fail.message);
      331. writefln();
      332. }
      333. }
      334.  
      335. static void showErrors(TestResult tr)
      336. {
      337. foreach(err; tr.errors)
      338. {
      339. writefln("Error: s", err.testName);
      340. writefln("%s", err.exception.msg);
      341. writefln();
      342. }
      343. }
      344.  
      345. static void run(TestBase tb)
      346. {
      347. auto result = new TestResult;
      348. writefln("Started...");
      349. tb.run(result);
      350. writefln("Finished\n");
      351. showErrors(result);
      352. showFailures(result);
      353. writefln();
      354. writefln("%d tests, %d assertions, %d failures, %d errors",
      355. result.testCount, result.assertionCount, result.failureCount, result.errorCount);
      356. if(result.hasPassed)
      357. writefln("Everything is OK.");
      358. }
      359. }
      360.  
      361. ////////////////////////////////////////////////////////////////////////////////
      362.  
      363.  
      364. class MyTestCase : TestCase!(MyTestCase)
      365. {
      366. void testOne() {
      367. assertTrue(false, "A stupid assertion");
      368. assertTrue(true);
      369. assertTrue(true);
      370. throw new Exception("Exception raised");
      371. }
      372.  
      373. void testTwo() {
      374. assertTrue(true);
      375. }
      376.  
      377. void testThree() {
      378. assertTrue(true);
      379. }
      380. }
      381.  
      382. class MyTestCase2 : TestCase!(MyTestCase2)
      383. {
      384. void testOne() {
      385. assertTrue(true);
      386. }
      387.  
      388. void testTwo() {
      389. assertTrue(true);
      390. }
      391.  
      392. void testThree() {
      393. assertTrue(false, "Yet another stupid assertion");
      394. }
      395. }
      396.  
      397. class MyTestCase3 : TestCase!(MyTestCase3)
      398. {
      399. void testMethod() {
      400. assertTrue(true);
      401. }
      402. }
      403.  
      404.  
      405. class MyTestSuit1: TestSuit!(MyTestSuit1, MyTestCase)
      406. {
      407. }
      408.  
      409. class MyTestSuit2: TestSuit!(MyTestSuit2, MyTestCase2)
      410. {
      411. }
      412.  
      413. class MyTestSuit3: TestSuit!(MyTestSuit3, MyTestSuit1, MyTestSuit2, MyTestCase3)
      414. {
      415. }
      416.  
      417. void main()
      418. {
      419. auto ts = new MyTestSuit3;
      420.  
      421. ConsoleRunner.run(ts);
      422. }

       



      運(yùn)行結(jié)果
       
      oldrev@ubuntu:~/work/dotmars/sandbox/2.0$ dmd2 -run test.d
      Started...
      Finished

      Error: stest.MyTestCase.testOne
      Exception raised

      Failure: test.MyTestCase.testOne [test.MyTestCase]
      A stupid assertion

      Failure: test.MyTestCase2.testThree [test.MyTestCase2]
      Yet another stupid assertion


      7 tests, 9 assertions, 2 failures, 1 errors


       

      安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
      国产午夜福三级在线播放_亚洲精品成a人片在线观看_亚洲自慰一区二区三区_久久棈精品久久久久久噜噜
      <source id="4vppl"><ins id="4vppl"></ins></source>
      <u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
      <object id="4vppl"></object>
    1. <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

      <object id="4vppl"></object>
      <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

        <i id="4vppl"><thead id="4vppl"></thead></i>

        <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>
        亚洲人成精品久久久久 | 亚洲性日韩精品一区二区三区 | 亚洲综合在线观看乱码 | 午夜福利亚洲国产不卡顿 | 在线播放美女口爆吞精 | 日韩精品视频网站 |