Paul, thanks VERY much for the explanations.
I refactored my code to almost match your recomendation (I did not put stuff from src/main/resources into src/main/java). When running mvn clean test I get: FAILED: testElementIsOnPage java.lang.RuntimeException: Request was not handled: 'demo/DayMonthYearDateInputDemo' may not be a valid page name. at org.apache.tapestry5.test.PageTester.renderPage(PageTester.java:177) at test.si.najdi.tapestry.library.demo.components.DayMonthYearDateInputDemo.testElementIsOnPage(DayMonthYearDateInputDemo.java:14) at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:74) at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92) at org.apache.maven.surefire.Surefire.run(Surefire.java:177) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) ... Removed 24 stack frames Just prior to this error message a list of available components is also printed out on the console: INFO [23:11:33.128] Available components: ActionLink: org.apache.tapestry5.corelib.components.ActionLink AddRowLink: org.apache.tapestry5.corelib.components.AddRowLink ... Zone: org.apache.tapestry5.corelib.components.Zone demo/DayMonthYearDateInput: test.si.najdi.tapestry.library.demo.components.DayMonthYearDateInputDemo demo/DayMonthYearDateInputDemo: test.si.najdi.tapestry.library.demo.components.DayMonthYearDateInputDemo Why there are 2 demo components? The source tree: ├───src │ ├───main │ │ ├───java │ │ │ └───si │ │ │ └───najdi │ │ │ └───tapestry │ │ │ └───library │ │ │ ├───components │ │ │ │ DayMonthYearDateInput.java │ │ │ │ NajdisiLogo.java │ │ │ │ │ │ │ ├───mixins │ │ │ │ ZoneUpdater.java │ │ │ │ │ │ │ ├───services │ │ │ │ LibraryModule.java │ │ │ │ │ │ │ └───util │ │ │ IntegerOptionModel.java │ │ │ IntegerSelectModel.java │ │ │ IntegerValueEncoder.java │ │ │ Month.java │ │ │ │ │ └───resources │ │ │ log4j.properties │ │ │ │ │ └───si │ │ └───najdi │ │ └───tapestry │ │ └───library │ │ ├───components │ │ │ day-month-year-date-input-error.png │ │ │ day-month-year-date-input.png │ │ │ DayMonthYearDateInput.properties │ │ │ DayMonthYearDateInput.tml │ │ │ DayMonthYearDateInput.xdoc │ │ │ DayMonthYearDateInput_sl_SI.properties │ │ │ najdi-logo.gif │ │ │ NajdisiLogo.xdoc │ │ │ │ │ └───mixins │ │ ZoneUpdater.js │ │ │ ├───site │ │ │ site.xml │ │ │ │ │ └───xdoc │ │ index.xml │ │ │ └───test │ ├───conf │ │ testng.xml │ │ │ └───java │ └───test │ └───si │ └───najdi │ └───tapestry │ └───library │ ├───base │ │ AbstractT5ComponentsLibraryTest.java │ │ │ ├───components │ │ DayMonthYearDateInputTest.java │ │ │ └───demo │ │ DemoModule.java │ │ │ └───components │ DayMonthYearDateInputDemo.java │ DayMonthYearDateInputDemo.tml │ testng.xml ==================== <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Najdi.si Tapestry Components Suite" parallel="false" thread-count="10" annotations="1.5" verbose="2"> <parameter name="tapestry.integration-webapp" value="src/main/webapp"/> <test name="DayMonthYearDateInput"> <classes> <class name="test.si.najdi.tapestry.library.demo.components.DayMonthYearDateInputDemo"/> </classes> </test> </suite> AbstractT5ComponentsLibraryTest.java ========================================================== package test.si.najdi.tapestry.library.base; import test.si.najdi.tapestry.library.demo.DemoModule; import com.formos.tapestry.testify.core.TapestryTester; import com.formos.tapestry.testify.testng.TapestryTest; public abstract class AbstractT5ComponentsLibraryTest extends TapestryTest { private static final TapestryTester SHARED_TESTER = new TapestryTester("demo", DemoModule.class); public AbstractT5ComponentsLibraryTest() { super(SHARED_TESTER); } } I tried instantiating TapestryTester with all kind of appPackage names I could think off. DayMonthYearDateInputTest.java ========================================================== package test.si.najdi.tapestry.library.components; public class DayMonthYearDateInputTest { } DemoModule .java ========================================================== package test.si.najdi.tapestry.library.demo; import org.apache.tapestry5.ioc.Configuration; import org.apache.tapestry5.services.LibraryMapping; public class DemoModule { public static void contributeComponentClassResolver( Configuration<LibraryMapping> configuration) { configuration.add(new LibraryMapping("demo", DemoModule.class.getPackage().getName())); } } DayMonthYearDateInputDemo .java ========================================================== package test.si.najdi.tapestry.library.demo.components; import org.apache.tapestry5.dom.Document; import org.testng.Assert; import org.testng.annotations.Test; import test.si.najdi.tapestry.library.base.AbstractT5ComponentsLibraryTest; public class DayMonthYearDateInputDemo extends AbstractT5ComponentsLibraryTest { @Test public void testElementIsOnPage() { Document page = tester.renderPage("demo/DayMonthYearDateInputDemo"); Assert.assertNotNull(page.getElementById("h1")); } } DayMonthYearDateInputDemo .tml ========================================================== <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <head> <title>DayMonthYearDateInputTestPage</title> </head> <body> <h1 id="h2">DayMonthYearDateInputTestPage</h1> </body> </html> Where am I failing? I am using Tapestry 5.1.0.5, TestNG 5.9 and Testify 1.0.0. Thanks, Borut 2009/9/2 Paul Field <paul.fi...@db.com> > Hi Borut, > > It looks like the T5 page class also contain the tests. > > You need to have separate classes for the page and for the tests. To test > components I create pages that I call "demo" pages (because they > demonstrate the component). > > Also I would advise putting the test class in a different package (I know > it's in a different source tree - but the java package is the same) as > that will stop T5 thinking the test class is part of the T5 > pages/components/mixins classes. T5 uses a special classloader for those > classes in order to implement its live reloading functionality - so best > to keep other things away from that magic. > > So, my project layout would look like the following (notice that some of > this is a very personal choice, but I'll present everything and you can > choose what you like): > > +---src > +---main > ¦ +---java > ¦ ¦ +---si > ¦ ¦ +---najdi > ¦ ¦ +---tapestry > ¦ ¦ +---library > ¦ ¦ +---components > ¦ ¦ ¦ DayMonthYearDateInput.java > ¦ ¦ ¦ day-month-year-date-input-error.png > ¦ ¦ ¦ day-month-year-date-input.png > ¦ ¦ ¦ DayMonthYearDateInput.properties > ¦ ¦ ¦ DayMonthYearDateInput.tml > ¦ ¦ ¦ DayMonthYearDateInput.xdoc > ¦ ¦ ¦ > DayMonthYearDateInput_sl_SI.properties > ¦ ¦ ¦ > ¦ ¦ +---mixins > ¦ ¦ ¦ ZoneUpdater.java > ¦ ¦ ¦ ZoneUpdater.js > ¦ ¦ ¦ > ¦ ¦ +---services > ¦ ¦ ¦ LibraryModule.java > ¦ ¦ ¦ TestInfrastructureModule.java > ¦ ¦ ¦ > ¦ ¦ +---util > ¦ ¦ IntegerOptionModel.java > ¦ ¦ IntegerSelectModel.java > ¦ ¦ IntegerValueEncoder.java > ¦ ¦ Month.java > ¦ ¦ > ¦ +---resources > ¦ log4j.properties > | > +---site > ¦ ¦ site.xml > ¦ ¦ > ¦ +---xdoc > ¦ index.xml > ¦ > +---test > +---conf > ¦ testng.xml > | > +---java > +---test > +---si > +---najdi > +---tapestry > +---library > +---base > ¦ > AbstractT5ComponentsLibraryTest.java > ¦ > +---demo > ¦ ¦ DemoModule.java > ¦ +---components > ¦ DayMonthYearDateInputDemo.tml > ¦ DayMonthYearDateInputDemo.java > +---components > DayMonthYearDateInputTest.java > > > Things to note: > > a) I've put all the component's resources alongside the java class (in > src/main/java/si/najdi/tapestry/library/components). Personally, I find it > > much easier to work with resources that are associated with a class if I > do this. > > To make Maven allow this you need to add the following to your pom (you > may need to tweak the 'includes' and 'excludes' rules depending on what > you have in your source folders): > <resources> > <resource> > <directory>src/main/resources</directory> > <filtering>false</filtering> > </resource> > <resource> > <directory>src/main/java</directory> > <excludes> > <exclude>**/*.java</exclude> > </excludes> > <filtering>false</filtering> > </resource> > </resources> > > <testResources> > <testResource> > <directory>src/test/resources</directory> > <filtering>false</filtering> > </testResource> > <testResource> > <directory>src/test/java</directory> > <excludes> > <exclude>**/*.java</exclude> > </excludes> > <filtering>false</filtering> > </testResource> > </testResources> > > > > b) I put all the tests in a parallel package hierarchy prefixed with > "test". So the tests for components in: > si.najdi.tapestry.library.components > will be found in the package: > test.si.najdi.tapestry.library.components > > This makes it easy to find the tests but also keeps them separate from a > Java runtime point-of-view. > > FYI, the Eclipse plugin MoreUnit (http://moreunit.sourceforge.net/) makes > it easy to jump between classes and tests and understands this convention. > > > c) For components, I create "demo" pages in a parallel hierarchy near the > test package. So the demo pages for: > si.najdi.tapestry.library.components > will be found in the package: > test.si.najdi.tapestry.library.demo.components > > This choice makes the demo pages and the tests fairly near each other in a > > package explorer view in your IDE. You can't put them in the same package > because of T5's special classloading for pages/components/mixins. > > > When running the tests, I create the IOC container with an additional > module (give this class as a parameter when you create your > TapestryTester): > > package test.si.najdi.tapestry.library.demo; > > public class DemoModule { > public static void contributeComponentClassResolver( > Configuration<LibraryMapping> configuration) { > configuration.add(new LibraryMapping("demo", > DemoModule.class.getPackage().getName())); > } > } > > And I would render the page like this: > private Document renderPage() { > return tester.renderPage("demo/DayMonthYearDateInputDemo"); > } > > > Hope you find that useful. > > - Paul > > > > --- > > This e-mail may contain confidential and/or privileged information. If you > are not the intended recipient (or have received this e-mail in error) > please notify the sender immediately and delete this e-mail. Any > unauthorized copying, disclosure or distribution of the material in this > e-mail is strictly forbidden. > > Please refer to http://www.db.com/en/content/eu_disclosures.htm for > additional EU corporate and regulatory disclosures. >