jastrachan | 13 Jul 13:36 2004

Re: [groovy-dev] Bruce Eckel's talk & easier unit testing...

On 13 Jul 2004, at 11:52, Yuri Schimke wrote:
> On 13/07/2004, at 12:11 PM, jastrachan@... wrote:
>> While watching Bruce Eckel's talk
>> http://mindview.net/WebLog/log-0055
>> it got me thinking that it'd be really cool to be able to type 
>> something like the following and use it as a unit test case...
>>     foo = new Foo(123)
>>     foo.doSomething("hello")
>>     assert foo.cheese == "cheddar"
>> i.e. just write a chunk of code as being an individual unit test 
>> case. This works fine for real simple stuff - if you want to get 
>> complex, write a class with setUp() / tearDown() methods and the 
>> like. The tricky thing is the above script won't generate a class 
>> which is-a JUnit TestCase and so if this were compiled to bytecode 
>> the usual JUnit test runner tools might not pick it up.
>> I'm wondering if this actually matters. e.g. we could run this from 
>> the command line whenever we like...
>> groovy MyTest.groovy
>> and if we get any exceptions, then its failed :). In this case the 
>> script = 1 test, so there's no real need to use a TestCase etc. So 
>> maybe we could have a form of the Ant <junit> task which as well as 
>> looking for TestCase instances, could also gracefully handle scripts 
>> as above, which would all implement Runnable, so we just treat the 
>> run() method as one test etc.
> I don't like this.  It pretty much assumes that Groovy is the 2nd 
> blessed language for the JVM.  So our projects will handle Java and 
> Groovy, but have to resort to hacks again for a third language.

Not really - java.lang.Runnable is a standard JDK thing - its got 
nothing to do with Groovy. Indeed other scripting languages which can 
generate bytecode could use the same approach.

> If we are not going to handle extra languages, its better to limit it 
> to a groovy test runner, or add plugin support to junit/testng for 
> alternative languages,  via JSR 233, BSF etc.

Agreed - a test runner capable of running JSR 233/BSF might be a good 

> Its a lot safer to use the current contract, which is simply class 
> files that extend TestCase.  So I much prefer your suggestion below.

Agreed. I don't much like the above :)

>> Though writing all that plumbing & hacking of Ant tasks doesn't sound 
>> like fun. So another idea could be to somehow mutate the script to be 
>> derived from TestCase, using some magic mechanism. e.g. if we 
>> supported AST level macros, we could maybe use a macro to change the 
>> base class of the script such that it actually created a TestCase 
>> with a main which ran the script. I guess that'd be the ideal, then 
>> it really would, at the bytecode level, be a TestCase and so work 
>> with any JUnit capable code. I'm not sure yet what the macro should 
>> look like but imagine its something like...
> I like this a lot.  As I understand scripts are currently limited to 
> "static main(args)" classes, but maybe can be enhanced to implementing 
> other things i.e. unit tests, portlets, general event handlers etc

Right now we can configure the compiler to know what the base class is 
for the script; but language support for this is probably a good idea. 
I'm just not sure the best way to do it - some kind of 'use' mechanism, 
or metadata or some new language syntax. Metadata/macro might be the 

>>     use UnitTest
>>     foo = new Foo(123)
>>     foo.doSomething("hello")
>>     assert foo.cheese == "cheddar"
> extends UnitTestScript {
>  // code
> }

Could be, though it should maybe look more like a function maybe.  The 
above makes me think you're extending the class and so the body of the 
{} should be method declarations.

>> or to looky-likey Java 5
>>      <at> UnitTest
>>     foo = new Foo(123)
>>     foo.doSomething("hello")
>>     assert foo.cheese == "cheddar"
>  <at> extends UnitTestScript

nice :)


 <at> extends GroovyTestCase

Playing devil's advocate for a second, you could say is

foo = new Foo()
assert foo.bar == 123

that much neater than

class MyTest extends GroovyTestCase {
     void testFoo() {
	foo = new Foo()
	assert foo.bar == 123

I guess we're used to stuff like the above, but it would help us create 
little testing scripts quicker & easier if we didn't have to wrap 
things in a class/method just to please the JUnit runner