User Tools

Site Tools


at:tutorial:appendix

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revisionBoth sides next revision
at:tutorial:appendix [2008/07/08 11:31] – added tvcutsemat:tutorial:appendix [2008/07/08 11:46] – added tvcutsem
Line 5: Line 5:
 ===== Unit Testing Framework ===== ===== Unit Testing Framework =====
  
-The file ''at/unit/test.at'' shipped with the AmbientTalk/2 system library defines a unit testing framework for AmbientTalk/2 which is similar in spirit and structure to JUnit and SUnit. Load the module by executing ''import /.at.unit.test''.+The file ''at/unit/test.at'' shipped with the AmbientTalk/2 system library defines a unit testing framework for AmbientTalk/2 which is similar in spirit and structure to [[http://www.junit.org|JUnit]] and SUnit. Load the module by executing ''import /.at.unit.test''.
  
 ====== Creating a Unit Test ====== ====== Creating a Unit Test ======
Line 25: Line 25:
 </code> </code>
  
-This will execute all ''test*'' methods in the given unit test, and print out which of the tests succeeded or failed. The ''runTest'' method can optionally take a "reporter" object as an argument, which can be used to implement a custom strategy for reporting success or failure of a unit test. The default reporter object is a text-based UI.+This will execute all ''test*'' methods in the given unit test (in an **undefined** order!), and print out which of the tests succeeded or failed. The ''runTest'' method can optionally take a "reporter" object as an argument, which can be used to implement a custom strategy for reporting success or failure of a unit test. The default reporter object is a text-based UI.
  
-Like in JUnit and SUnit, it is possible to define two methods named ''setUp()'' and ''tearDown()'' that are invoked in between //each// individual ''test*'' method.+Like in JUnit and SUnit, it is possible to define two methods named ''setUp()'' and ''tearDown()'' that are invoked in between //each// individual ''test*'' method. Never rely on the lexical order of your unit test methods for the purposes of initialization, etc.! Unit test methods may be exacuted in an arbitrary order.
  
 ====== Assertions ====== ====== Assertions ======
Line 57: Line 57:
  
 <note warning> <note warning>
-Be sure to invoke the above assertion methods by means of self-sends as shown in the above example! These methods are defined in the ''UnitTest'' parent object, not in the global lexical scope.+A common mistake is to invoke the above assertion methods as if they were lexically visible (e.g. invoking ''assertEquals(...)''). However, these methods are not lexically visible, rather they are defined in the ''UnitTest'' parent object. Hencethe proper way to invoke them is via a self-send, as shown in the above example.
 </note> </note>
  
 ====== Asynchronous Unit Tests ====== ====== Asynchronous Unit Tests ======
  
-When a method is prefixed with 'testAsync', the unit testing framework expects the method to return a future and will only process subsequent test methods once the future is resolved/ruined. This is useful for performing unit tests that require asynchronous message sends.+Up to now, the unit testing framework assumed that all of your unit tests consisted of purely synchronous method invocations. When running the tests, all ''test*'' methods are invoked sequentially, and the unit test ends when the last ''test*'' method has been invoked. 
 + 
 +To support unit test methods that need to perform asynchronous invocations (e.g. those performing concurrent or distributed unit tests), the unit testing framework introduces a new prefix: all methods that spawn asynchronous computation must be prefixed with ''testAsync''
 + 
 +When a method is prefixed with ''testAsync'', the unit testing framework expects the method to return a future and will only process subsequent test methods once that future is resolved or ruined. Here is an example that tests whether future-type messaging works: 
 + 
 +<code> 
 +def testAsyncFutures() { 
 +  import /.at.lang.futures; 
 +  def adder := object: { def inc(x) { x+1 } }; 
 +  def f := when: adder<-inc(42)@FutureMessage becomes: { |val| 
 +    self.assertEquals(43, val); 
 +  }; 
 +  f 
 +
 +</code> 
 + 
 +The unit test framework will invoke this method, receive a future ''f'', and only continue once the future ''f'' has been resolved.  In the above example, the future ''f'' is the return value of the ''when:becomes:'' function, which means that ''f'' implicitly depends on the future associated with the call to ''<-inc(42)''
 + 
 +It is also possible to use ''makeFuture()'' to create a fresh future explicitly within the unit test method, and to use the returned resolver to resolve the future at the appropriate time.
  
 ====== Test Suites ====== ====== Test Suites ======
at/tutorial/appendix.txt · Last modified: 2021/09/24 10:28 by elisag