hard time to get GWTTestCase to work

2,026 views
Skip to first unread message

tanteanni

unread,
Jan 27, 2012, 4:41:22 AM1/27/12
to google-we...@googlegroups.com
i just tried my first GWTTestCase but it fails. My setup is Eclipse/Maven (not the happiest couple on the planet) - the pom was initially generated by gwt-tool ("webappcreator"?). I use MVP,gin, guice (testing views is not #1 priority but i want it to work).
Normal Unit-Tests work just fine. 
But with GWTTestCase i got different kinds of trouble:
if i try it with Eclipse' "run as GWT  Test" i got:

com.google.gwt.junit.JUnitFatalLaunchException: The test class '....client.view.DynamicLayoutViewImplTest' was not found in module '...integration'; no compilation unit for that type was seen
at com.google.gwt.junit.JUnitShell.checkTestClassInCurrentModule(JUnitShell.java:743)
at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1346)
at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1309)
at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:653)
at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:441)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:296)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

(The Test is in same package as the view, the module used inherits the "normal" module but it includes all permutations)

If i run "mvn test" i got a much bigger exception: for some reasen the app is deployed on jetty together with all server side stuff and i get an guice-error!? mvn gwt:test does absolutly nothing. The first question is: is this a source-code problem or a configuration problem or both? Here is the source:

public class DynamicLayoutViewImplTestGWT extends GWTTestCase {

    @Override
    public String getModuleName() {
        return "...Integration";
    }

    private DynamicLayoutViewImpl testObject;

    @Before
    public final void init() {
        AdbResources resources = GWT.create(AdbResources.class);
        testObject = new DynamicLayoutViewImpl(Unit.EM, resources);
    }

    @Test
    public final void testIt() {
        System.out.println("here");
    }

}
as you see i just tried to get an instance of my testobject. 

thx in advance

(i also tried gwt-test-utils is also failed)


salk31

unread,
Jan 27, 2012, 10:34:09 AM1/27/12
to Google Web Toolkit
The usual problem is that your test sources are not in the
classpath... the first bit of the stack trace suggests that I think.

Cheers

Sam

On Jan 27, 9:41 am, tanteanni <tantea...@hotmail.com> wrote:
> i just tried my first GWTTestCase but it fails. My setup is Eclipse/Maven
> (not the happiest couple on the planet) - the pom was initially generated
> by gwt-tool ("webappcreator"?). I use MVP,gin, guice (testing views is not
> #1 priority but i want it to work).
> Normal Unit-Tests work just fine.
> But with GWTTestCase i got different kinds of trouble:
> if i try it with Eclipse' "run as GWT  Test" i got:
>
> com.google.gwt.junit.JUnitFatalLaunchException: The test class
> '....client.view.DynamicLayoutViewImplTest' was not found in module
> '...integration'; no compilation unit for that type was seen
> at
> com.google.gwt.junit.JUnitShell.checkTestClassInCurrentModule(JUnitShell.ja va:743)
> at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1346)
> at com.google.gwt.junit.JUnitShell.runTestImpl(JUnitShell.java:1309)
> at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:653)
> at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:441)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:296)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at
> org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:8 3)
> at
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRe ference.java:49)
> at
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java: 38)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestR unner.java:467)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestR unner.java:683)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner .java:390)
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunne r.java:197)

tanteanni

unread,
Jan 30, 2012, 2:31:12 AM1/30/12
to google-we...@googlegroups.com
thx, the problem is how to fix it. i have a maven project generated by webappcreator from google. i thought unit tests with gwttestcase should work out of the box? 
with sources not in classpath do you mean the eclipse way of sources (knowing were to look in debugging session, debugging "normal" tests is working fine)? Or do you mean the "gwt-sources" (declared in gwt.xml)? (i put all tests in same packages as the OUTs - that should be enough for gwt to find the sources?!)

salk31

unread,
Jan 30, 2012, 10:43:23 AM1/30/12
to Google Web Toolkit
Sorry, I'm afraid I don't use maven

Steve Moyer

unread,
Feb 7, 2012, 8:41:37 AM2/7/12
to Google Web Toolkit
Actually when the error says the compilation unit is not found, it
means that the test runner isn't finding your compiled class. If you
look at the "Source" tab of your "Java Build Path", I'll bet that you
have the "Allow output folders for source folders" checkbox checked.
Unchecking this will cause all compilation units to be put into
targets/classes (your test classes are currently in target/test-
classes and the test runner can't find them). There are other ways to
solve this problems but this is the simplest. It has the undesired (I
assume) side affect of including the test classes in your output jar
or war, so you have to exclude them during packaging. The second
alternative is to make sure the target/test-classes folder is on your
classpath during testing.

Ed

unread,
Sep 16, 2012, 5:49:38 PM9/16/12
to google-we...@googlegroups.com
@ tanteanni :
Easiest solution: don't use GWTTestCase... It simple doesn't work well and if you have it working, it's hard to maintain...

Try to do everything through unit testing...
Nowedays I can test almost everything through unit tests, and works well. Google around for "awesome testing with IsWidget", 
if I remember correctly, and you find some forum posts of me that might help you in the correct direction...

- Ed

Ajax

unread,
Sep 17, 2012, 2:06:10 PM9/17/12
to google-we...@googlegroups.com
Not everything can be tested with unit tests.

I write a lot of generator + linker code, so, by necessity, I must use GWTTestCase, as I am testing the compilation process.

If your tests don't involve the gwt generator, then definitely don't incur the overhead of GWTTestCase,
but if you are working in the generator layer, or if you want to test a functional gui in the browser, then you should use GWTTestCase.

It might be possible with selenium to achieve the in-browser tests, but you will likely need to run the gwt compile anyway,
so you might as well just use the testing suite provided. =}

