Applying ExtremeProgramming techniques to AtgDynamo. The bulk of this conversation is about UnitTest''''''ing. ---- YahooGroups now hosts XPATG, a group dedicated to facilitating the adoption of Extreme Programming on ATG projects: http://groups.yahoo.com/group/xpatg/ ---- Useful ATG applications: http://sourceforge.net/projects/mockobjects/ (MockObject''''''s 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) http://atgdust.sourceforge.net/ ATG Dust: A Toolkit for writing ATG Nucleus and Repository based tests within JUnit ---- It's important to be aware that Dynamo takes a while to start up. There's a lot of classes and queries from repositories that a full blown application goes through, so there are a number of things which can be done to minimize the cycle time. 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 UnitTest''''''s 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 suppose a good way to do UnitTest''''''s might be to use JHTML pages and write a droplet to look for expected bean states. You could probably wire a good testing framework in Dynamo by having a property in each component which would call up a tester in doStartService to make sure it was internally consistent, but I don't see any functional difference between that and just ordinary assertions. 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 ---- I disagree that unit testing, and hence ExtremeProgramming, is too hard to do with servers. I've just introduced one of our teams to the joys of MockObject''''''s. It's a bit harder in AtgDynamo, rather than raw JavaServlets, but not impossible. It really shows up where ATG should have used interfaces rather than classes. ''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 ----- Here is a more solid example of using Generic''''''Servlet''''''Request,it is not a documented class so use at your own risk. public void testSomeDynamoFeature(String pComponentPath) { Head''''''Pipeline''''''Servlet head; head = (Head''''''Pipeline''''''Servlet)Nucleus.getGlobalNucleus() .resolveName("/atg/dynamo/servlet/pipeline/Dynamo''''''Handler", Nucleus.getGlobalNucleus(), true) Dynamo''''''Http''''''Servlet''''''Request request = ((Head''''''Pipeline''''''Servlet)).getRequest(null); response.setResponse(new Generic''''''Http''''''Servlet''''''Response()); response.setOutputStream(new Byte''''''Array''''''Servlet''''''Output''''''Stream()); Dynamo''''''Http''''''Servlet''''''Response response = new Dynamo''''''Http''''''Servlet''''''Response(); // component path is a string like "/path/to/some/dynamo/component" Some''''''Class someClass = (Some''''''Class)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 ----- I'm glad some folks like ATG. I don't like it much at all. Of course, our project is writing an RMI app, not a web app. It really lacks good RMI support. .02 ----- Erm... Dynamo uses the RMI support that comes with the box. If you want to write an RMI application, you just have to create a GenericRMIService and add that to the exportedRMIServices list in the RMIServer component. -- WillSargent ----- I totally disagree with a lot of the sentiments on this page. I have been working almost exclusively with Dynamo starting with version 3 up to the current 5.1 version. I find Dynamo applications to be extremely easy to test - certainly easier than other architectures. However, I think the reason I have such a different opinion is that I never run tests within Dynamo. In other words, I never need to start the server to run my test cases. Why? Well Dynamo is really good about decoupling object. Let's say I have a servlet that knows about some service. The code for the servlet "looking up" the service doesn't exist within the servlet. The servlet just has a getter and a setter for the service. In the properties file I indicate what Dynamo should pass into the setter and the Nucleus takes care of it. 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 D''''ynamoHttpServletRequest 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 MockObject''''''s 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 practical advice goes... it depends on what you want to do. XP is a means to an end, not the end itself. It's not the only methodology, or even the best one in all circumstances. I will say that I've been very happy with the JwebUnit API (http://jwebunit.sourceforge.net) recently for testing JHTML pages. 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. ---------------------- I am a newbie to ATG and JUnit. I am currently writing a JUnit test to connect to a repository and just get all items from the repository. But when I connect to repository I get a NullPointerException. Anybody has idea on what am I doing wrong. My TestRunner properties file calls my TestRunner that starts the Test suite. Vanita ------------------------------ 10/27 2007 I'd like to mention another tool for helping develop unit tests with ATG. It allows Nucleus and Repositories to be started within seconds inside a JUnit test. The project website is http://atgdust.sourceforge.net/. The project itself is hosted at http://sourceforge.net/projects/atgdust/ -----