Unit testing emails

By Confusion on Monday 23 June 2008 21:25 - Comments (9)
Categories: Software engineering, Testing, Views: 4.440

Sometimes the main purpose of an application is sending emails. But how do you unit test such a beast? Manually verifying the arrival and contents of the emails is fine for small amounts of email, but when the number of code paths and email varieties grows, you need an automated way to verify that the correct emails have been sent.

I have not yet done any research on existing libraries/frameworks that solve this problem, but I think it has to be either of two solutions:
  1. Have the test code poll a dedicated email box, matching emails with testcases and determining whether they are correct
  2. Launch a mock email server from your code, modify the test configuration in such a way that the mails are sent to that mail server and immediately check back whether the mails are correct.
The major drawback of the first solution is that you have no control over the moment when, and the order in which, the emails arrive. The largest problem of the second solution is writing/finding that server, that programmatically allows you to fetch the last received mail, etc.

If you already have an project layout and architecture that allows dependency injection and a seperate configuration for tests, then the second seems the obvious way to go: much more flexible and contained. Unfortunately, the project for which I would like to implement this does not have anything of the sort and adding that will not be easy, which make me prefer the first solution.

There is another thing to consider: library support. As I said, I have not yet searched, but my guess is that the second solution is the one for which there will be several solutions readily available, because it is the 'proper' solution. Moreover, I doubt whether I will find any existing solution that makes implementing the first solution easier.

I think I'll just go with the 'proper' solution :).

JSON to XML conversion

By Confusion on Saturday 21 June 2008 12:48 - Comments (4)
Categories: Software engineering, XML, Views: 14.578

If a form POST needs to pass a lot of structured data, it might be advisable to prescribe an XML format in which the data should be passed. This enables validation of the data with an XSD and the readability makes debugging easier. However, building an XML document in javascript is neither elegant nor easy. It is much easier to just build the object structure and convert it to a JSON string, for instance using this helper library (2.3 KB when 'compressed' with a decent utility; smaller if you don't need the 'parse' method and strip it).

Allowing JSON to be posted required the receiver to convert the JSON to XML before validating it, which poses three problems
  1. JSON doesn't have any namespaces
  2. JSON doesn't distinguish between elements and attributes, like XML does
  3. JSON doesn't really care about ordering
If the elements in the XML are all from the same namespace, the first problem can be remedied by adding the relevant default namespace declaration to the root element. If multiple namespaces are required, there are two solutions:
  1. Namespace the JSON elements in some way ( { ns1_element1: "bar" } )
  2. Magically determine which element is from which namespace
Obviously, both solutions have their problems. In the first case, you need a (synchronised) mapping of namespace identifiers to the actual namespaces that would need to be declared and, depending on usage, that mapping may be necessary in the javascript as well. In the second case, different namespaces cannot declare the same elements, which is quite limiting.

The second problem can be solved in much the same way: by prefixing the attributes-to-be, for instance with xml_attr_<elementname>. Another solution is keeping a (synchronised) list of the attributes appearing in the XSD, checking for their presence and converting them if required. Again, boh solutions have problems, similar to the solutions to the first problem.

The third problem can again be solved in two ways: either by requiring the JSON to be constructed in the correct order and keeping that order intact when converting the JSON to XML (for instance by using these classes, modified by changing the HashMap in JSONObject to a LinkedHashMap) or you could write code to magically impose the order required by the XSD on the resulting XML. The last solution poses a pretty daunting task, while the first solution is easier, provided the users receive clear feedback about ordering problems when testing the JSON they constructed.

After this analysis, our conclusion was that for our case, allowing the webdevelopers to post JSON is an acceptable solution, as we
  • All our elements are in one namespace,
  • The webdevelopers see no problem in making sure the JSON is ordered correctly
  • An attribute prefix does not really limit the possibilities, as long as it is documented, the webdevelopers are kept aware of it and clear feedback points out where they forgot to mark an attribute
The only question that remains on my part is: is it really much easier/cleaner to construct JSON that to construct XML in javascript?

The Eclipse update annoyance

By Confusion on Friday 20 June 2008 08:47 - Comments (2)
Category: Software engineering, Views: 6.582

Can anyone explain to me why the Eclipse 'update' feature has such braindead server selection characteristics? There are two possiblities:
  1. Every time you update, you have to select which server is closest to you, multiple times.
  2. You tick 'auto-select closest server' and it selects a slow US server, while I'm in Europe and there are plenty European servers available.
Can there possibly be a reason for this? I can't think of one, as every other update feature I know works without being so annoying. Hell, even websites like Sourceforge auto-select a decent mirror. Isn't there one Eclipse developer that considers this annoying enough to fix it? It can't be that hard to just store the last server the user selected.

A namespace gotcha in XSL transformations

By Confusion on Thursday 19 June 2008 16:56 - Comments (1)
Categories: Software engineering, XML, Views: 2.485

Say you have an xml document that conforms to the schema it references

XML:
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<root 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xml.mydomain.nl/meaningful-path/1.0 schema.xsd"
    xmlns="http://xml.mydomain.nl/meaningful-path/1.0">

    <foo>Foo!</foo>
</root>


You use the default namespace for the namespace from which you will reference the most element, to keep the document as short and readable as possible.

Now you want to transform this bit of XML using an XSLT:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://xml.mydomain.nl/meaningful-path/1.0"
    version="1.0">

    <xsl:output method="xml" indent="yes" encoding="UTF-8" />
    
    <xsl:strip-space elements="*" /> 

    <xsl:template match="/">
        <xsl:apply-templates select="//root"/>
    </xsl:template>
    <xsl:template match="root">
      <bar><xsl:value-of select="foo"</bar>
    </xsl:template>
</xsl:stylesheet>


and you expect the output to read

XML:
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xml.mydomain.nl/meaningful-path/1.0 schema.xsd" 
xmlns="http://xml.mydomain.nl/meaningful-path/1.0">
    <bar>Foo!</bar>
</root>


Unfortunately, this won't work, because of this tiny fact from section 2.4 of the XSLT specification:
The default namespace is not used for unprefixed names.
As a result, only this will work:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns1="http://xml.mydomain.nl/meaningful-path/1.0"
    version="1.0">

    <xsl:output method="xml" indent="yes" encoding="UTF-8" />
    
    <xsl:strip-space elements="*" /> 

    <xsl:template match="/">
        <xsl:apply-templates select="//ns1:root"/>
    </xsl:template>
    <xsl:template match="ns1:root">
      <bar><xsl:value-of select="ns1:foo"</bar>
    </xsl:template>
</xsl:stylesheet>



I'm still not sure why this is the case, but I do know it took me quite a while to figure out...

NB. I know this schema.xsd schemalocation reference will only work for a local file and even then only in some cases. Replace schema.xsd by
http://xml.mydomain.nl/meaningful-path/1.0/schema.xsd before nitpicking about syntax :)

When a tutorial makes you smile

By Confusion on Wednesday 18 June 2008 16:44 - Comments (3)
Categories: Java, Software engineering, Views: 4.257

Sun, in the Java EE 5 tutorial:
The Application Server supports iterative development. Whenever you make a change to a Java EE application, you must redeploy the application.