Ed

unread,
Sep 17, 2012, 5:11:38 PM9/17/12
to google-we...@googlegroups.com
Just curious: where do you use your linker and generators for?
(I always tried to avoid them as much as possible, don't like hem).

Op maandag 17 september 2012 20:06:10 UTC+2 schreef Ajax het volgende:

Ajax

unread,
Sep 17, 2012, 8:03:49 PM9/17/12
to google-we...@googlegroups.com
Anywhere you find yourself re-writing the same code more than three times, you would likely benefit from a generator.

Linkers are only useful if you need to translate java source into artifacts other than the embedded js.
For gadgets and files that require xml configurations, it may be more work up front to write a generator + linker combo, but it will save piles of frustration because your config file comes from your source code, rather than being edited by hand.

Currently, I'm doing a lot of work with creating my own cross-platform dependency injection framework (by implementing java.util.ServiceLoader for gwt).

The easy part was getting the generated javascript to work; the hard part was getting dev mode to work correctly, since it does not honor super-source overrides.


I prefer to work with interfaces and annotations as much as possible, and generators really help fill the gap without having to manually bind an interface to a factory or, even worse, just hardcoding an implementation.  

My next task for code generation will be to subclass java.lang.Thread and have it export a generated artifact to a web worker.

Rather than manually export multiple modules for the web workers and test them with trial, error and lots of recompiles,
I'm just going to write a generator which acts as a generic ThreadFactory, spits out a controller interface that will speak through to the web worker (or js object if web worker unavailable), and link the actual worker code into a separate js compile.  

This way, I can get the boilerplate right exactly once, and then reuse that boilerplate by calling GWT.create(GwtThread.class) any time I want to offload tasks to a web worker.

Ed Bras

unread,
Sep 18, 2012, 3:42:55 AM9/18/12
to google-we...@googlegroups.com
Thanks
Anywhere you find yourself re-writing the same code more than three times, you would likely benefit from a generator.
Can you give some examples?  
And what is your experience concerning debugging?

Ajax

unread,
Sep 19, 2012, 6:52:54 PM9/19/12
to google-we...@googlegroups.com
Anywhere you find yourself re-writing the same code more than three times, you would likely benefit from a generator.
Can you give some examples?  

- GWT.runAsync(); same boilerplate every time, but in order to work, each call must be behind a method of its own.
The lightweight dependency injection code I'm working on now wraps all this up behind a generated provider method.
It creates a RunAsyncCallback subclass for every marked async, and generates all the boilerplate to inject the implementation behind a code split.

To write by hand, you must, at the very least, implement the RunAsyncCallback class, plus some kind of sanity-check to avoid dupping the provided object.
Using a generator, it's a single line to annotate the target type, and a single method which takes an interface class and a callback to do DI + code split.


Another good example is DTO objects.  How many bean objects have you had to make just to pass around a couple strings and ints?
Using an interface + generator (like autobeans), you can just write out the type of data you want, and let the generator supply implementations on client (and server, if you're crafty).
One example I'm working on here is to present the client with raw JSOs to implement the interface, which translate directly to/from enhanced entities on the server which can access my datastore.
When I get my appengine virtualization layer finished, my DTO interfaces will also have .toEntity(), .fromEntity() methods, as well as .save() and .delete().

to/fromEntity() will be used mainly on the server to translate to datastore types, but also on the client to translate a statically typed object into a hash-bag object for use in CellWidgets.
.save() and .delete() will, on the client, call up (or queue up) requests to delete the entities on the server, and on the server, the objects will perform the actual deletions.
This way, I can help erase the client/server boundary.

Finally, and maybe most importantly, generators are great at spitting out boilerplate code.
If you have a specific procedure you must do (like un/marshalling data, or validating data), you will often find yourself writing, essentially the same code using different accessors for different objects.
These processes cannot be handled by a concrete class, unless you can implement accessor interfaces for every object (which you must still write by hand).
Instead, if you use a generator, you can just dream up any annotation to tell your code "check this, throw X if !Y", and let the generator write the dirty details itself.
Not only does the generator remove messy, error-prone boilerplate, it also updates and adapts as your app changes;
if you change a field's requirements, you just have to update that field's annotation, rather than lookup every place that field is validated and update by hand.


Basically, anywhere you need to repeat a process, but cannot hide it behind a simple concrete abstraction layer, a generator will probably help.


 
And what is your experience concerning debugging?

For debugging, it can be frustrating if you just run compiles and check output.
Instead, I specify the -gen directory to point to a project where I have symlinked in all relevant code.
The generated folder is the only concrete source folder, and all other source is just linked in.

This way, any compile errors or warnings or mistakes in the generated code can be picked up immediately,
and I can trace through the generated code easily.

Obviously, if the generator fails and produces no output, you are going to have some headache.
This is where using a subclassed SourceWriter which can debug to console while working can help you pick out errors;
turn a debug flag on, and your console will spew out the generated classes as it writes them, so you can see where the errors are.

If you have the symlinked gen project, you can just copy+paste broken generated code into it, and see where the compile errors are immediately.
Were I a little more ambitious, I would have the subclasses SourceWriter print the generated code to console, to the generator, and to the gen-view project,
so a simply F5 in the gen project will immediately show all compile errors...
Though, I haven't hit any bugs bad enough that I couldn't fix just as easily with debugging output, and maybe java debugger for NPEs here and there. =}
Reply all
Reply to author
Forward
0 new messages