There are some complex cases we need to test inside myfaces core and other projects. But create those test becomes a difficult task, mostly because with in-container testing you have a lot of unnecessary problems setting up dependencies, war files, classloaders, etc. And each time they are executed requires time setting up/shutting down the container. In other hand, doing testing with mock objects like the ones in myfaces test does not work very well, because sometimes we need to test the "interaction" between multiple parts of myfaces core (viewhandler, statemanager, lifecycle ...).
Things like org.apache.myfaces.view.facelets.FaceletTestCase are very productive to test such scenarios. You just provide an xhtml file, write a test method that take the vdl and build the view and then you add some asserts and that's it. These tests are very fast and very compact. Additionally it is very easy to debug, because you can put a break point directly on myfaces code and then on the test case and since it is the same thread running the code it becomes very easy and straightforward to follow the code.
In-container testing like the alternatives already proposed in myfaces using Arquillian are good but for integration tests, where you need to test complete use cases. Here we need to test only some parts of server-side code. But this strategy could be useful too in such scenarios, specially because you can "simulate" an user input and check navigation, if pages compiles against facelets engine, check if the EL expressions has all managed beans, take statistics about the code, and much more that you just can't do it with the other strategy.
The proposal I'm working on is create these classes:
as base classes to create unit tests. The trick here is initialize/shutdown myfaces and provide the same variables as in MyFaces Test. So if you already written a junit test using myfaces test, this is not really different.
for the client provide a class like this:
that "hides" the client language. By default, it just takes the data directly from the component and fill the request parameters, header and cookies. In that way the client is decoupled from the test environment.
Finally provide a MockMyFacesFaceletViewDeclarationLanguage class that extends from the default FaceletViewDeclarationLanguage but that add this method:
public void buildView(FacesContext context, UIViewRoot view, String xmlFile) throws IOException
To call it from AbstractMyFacesFaceletsTestCase, just like FaceletTestCase.
For now my intention is add these classes to myfaces-impl test package and use it to see how it works and if it is worth to create a custom module for this one in myfaces test.
Suggestions are welcome.