THIS IS A TEST INSTANCE. ALL YOUR CHANGES WILL BE LOST!!!!
Excerpt | ||
---|---|---|
| ||
How to achieve cleaner code and compile-time type-safety for your tests, probably saving 60% of your time |
If you use Test Driven Development in Wicket, the first approach is often to use component's path names (e.g., page:panel:form:component) to test them. This is good bearable at first, but as your pages get more and more complicated and have deeper hierarhices, you will find yourself spending a whole lot of time debugging typos and misconceptions (in my opinnion: you would waste 60% of your time doing this). The solution is: make your component hierarcy type-safe so that you can GET all of your components when testing:
Code Block |
---|
public class TestHomePage extends TestCase { private WicketTester tester; @Override public void setUp() { tester = new WicketTester(new WicketApplication()); } /** * */ public void testBookList() { // start and render the test page tester.startPage(HomePage.class); // assert rendered page class tester.assertRenderedPage(HomePage.class); // assert rendered label component tester.assertLabel("message", "If you see this message wicket is properly configured and running"); // assert rendered page class HomePage homePage = (HomePage) tester.getLastRenderedPage(); BookForm bookForm = homePage.getForm(); BookListView bookListView = bookForm.getBookListView(); List<BookListItem> bookItems = toLinkedList(bookListView.iterator()); { // Test values of 1st book BookListItem bookListItem = bookItems.get(0); // Note: no hassle with // run-time component path // id's assertEquals("first", bookListItem.getNameField().getValue()); assertEquals("", bookListItem.getAuthorField().getValue()); assertEquals("-1", bookListItem.getTypeChoice().getValue()); } { // Test values of 2nd book BookListItem bookListItem = bookItems.get(1); // Note: no hassle with // run-time component path // id's assertEquals("second", bookListItem.getNameField().getValue()); assertEquals("", bookListItem.getAuthorField().getValue()); assertEquals("-1", bookListItem.getTypeChoice().getValue()); } { // Test values of 3rd book BookListItem bookListItem = bookItems.get(2); // Note: no hassle with // run-time component path // id's assertEquals("third", bookListItem.getNameField().getValue()); assertEquals("", bookListItem.getAuthorField().getValue()); assertEquals("-1", bookListItem.getTypeChoice().getValue()); } { // Set new values FormTester formTester = tester.newFormTester(bookForm .getPageRelativePath()); // formTester.setValue(bookItems.get(1).getAuthorField(), "Hemingway"); // // TODO New feature request tester.getServletRequest().setParameter( bookItems.get(1).getAuthorField().getInputName(), "Hemingway"); // Submit changes // formTester.submit(bookForm.getSubmitButton()); // TODO New feature // request formTester.submit(); } tester.assertRenderedPage(HomePage.class); // Verify the submitted value { // Test values of 2nd book BookListItem bookListItem = bookItems.get(1); // Note: no hassle with // run-time component path // id's assertEquals("second", bookListItem.getNameField().getValue()); assertEquals("Hemingway", bookListItem.getAuthorField().getValue()); assertEquals("-1", bookListItem.getTypeChoice().getValue()); } } /** * @param <T> * @param iterator * @return List<T> */ public static <T> List<T> toLinkedList(Iterator<T> iterator) { List<T> linkedList = new LinkedList<T>(); for (; iterator.hasNext();) { linkedList.add(iterator.next()); } return linkedList; } } |
...
Code Block |
---|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.sourceforge.net"> <head> <title>Wicket Quickstart Archetype Homepage</title> </head> <body> <strong>Wicket Quickstart Archetype Homepage</strong> <br/><br/> <span wicket:id="message">message will be here</span> <form wicket:id="form"> <table border="1"> <tr wicket:id="book_list"> <th>Name:</th><td><input type="text" wicket:id="name"/></td> <th>Author:</th><td><input type="text" wicket:id="author"/></td> <th>Type:</th><td><select wicket:id="type"></select></td> </tr> </table> <input type="submit" wicket:id="submit" value="Submit"/> </form> </body> </html> |
The benefits of the introduced approach are:
- Compile-time type-safety
- By not hardcoding the runtime component paths into the tests, you can make your tests truly modular!
- You save 60% of your time (the time you would have wasted banging your head to the wall of wrong paths and components)
- The code is cleaner and nicer, easier to maintain
- The test-code is easier to read and makes much more sense as a spec