Using standard modules in tests elegantly

349 views
Skip to first unread message

Julian

unread,
Jun 3, 2011, 11:11:27 AM6/3/11
to juk...@googlegroups.com
Hello there!

Is there a better (more concise) way to leverage an already existing module for a test than the following?

@RunWith(JukitoRunner.class)
public class MyTest {

public static class Module extends JukitoModule {
protected void configureTest() {
install(new MyModule());
}
}

@Test
public void testRequiringStuffBoundInMyModule(SomeTypeFromMyModule someType) {
...
}

}

If not, how about an annotation like @Jukito(Use/Bind)Modules(..) which can be defined on test classes and methods.

@RunWith(JukitoRunner.class)
@JukitoUseModules(ModuleA.class, ModuleB.class, ...)    // Stuff bound in these modules can be used in every test, setup, teardown, ...
public class MyTest {

@Test
        @JukitoUseModules(MyModule.class)    // Stuff bound in this module will only be available in the following test
public void testRequiringStuffBoundInMyModule(SomeTypeFromMyModule someType) {
...
}

}

Of course all this modules need to have a default (no-args) constructor.


And last but not least, thanks for developing Jukito, I really enjoy using it. :)

Best,
Julian

Philippe Beaudoin

unread,
Jun 3, 2011, 11:13:10 AM6/3/11
to juk...@googlegroups.com
Thanks Julian,

I've been toying with your proposal for a while and I think it's a good idea! I invite you to submit an issue and I'll get to it soon... (Or better yet, if you can provide a patch, I'll add it in! :))

Cheers,

   Philippe

Julian

unread,
Jun 3, 2011, 11:56:08 AM6/3/11
to juk...@googlegroups.com
Hey Philippe,

I took the liberty to create an issue (#26) and link back to this topic.

Looking forward to the next releases of Jukito.

Best,
Julian

Julian

unread,
Sep 17, 2011, 8:30:21 PM9/17/11
to juk...@googlegroups.com
Hey Philippe,

I was finally able to spend some time on this issue (#26).
See the attached patch and let me know what you think.

It is just a first proposal and I will be happy to iterate on it, if you give me feedback.
If you decided that this goes into trunk, I can also change the existing test suite to use the new approach and fix the bugs and corner cases that will crop up.
I also suggest that we remove the implicit semantics of the inner static TestModule/JukitoModule class in favor of the new, more explicit approach. Even if that means that we break existing test code - we still can give a nice, descriptive error message though.
This would prevent the need to maintain and test both approaches.
What do you think?

Cheers,
Julian

Jukito_58_to_84.diff
Jukito_58_to_84.hg
jukito-patch.zip

Julian

unread,
Sep 18, 2011, 8:20:28 AM9/18/11
to juk...@googlegroups.com
I think the previous patch did not include all changesets.
Jukito_57_to_84.diff
Jukito_57_to_84.hg

Philippe Beaudoin

unread,
Sep 18, 2011, 8:54:22 AM9/18/11
to juk...@googlegroups.com
I'll take a look at this soon. However, I'm not a huge fan of deprecating the old way. Many people are using Jukito efficiently with modules defined as static inner classes and I believe it's a very nice way to document what the test is doing right in the test. I'm pretty sure both approaches can live side-by-side. What do you think?
Message has been deleted

Julian

unread,
Sep 18, 2011, 9:51:13 AM9/18/11
to juk...@googlegroups.com
Hey Philippe,

I will try to motivate and explain my point of view a bit better than I did in my last post.

1) 
[...] modules defined as static inner classes and I believe it's a very nice way to document what the test is doing right in the test. 

I fully agree for the reasons you mentioned (conciseness, everything is in one place, self-documenting). It is definitely the way to go!
Maybe I expressed myself poorly in the last post: The only change for this to work with the 'new approach' is to add another annotation to your test class.
It also makes it more explicit which module is used, if any. (You can just look at your class definition and don't have to 'scroll over the class body' to find the module / to find out that there is none defined.)

2)
The annotation approach is a bit more flexible. You can use multiple modules, they don't have to be derived from TestModule, you can apply them on a method-level basis and you can reuse already defined modules.
I don't think that it is a good idea to allow mixing of both approaches in a single test class.

3)
I also read through the other discussion 'Inherited TestModules from parent classes'.
This patch almost solves this problem too, I think.
First of all, I don't like the idea that test modules are inherited from base classes implicitly.
What if you do not want this behavior? What if you declare a module in your subclass? Which module should be used? The one in the subclass? Both? ...
With the annotation approach you just tell the runner which module(s) you would like to use in your subclass.
It does not even has to be a module that is defined in the base class, but it may be one that is defined there.
Again, it makes the whole situation more explicit (self-documenting) which is a Good Thing, in my opinion.
You can also use Ctrl+Click / F3 in Eclipse to go to the test module very fast, which you cannot if it is inherited implicitly (Where do you click then? ;).

