Hmm.. okay. But doesn't this sort of make MyFacesTest obsolete? Or am I missing something...
___ Kito D. Mann | @kito99 | Author, JSF in Action Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and consulting http://www.JSFCentral.com | @jsfcentral +1 203-998-0403 * Listen to the Enterprise Java Newscast: *http://w <http://blogs.jsfcentral.com/JSFNewscast/>ww.enterprisejavanews.com <http://ww.enterprisejavanews.com>* * JSFCentral Interviews Podcast: http://www.jsfcentral.com/resources/jsfcentralpodcasts/ * Sign up for the JSFCentral Newsletter: http://oi.vresp.com/?fid=ac048d0e17 On Sat, Jan 25, 2014 at 10:17 PM, Leonardo Uribe <[email protected]> wrote: > Hello Kito > > It is not possible to include it into MyFaces-Test by several reasons: > > - MyFaces Core has a dependency over MyFaces Test. This code is in > between both projects, so if we include it into MyFaces Test it means > we will have a circular dependency between both projects. > - The code includes some small but important changes for MyFaces Core. > It is easier to maintain these details if the resulting module is > released along with MyFaces Core, and it will be easier for users to > know which version of the module is compatible with, because the > released module will have the same release version numbers as MyFaces > Core. > - This code is needed to test Myfaces Core code, because we have > already a bunch of test cases using this stuff. > > The code has been used for some time, and the idea is improve it and > give the opportunity to users to include it into their projects, and > also use it in other MyFaces projects in the future. > > regards, > > Leonardo > > > 2014-01-25 Kito Mann <[email protected]>: > > Hello Leonardo, > > > > This sounds very cool. Why not add it to MyFaces-Test instead? > > > > > > On Saturday, January 25, 2014, Leonardo Uribe <[email protected]> wrote: > >> > >> Hi > >> > >> With JSF 2.0/2.1 and with the introduction of JSF 2.2, it has become > more > >> and > >> more frequent to find cases where you have a JSF-CDI application, and > you > >> want > >> to create JUnit tests. Usually, the interest in these cases is test some > >> complex server side logic, but the problem is you usually need some > >> control of > >> the JSF lifecycle, or there is an interaction between pages and beans > and > >> with a mocked environment like the one provided in MyFaces Test you can > >> only > >> simulate partially the beans. In these cases, it is not necessary to > fully > >> simulate the client, because what you really want to check is what's > going > >> on > >> in the server side. > >> > >> Solutions like the one provided by JSFUnit or Arquillian does not fit > >> properly > >> in these cases, because the server does not run on the same side as the > >> client, > >> so there are 2 running classloaders (the one where junit is and the > other > >> that belongs to the web server) which makes debugging difficult. > >> > >> Additionally, some time ago, these issues were opened in MYFACESTEST > issue > >> tracker: > >> > >> - MYFACESTEST-42 Implement support for creating managed beans from > >> faces-config.xml or other JSF config files. > >> - MYFACESTEST-59 Move MockViewDeclarationLanguageFactory from MyFaces > Core > >> to > >> MyFaces-test > >> - MYFACESTEST-62 Move FaceletTestCase from internal MyFaces to the > MyFaces > >> Test project > >> > >> These issues suggest it would be great to have some mock test > environment > >> that > >> can do things like build a view from a .xhml or read faces-config.xml or > >> .taglib.xml files. In few words, run MyFaces Core in a JUnit test. > >> > >> Looking for a way to fix this problem, some time ago it was created this > >> issue: > >> > >> https://issues.apache.org/jira/browse/MYFACES-3376 Create abstract test > >> classes > >> that runs MyFaces Core as in a > >> container > >> > >> Inside MyFaces Core Impl module, in src/test/java directory there is a > >> package > >> called org.apache.myfaces.mc.test.core with these junit base test > classes: > >> > >> - AbstractMyFacesTestCase > >> - AbstractMyFacesRequestTestCase > >> - AbstractMyFacesFaceletsTestCase > >> - AbstractMyFacesCDIRequestTestCase > >> > >> These classes creates a mock servlet test environment that is able to > run > >> MyFaces Core using JUnit. For example: > >> > >> // 1. In pom.xml it is necessary to make available src/main/webapp > >> resources > >> // as test resources: > >> > >> <build> > >> <testResources> > >> <testResource> > >> <directory>${project.basedir}/src/test/resources</directory> > >> </testResource> > >> <testResource> > >> <directory>${project.basedir}/src/main/webapp</directory> > >> <targetPath>webapp</targetPath> > >> </testResource> > >> </testResources> > >> <!-- .... --> > >> > >> // 2. Add beans.xml in src/main/java/META-INF and src/test/java/META-INF > >> // 3. Now create the test class > >> > >> public class SimpleTestCase extends AbstractMyFacesCDIRequestTestCase > >> { > >> @Inject > >> @Named("helloWorld") > >> private HelloWorldController helloWorldBean; > >> > >> @Test > >> public void testHelloWorld() throws Exception > >> { > >> startViewRequest("/helloWorld.xhtml"); > >> processLifecycleExecute(); > >> Assert.assertEquals("page2.xhtml", helloWorldBean.send()); > >> renderResponse(); > >> > >> client.inputText("mainForm:name", "John Smith"); > >> // The button end current request and start a new request > >> // with a simulated submit > >> client.submit("mainForm:submit"); > >> > >> processLifecycleExecute(); > >> Assert.assertEquals("John Smith", helloWorldBean.getName()); > >> Assert.assertEquals("/page2.xhtml", > >> facesContext.getViewRoot().getViewId()); > >> endRequest(); > >> } > >> > >> @Override > >> protected ExpressionFactory createExpressionFactory() > >> { > >> // By default it uses a mock ELFactory. > >> return new com.sun.el.ExpressionFactoryImpl(); > >> } > >> > >> @Override > >> protected String getWebappContextFilePath() > >> { > >> // By default it is the package name of the test. > >> return "webapp"; > >> } > >> > >> } > >> > >> The example simulates a helloworld submit. getWebappContextFilePath() > >> defines > >> the link between the webapp context as test resource, to allow the test > to > >> load the resources from that location. All faces-config.xml and > >> .taglib.xml > >> from the classpath are automatically loaded. JSF annotation scanning is > >> disabled by default but you can enable it overriding isScanAnnotations() > >> method and setting up "org.apache.myfaces.annotation.SCAN_PACKAGES" > param > >> to reduce the time spent in classpath scanning. > >> > >> This code has allowed us to make very complex tests inside MyFaces Core > >> very > >> easily, like Faces Flows, Resource Library Contracts, Reset Values or > View > >> Pooling. The resulting simulated environment is almost identical in > >> comparison > >> with the one created inside a web server, and the differences can be > fixed > >> quite easily, overriding the appropiate methods. The integration with > >> CDI is just register the servlet listener and that's it. > >> > >> If users are using some JSF third-party component library, it is quite > >> easy > >> to create a custom mock client and use Firebug or something else to > check > >> the http requests and provide some methods to fill the simulated client > >> side logic. > >> > >> Create test cases is pretty straightforward, because everything is > running > >> in the junit test case, so you don't need to write any callback, just > >> write > >> the instructions and do the necessary validations in the right spots. > This > >> is > >> how a redirect is simulated: > >> > >> @Test > >> public void testRedirect1() throws Exception > >> { > >> startViewRequest("/redirect1.xhtml"); > >> processLifecycleExecute(); > >> renderResponse(); > >> client.submit("mainForm:submit"); > >> processLifecycleExecuteAndRender(); > >> // redirect sends 302 response, so the client must take it and > >> // start the redirected request > >> client.processRedirect(); > >> // this is the lifecycle of the redirected request. > >> processLifecycleExecuteAndRender(); > >> String redirectedContent = getRenderedContent(); > >> Assert.assertTrue(redirectedContent.contains("Redirected > Page")); > >> } > >> > >> The code tries to reuse as much configuration info as possible. For > >> example > >> a test case like FlowMyFacesRequestTestCase in my machine in Netbeans > >> takes 2.5 seconds to be executed and then 0.17 seconds per each > additional > >> test, and the IDE takes another 3 or 4 seconds to execute > >> "compile on save" and start junit. CDI takes about 1.1 seconds per > method. > >> Note this is a lot less than deploy a server like jetty or tomee, which > in > >> the same conditions could take (with a helloworld app) about 10 seconds > or > >> more to start, run the test and stop. > >> > >> The proposal I have for the consideration of MyFaces community is > create a > >> new module for MyFaces Core 2.2 branch called impl-test. The module > takes > >> the code from org.apache.myfaces.mc.test.core in impl module and > repackage > >> it into a new jar file so users can reference it into its own projects. > >> In that way we can use the code in MyFaces Core like we are doing right > >> now and we can maintain it at the same time. > >> > >> This is the issue in jira to keep track of this feature: > >> > >> https://issues.apache.org/jira/browse/MYFACES-3849 > >> > >> I have already committed the necessary code so you can just take it from > >> trunk and try it. If no objections, I'll include the module into the > next > >> release of MyFaces Core. This is also a good moment to provide ideas > about > >> how to improve this feature, so suggestions are welcomed. > >> > >> regards, > >> > >> Leonardo Uribe > > > > > > > > -- > > ___ > > > > Kito D. Mann | @kito99 | Author, JSF in Action > > Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and > consulting > > http://www.JSFCentral.com | @jsfcentral > > +1 203-998-0403 > > > > * Listen to the Enterprise Java Newscast: > http://www.enterprisejavanews.com > > * JSFCentral Interviews Podcast: > > http://www.jsfcentral.com/resources/jsfcentralpodcasts/ > > * Sign up for the JSFCentral Newsletter: > http://oi.vresp.com/?fid=ac048d0e17 > > >
