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 <[email protected]>
> 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.
>