As I see it (as a user) is that we get more flexibility and explicitness by adding a single line of boilerplate (annotation).
The only real problem with 'enforcing the new approach' is that we break existing test code.
But all the errors will be easy to fix (add a simple annotation), it will not fail silently and in addition we can give a nice error message.

Cheers,
Julian

Tim Peierls

unread,
Sep 18, 2011, 4:48:25 PM9/18/11
to juk...@googlegroups.com
On Sun, Sep 18, 2011 at 9:51 AM, Julian <julian....@gmail.com> wrote:
The only real problem with 'enforcing the new approach' is that we break existing test code.
But all the errors will be easy to fix (add a simple annotation), it will not fail silently and in addition we can give a nice error message.

I'm not sure you can guarantee that it won't fail silently. It shouldn't be too hard to preserve existing semantics while providing new functionality.

--tim

Philippe Beaudoin

unread,
Sep 20, 2011, 8:58:52 AM9/20/11
to juk...@googlegroups.com
We seem to have a debate over the balance between:
- Boilerplate
- Self-documentation

It's a tricky one to get right... Personally, I tend to think Java development in general is too verbose, so in Jukito I have tried to err on the side of "less line of code for the same test is good". For that reason, I very much like the "module-in-a-static-inner-class-is-enough" model and don't plan on deprecating it. IMHO, it _is_ self-documenting. What else would a module be doing there?

Given that, the issue we should try to solve is to make it less verbose for situations in which you wish to reuse ONLY existing modules. (Because if you want to mix existing modules and new bindings, then install() is pretty much the best you can do.) The problem in that case is that you need a static inner class containing only a bunch of install() where an annotation could have done the trick.

With that in mind, I believe the best approach is to support EITHER:
- A static inner module class extending JukitoModule; OR
- An annotation pointing to other modules
If you provide both you get a warning that the static inner class is ignored. (Or an error?)

Then we're left with the case where we'd like child classes to inherit their parent class bindings. That's a tricky one because with the automatic-inheritance approach we lose self-documentation, and with the "every child class connects to the parent" approach we lose the single-point-of-control offered by inheritance. I believe we still need to think about this one.

Cheers,

   Philippe

Julian

unread,
Oct 5, 2011, 6:14:57 PM10/5/11
to juk...@googlegroups.com
Hey Philippe,

Did you review the patch? Are you interested, does it need improvements or did you discard it?

Cheers,
Julian

Philippe Beaudoin

unread,
Oct 12, 2011, 1:15:50 PM10/12/11
to juk...@googlegroups.com
Sorry, I have not had time to review it yet. It's on my todo list. I don't think I will discard it, although I'll probably revisit it a bit. I really want to do something in that area.

Cheers,

   Philippe

omax

unread,
Jun 15, 2012, 6:04:11 AM6/15/12
to juk...@googlegroups.com
Were there any progress on this? I'm interested in this new functionality.

Brandon Donnelson

unread,
Jul 27, 2012, 6:31:32 PM7/27/12
to juk...@googlegroups.com
I'm looking into this to see if I can help get that into the repo. I think I'll see if we can get that into the code review tool so its easier to merge. 

Brandon Donnelson

unread,
Jul 27, 2012, 7:39:13 PM7/27/12
to juk...@googlegroups.com
@Julian I imported the patch but there are some errors that exist. Not sure why yet. Have you merged with master recently?

Julian

unread,
Jul 30, 2012, 4:27:52 AM7/30/12
to juk...@googlegroups.com
No, I haven't.
The patch is almost one year old.

Christian Goudreau

unread,
Aug 2, 2012, 8:56:03 AM8/2/12
to juk...@googlegroups.com
Could you take a look? :D
--
Christian Goudreau

Przemyslaw Galazka

unread,
Feb 8, 2013, 10:12:01 AM2/8/13
to juk...@googlegroups.com
I opt for static inner class for installing custom modules. Installing modules via constructor may need some parameters. Using only annotations is cool but limited.  

Depending on test context we would install some default module and sometime an additional. It works quite well when using custom modules but it is limited to AbstractModules. 

More here
Reply all
Reply to author
Forward
0 new messages