YahooGroups now hosts XPATG, a group dedicated to facilitating the adoption of Extreme Programming on ATG projects: http://groups.yahoo.com/group/xpatg/
http://sourceforge.net/projects/mockobjects/ (MockObjects integration with Dynamo -- note the one on tersesystems.com is more recent as of March 8th, 2004)
http://tersesystems.com/code/ (has some utility modules for ATG Dynamo)
http://sourceforge.net/projects/dynamomocks/ (Still has some growing up to do)
http://www.onwhichsubject.com/DynaCactus (Using Cactus with Dynamo, relatively new -- PiranMontford)
The first thing to be aware of is the DisposableClassLoader?; this is detailed in an appendix of the Programming Guide. The DisposableClassLoader? will read in new classes that have been changed on the filesystem without restarting the server, so the tests can be rerun immediately.
The second thing to be aware of is that not all of Dynamo needs to be run at once. For instance, if you're only testing the repository interfaces, you can set up an application module which only loads the repositories and nothing else. In some cases, you can modify the startSqlRepository script to execute your classes directly, so that a minimal Nucleus is created and a suite of tests can be run directly (although currently this depends on source code which isn't available publicly).
Finally, if you just want to hack on code without reloading anything, you can use BeanShell and Dynamo to provide an interpreted Java like environment. This can give you the chance to change functionality through your interfaces without bringing down anything and without any classloader issues.
Also note that in many cases UnitTests can run without a full Nucleus startup at all. If you have classes which take interfaces as parameters and you're not running through a Dynamo pattern (i.e. formhandlers) then you can test those methods directly with mockobjects done with inner classes which implement the required interfaces and then pass in the mock objects as parameters without starting anything externally.
-- WillSargent.
I've found that clicking around randomly is actually a strong testing tactic (as opposed to following what I "know" is the rational way to go through the site). I'm still not quite sure how you'd get code to emulate a user for you and input data for you (say, registering a user, getting a "this username already registered" error and then changing the name and trying again). When you compare the code it would take to write this, it seems simpler to have it run through QA (because any code you write won't take advantage of the pathological pathways users are capable of).
Have you looked at Meterware's HttpUnit? It has classes to let JavaUnit tests speak request/response natively, POST forms, interrogate DOMS and such. I was busy learning Dynamo and was doing it via HttpUnit. Except that didn't get very far down that route, since HttpUnit seemed not to understand redirection. -- KeithBraithwaite (who's no longer working with Dynamo)
I looked at HttpUnit a long time ago, in conjunction with a C++ project I was interested in (I ended up doing manual testing because expect was incomprehensible to me). It might work, but I haven't looked at it so I dunno.
If you have any tips on using with Dynamo, please put it up on the page. As soon as I do, I will.
How do you see output?
It's an extension to JUnit, so you don't. You suck the DOM out of the Response and iterate over that assert()ing for whatever content you expect. I've put an example up on HttpUnit.
I know this isn't really extreme programming, but I think there are some assumptions behind ExtremeProgramming that don't fit well within the context of a server environment... if you're building a project from scratch then XP is the way to go, but most people prefer not to do that.
-- WillSargent.
I think there are some assumptions behind ExtremeProgramming that don't fit well within the context of a server environment
Don't let Ron hear you say that. You're probably right, though. Anything that makes testing hard, or slows the test-code cycle will conflict with XP.
Hopefully we can start to continue to expand this page.
In my new role I've been nominated to become the local Dynamo "expert", and I'll certainly be wanting any Dynamo projects at AMS eCustomer Europe to be using as many XP practices are possible. -- KeithBraithwaite
Which classes are you talking about?
The initial costs are a bit high, but not much more than a day or two. The interesting thing about doing so, is that it really forces you into understanding the Dynamo implementation. So far the team have found the switch a bit hard, but they really like the effect. -- SteveFreeman
It doesn't seem as if anyone is claiming that XP is too hard with servers, just that it is harder, and it's worth recognizing that, and it would be nice to know (even qualitatively) how much harder.
When oh when [per KentBeck] will we reserve our tight fists full of dollars for tools, libraries & servers created only via TestDrivenDesign, so that just to test our own code thru these systems we don't need to bend over backwards and stick our heads up our butts? -- PhlIp
It would be really phat if vendor's like ATG and WebLogic provided test suites and harnesses for their own product, maybe as part of their API? pre-existing tests for SQLStoreDBManager would encourage and aid developers to write proper tests for their own extensions. Come to think of it, it would be great to start an instance up in test mode, and be able to exercise the system automatically. given the all-Java architecture, this shouldn't be too difficult to do, but we all know that writing tests retroactively isn't the way to go. -- SalvatoreSferrazza
I was just browsing the javadoc for Dynamo 4.5.1 and found no reference to atg.servlet.GenericServletRequest? or atg.servlet.GenericServletResponse? there. The closest thing I saw was javax.servlet.GenericServlet?. Are you looking at an older/newer version of Dynamo? I'd really like to start doing end to end unit tests of all my components within Dynamo, and anything that could help would be great.
I have done extensive testing in Dynamo by making some minor changes to JUnit. Basically, I modified JUnit to to run inside of a Dynamo Servlet. It doesn't help testing the JHTML, but I can test all of the Form Handlers, Business Objects and property files, live in the server. Also, I pass the "request" and "response" down to TestCase. Having these available means I can resolveName on the property files and output test info to the browser. By sending output to the browser, I don't have to search the dynamo.log file to try and find my test info.
I have been planning on making similar changes to be able to run JUnit in a Servlet. All this requires is by-passing main and running start. -- MarkStang
Also, given that the JhTml? is essentially a programming language, I've also started writing tests in it. I pass stuff into AtgDynamoDroplets? and adjust rendered output accordingly. Successful tests render a full stop (like JUnit) and failures render something large in red. By building up a hierarchy of page fragments, I can get quite a long way and see the result in a single page. -- SteveFreeman
public void testSomeDynamoFeature(String pComponentPath) { HeadPipelineServlet head; head = (HeadPipelineServlet)Nucleus.getGlobalNucleus() .resolveName("/atg/dynamo/servlet/pipeline/DynamoHandler", Nucleus.getGlobalNucleus(), true) DynamoHttpServletRequest request = ((HeadPipelineServlet)).getRequest(null); response.setResponse(new GenericHttpServletResponse()); response.setOutputStream(new ByteArrayServletOutputStream()); DynamoHttpServletResponse response = new DynamoHttpServletResponse();// component path is a string like "/path/to/some/dynamo/component" SomeClass someClass = (SomeClass)request.resolveName(pComponentPath); someClass.handleSomeTest(request,response); }
Here at ZEFER Pittsburgh we're in the midst of our first serious Dynamo project, and I have to say its one of the most amazing pieces of software I've ever encountered. The ATG guys have built an incredibly flexible and extensible system. A great demonstration of the power of good design. Anyway, we're running the project as XPish as we can, and hoping to work through the difficult UnitTest of the server etc. We'll let the group know if we come up with any good ideas. Thanks for the hints gang! -- ToddJonker
Given this, I see no reason why Dynamo needs to call that setter. I can just as easily (actually much easier) call the setter myself in my development environment passing in a variety of objects representing the conditions I want to test. Because Dynamo decouples the process of hooking up components from the components themselves, I see no reason to run these sorts of tests within Dynamo.
The same approach works for servlets (droplets). If I can create a subclass of DynamoHttpServletRequest and Response and simulate the values that the JHTML might put into it, I don't need to run the application server. I just isolate the unit and control the inputs and outputs.
This approach has worked wonderfully for me. I see no reason to run the overhead of an app server when I can simply control the inputs to and examine the outputs from my unit. -- TracieKarsjens
Absolutely!!! Some of us in the ExtremeTuesdayClub have been doing this for a while. The next tricky part is how to test the jhtml. I try to treat it like code (which it is) and refactor and test accordingly. As always, this gets much harder when you inherit someone else's over-complicated "architecture". -- SteveFreeman
I've taken a look at the ExtremeTuesdayClub, and it's fascinating. I especially like http://www.xpdeveloper.com/cgi-bin/wiki.cgi?TestingServlets. The big question I have is that it's all very well to try out droplets and formhandlers in isolation. But usually you have access to various attributes and parameters of the request, you may want to get at repository information, and you might want to do some XML work. How do you set all this stuff up without using Nucleus? I've been working on a MockRepository? interface, but if you don't have that available, do you just go in and configure a GSARepository object by hand? -- WillSargent
Please consider contributing to the mockobjects project on sourceforge. In the meantime... can you give us a concrete example you want to work on? Also, are you using Dynamo 4 or 5 repositories? -- SteveFreeman
I'm struggling with how to setup JUnit tests for the extensions to the DCS. Integrating servlets, Nucleus components and repositories into JUnit is a daunting task. If anybody would care to share their progress in this area it would be greatly appreciated. -- ToddBreiholz
Has anyone tried using Cactus? I frobbed a few switches to turn Cactus into an Application Module and verified that it worked as a J2EE App, but I haven't done anything with it since then. It looks like it's fairly trivial to get it to use JHTML instead of JSP for redirection, so that might be a good place to build on. -- WillSargent.
PiranMontford writes: I've written a module for this, see the list of tools above.
Hi everyone. I'm in the middle of an ATG Dynamo eCommerce project and we're trying to implement some of the XP practices. By a long way, TestDrivenDevelopment looks like the hardest one. I've read some things like DaveHoover 's BabySteps, but the MockObjects project on SourceForge seems moribund. Also, nobody seems to have written anything about XP and Dynamo recently. Can anyone offer me some practical advice for Dynamo 6.0.0? -- RobertAtkins
As far as lower level stuff goes: one advantage of Dynamo is that you can turn debug logging on and off dynamically. Therefor, you can include a debug statement at the beginning of all important methods in a component, and trace down a problem. Aggressive use of assertions helps as well. -- WillSargent
By practical advice, I mean answers to questions such as these: How do you run unit tests on a dynamo component without Dynamo running? Because as soon as Dynamo's not running, all those if (isLoggingDebug()) { logDebug("...")} statements fail because the class can't find its logger... -- RobertAtkins
Okay. You have to set the log listeners for those services. You can do this through an InversionOfControl framework, or you can do it by hand by creating a class that implements LogListener? and generates log events. Take a look at ApplicationLoggingImpl?.java for an example.
I went to AtgOpen? and wrote up a summary to the WritingTestsFirstInAtg session. It was useful information and helped our project get started with TDD and ATG. As BabySteps shows, though, TDD eventually fizzled out for us. I'm still trying to resurrect it. --DaveHoover
Rao is unit testing on ATG dynamo.
Vanita
This page mirrored in ExtremeProgrammingRoadmap as of April 29, 2006