This page outlines the coding conventions used in HtmlUnit. If you wish to contribute code to this project then the code will be expected to follow these conventions.
The purpose of having common coding conventions is to make the code easier to understand and therefore more easily maintained. I have worked on far too many projects where over time the code became brittle or difficult to maintain. The conventions in this document are the best practices that I have adopted over time to keep the code easily maintainable and robust.
We use checkstyle to check as many coding
conventions as possible. Things covered by checkstyle are only documented below if we feel
that they require explanation. You can run checkstyle with the following target:
All code must have 100% automated test coverage using the JUnit
testing framework. It is strongly suggested that you write the code test-first but it is fine
as long as there are full tests for everything. Run the tests with the following target:
Abbreviations obscure meaning and therefore they are not to be used in variable/method names. If you saw the following code, would you have any idea what it was doing?
I didn't either - this was code that I have had to maintain..
There are some abbreviations that are so common that it doesn't make sense to exclude them. The following list contains all those abbreviations that are allowed. If it isn't in this list, it isn't allowed.
Abbreviation | Description | Comments |
Util | Utility | Used only in class names. i.e. StringUtil |
e | Exception | Used only in catch blocks. i.e. catch( MyException e ) |
i | Loop variable |
How do you add an abbreviation to the list? Bring it up on the mailing list and if none of the other maintainers object to it then it gets added.
The final keyword should be used wherever possible. It provides information to the compiler about your intended use of the code. This allows the compiler to generate move efficient code and identify potential errors.
Declare a variable to be final to indicate that it will only be assigned a value once.
Final instance variables must have been given a value by the end of the last constructor.
Final static variables must have been given a value by the end of the last static block.
Final local variables must have been given a value before being used.
Declare method parameters method final to indicate that they will not be changed.
Declare a method final to indicate that it may not be overridden
Declare a class final to indicate that it may not be subclassed
Use fully qualified import statements not wildcards. In other words, use
Instead of
Fully qualified import statements make it much easier to maintain the source. When I'm trying to learn someone else's code, one of the first things I do is expand all the .* imports so that I can figure out what class came from where. If they're already expanded then it makes it much easier to understand the code.
A common complaint about this convention is "how will I know if an import isn't needed anymore?". The answer is, use a tool that warns you about this. Eclipse and IDEA can be configured to warn you about unused imports. If your editor doesn't perform this check then the maven build will check it for you.
Indent by using spaces, not tabs. Indent four (4) spaces at a time.
From time to time code needs to be removed from public APIs. When possible we will deprecate the existing API (using the javadoc @deprecated tag). Code deprecated in this way should be left in the source for at least 6 months and at least 2 releases, meaning the time could be longer than 6 months if there are not 2 releases in a 6 month period but never less than 6 months. When deprecation is not possible a change log message containing "INCOMPATIBLE CHANGE" should be added to make these changes easy to find.
The dependencies page lists all the jars that you will need to have in your classpath.
The class
Most unit testing will be done within a framework like JUnit so all the examples here will assume that we are using that.
In the first sample, we create the web client and have it load the homepage from the HtmlUnit website.
We then verify that this page has the correct title. Note that getPage() can return different types
of pages based on the content type of the returned data. In this case we are expecting a content
type of text/html so we cast the result to an
Often you will want to simulate a specific browser. This is done by passing a
Specifying this BrowserVersion will change the user agent header that is sent up to the server and will change the behavior of some of the JavaScript.
Once you have a reference to an HtmlPage, you can search for a specific HtmlElement by one of 'get' methods, or by using XPath.
Below is an example of finding a 'div' by an ID, and getting an anchor by name:
XPath is a suggested way for more complex searches, a brief tutorial can be found in W3Schools
The last WebClient constructor allows you to specify proxy server information in those cases where you need to connect through one.
Specifying this BrowserVersion will change the user agent header that is sent up to the server and will change the behavior of some of the JavaScript.
Frequently we want to change values in a form and submit the form back to the server. The following example shows how you might do this.
Some HtmlUnit committers provide professional support beyond the free support provided on a volunteer basis by users and project members on HtmlUnit's mailing lists.
Marc Guillemot | |
---|---|
Committer since | 2004 |
Contact | http://www.efficient-webtesting.com |
Location | Bornheim, Germany |
Involvement in related projects | committer to NekoHTML, contributor to Rhino |
Involvement in other Open Source projects | committer to Groovy and Canoo WebTest |
Daniel Gredler | |
---|---|
Committer since | 2006 |
Contact | sdanig at users.sourceforge.net |
Location | Atlanta, USA |
Involvement in related projects | committer to CSSParser, contributor to Rhino |
Involvement in other Open Source projects | committer to Tapestry |
Getting the page inside <frame> element or <iframe> element can be done by using
HtmlPage.getFrames().
Suppose you have the following page:
You can use the following code to get the content of two.html:
Another example that navigates API docs to get a desired page of a class:
To get the page of the first frame (at upper left) and click the sixth link:
To get the page of the frame named 'packageFrame' (at lower left) and click the second link:
To get the page of the frame named 'classFrame' (at right):