The "New Contact" Function
The "new contact" feature is accessible at http://localhost:8080/phonelist/new.do. This URL should bring up a page with a form that accepts entry of a contact's properties: last name, first name, phone, fax, and email. You also need a save action that does the following:
- Accepts the data entered by the user at the Web browser
- Creates a new ContactBean instance with a unique ID value
- Stores that bean in the ContactDatabase repository.
The NewTest class should test for the following conditions or functionality:
- On the page displayed by the /showList.do action, a link entitled "Create New Contact" points to /new.do.
- On the new contact page, a form with last name, first name, phone, fax, and email fields has an action attribute pointing to /save.do.
- When a contact is submitted with random data for the fields, the newly created data shows up in the page the showList.do action displays. Furthermore, the number of contacts increases by one.
Type the code contained in Listing 1 into a file named NewTest.java in the src/WEB-INF/classes/com/abcinc/phonelist directory.
The NewTest class should look familiar. It is similar to the ShowListTest class from Part I. The NewTest class will perform the three tests specified in Listing 1. Right now, it performs the first of the three tests. You may compare your NewTest.java file with NewTest.java.v1 from the example code archive (phonelist-example-files.tgz). The NewTest.java.v1 file contains helpful comments, so you may wish to look at it even if you intend to use your own NewTest.java file.
For the new test, you also need to add a target to the build.xml file included in the example code. You should copy build.xml.v2 from the example code archive to a file named build.xml in your ~/projects/phonelist directory. Then, add the following target definition below the existing definition of test-showlist:
<target name="test-new" depends="compile-tests, post-compile-tests-init"
description="Run new test">
Additionally, you need to change the existing definition of the test target to append the test-new definition as one of the dependencies. Replace your existing definition of the test target with the following:
depends="compile-tests, post-compile-tests-init, test-showlist, test-new"
description="Run all tests"/>
Your build.xml file should closely resemble the build.xml.v3 file from the example code archive, with the exception of comments and possibly formatting. You could adopt build.xml.v3 as your build.xml file if you were unsure about whether you made the changes described above correctly.
Run the tests by typing "ant test". The ant test command will run both the showlist test and the new test to ensure that the old functionality is tested. Any changes in functionality have to not only provide the new functionality being tested for but also avoid breaking any old functionality.
The showlist test should still pass. The new test should also pass at this point, but you have not yet finished coding up the two other test cases of the new contact test suite. After you implement the two other test cases, the NewTest test suite should fail because you have not yet implemented the new contact functionality. Implement the two remaining tests so that you can then implement the functionality that those two tests test.
Add the following to the top of the NewTest.java file beneath the other import statements:
Add the following to NewTest.java after the line that reads: private static String newPath = "/phonelist/new.do":
private static String savePath = "/phonelist/save.do";
private static String randomCharacterSet =
The randomCharacterSet variable is used to generate random strings. The random strings are used to verify that the application is saving new contacts. Also add the following static variable declaration above the declaration of webConversation:
private static Random random = new Random();
Now add the new methods contained in Listing 2 to NewTest.java.
The testNewContactForm method verifies that the new contact form exists, that it contains the fields you require, and that it has the proper action setting. The testSaveNewContact method is a bit more complex. It figures out the number of rows in the list of contacts, then retrieves the new contact form and simulates the process of filling out the form fields with completely random strings of eight characters each for the last name, first name, phone, fax, and email fields. It then simulates a user pressing the "Save" button. Since both a "Save" button and a "Cancel" button exist, it is important to simulate the click on the right button. Finally, it parses the response from saving the contact, which should be the "showList" page. It checks that the number of contacts has increased by one and that one of the contacts in the list matches the newly entered contact.
The getRandomString method is simply a helper method that generates a random string of a length specified by a parameter. The testSaveNewContact method calls on getRandomString in order to generate values for the different fields. The testSaveNewContact method tests the values that were submitted with the updated list of contacts to make sure that the newly appearing contact on the list matches what was submitted. At this point, your NewTest.java file should be the same as NewTest.java.v2 from the example code, with the exception of comments and possibly formatting.
Run ant test now. The showlist test suite should pass completely, but the new test will only partially succeed. Two of the three test cases in the test suite will fail due to the lack of a "/new.do" action. You will receive an error message like the following:
[java] 2) testSaveNewContact(com.abcinc.phonelist.test.NewTest)com.meterware.httpunit.HttpException:
Error on HTTP request: 400 Invalid path /new was requested [http://localhost:8080/phonelist/new.do]