UPDATE / 13 March 2009: snakefight 0.3 now has a --include-jar option, prefer that to using my hack. After reading P. Jenvey's blog post about Deploying Pylons Apps to Java Servlet Containers I immediately downloaded the Jython 2.5 beta and installed snakefight to give it a try. One of our services where I work is a Pylons based application. It is deployed using paster and Apache ProxyPass. Our main application is written in Java and is deployed as a war under Jetty. So if I can get my Pylons application built as a war and deployed that way, it would greatly simplify our deployment process. [sourcecode language="bash"] $ sudo /opt/jython25/bin/easy_install snakefight $ /opt/jython25/bin/jython setup.py develop $ /opt/jython25/bin/jython setup.py bdist_war --paster-config dev_r2.ini ... output of success and stuff ... $ cp dist/project-0.6.8dev.war /opt/jetty/webapps [/sourcecode] Now I visit my local server and hit the project context. I get some database errors, kind of expected them. So for the time being, I'll be running this directly using Jython to speed up the debugging process. A quick googling of my DB issues turns up zxoracle for SQLalchemy which uses Jython zxJDBC. I install that in to sqlalchemy/databases as zxoracle.py and give it another go. Changing the oracle:// lines in my .ini file to now read zxoracle:// Now it can't find the 3rd party Oracle libraries (ojdbc.jar). [sourcecode] $ cd ./dist $ jar xf project-0.6.8dev.war $ cd WEB-INF/lib $ ls # no ojdbc.jar as expected ... $ cd ~/project $ export CLASSPATH=/opt/jython25/jython.jar:/usr/lib/jvm/java/jre/lib/ext/ojdbc.jar $ /opt/jython25/bin/jython /opt/jython25/bin/paster serve --reload dev_r2.ini [/sourcecode] Now it is looking a little better and it able to find the jar, but still a DB issue, now with SQLalchemy library. Not having a ton of time to investigate, I decide to try rolling back my SQAlachemy version for Jython. Turns out rolling back to 0.5.0 fixed the issue. I'll be investigating why it was breaking with 0.5.2 soon (tm). So now I rerun it, and get a new error. [sourcecode lang="bash"] AttributeError: 'ZXOracleDialect' object has no attribute 'optimize_limits' [/sourcecode] I decide I am just going to go in to the zxoracle.py and add optimize_limits = False to the ZXOracleDialect. No idea what this breaks or harms, but I do it anyway and rerun the application. Success! Every thing is working now. No liking the idea of having to manually insert the Oracle jar in to the WEB-INF/lib and not really wanting to much around with environment variables, I also implemented a quick and dirty include-java-libs for snakefight, the diff for command.py is below. This allows me to pass in a : separated list of jars to include in the WEB-INF/lib. EDIT: The diff I posted isn't needed since I put it on my hg repo. You can grab it from here. So now I am back to building my war. Just as before. [sourcecode lang="bash"] $ /opt/jython25/bin/jython setup.py bdist_war --paste-config dev_r2.ini --include-java-libs /opt/jython25/extlibs/ojdbc.jar running bdist_war creating build/bdist.java1.6.0_12 creating build/bdist.java1.6.0_12/war creating build/bdist.java1.6.0_12/war/WEB-INF creating build/bdist.java1.6.0_12/war/WEB-INF/lib-python running easy_install project adding eggs (to WEB-INF/lib-python) adding jars (to WEB-INF/lib) adding WEB-INF/lib/jython.jar adding Paste ini file (to dev_r2.ini) adding Paste app loader (to WEB-INF/lib-python/____loadapp.py) generating deployment descriptor adding deployment descriptor (WEB-INF/web.xml) created dist/project-0.6.8dev-py2.5.war $ cp dist/project-0.6.8dev-py2.5.war /opt/jetty/webapps $ sudo /sbin/service jetty restart [/sourcecode] And presto! I am in business. My pylons application is deployed under Jetty and all the selenium functional tests are passing. I am sure there is probably a easier, neater, or cleaner way to do all this, but this was my first iteration through and also my first time ever deploying a WAR to a java servlet container so all in all I am happy with the results. Performance seems about the same as when running the application with paster serve, but Jetty does use a little more memory than before (expected I guess).
I get made fun of on a daily basis for this but I am addicted to GUI Green-Bar testing. When I say that I literally mean a simple little Green/Red progress bar that shows me my pass/fail tests. I am addicted to it. I need it. Eclipse C++ and CUTE had spoiled me and now I desire the same thing for Python. Don't get me wrong, I don't practice "metrics driven development", but for me personally, it is a motivator, an easy and clearly defined goal in my test driven approach, make that bar go full green. I've spent the last few hours on Google and misc blogs looking for GUI Green bar testing for modern Python and have been unsuccessful in finding anything. So I ask anyone who happens to read this blog if you know of any plugins for any IDEs or text editors that support this for Python. In the mean time I started my first Eclipse plugin project ever in hopes I can hack my through enough Java and pull enough from PyDev extension that I can make a simple green bar for Eclipse that parses nosetests output or something.
This is a short review of the first chapter ofThe Art of Unit Testing. Which is available for free. The chapter is short and concise. It is a good warm up for what the reader is to expect in the coming chapters. The initial fail project that is talked about is covered in very brief. It touches on some reasons why it failed, things like unmaintainable unit tests, but it almost seems as if the project itself confused functional tests with unit tests, which I guess would be a reason to author a book about good unit tests and what a unit test is and is not. It has a great definition of what a good unit test is. DEFINITION: A GOOD UNIT TEST A unit test is an automated piece of code that invokes a different method and then checks some assumptions about the logical behavior of that method or class under test. A unit test is written using a unit testing framework. It can be written easily and runs quickly. It can be executed, repeatedly, by anyone on the development team. I found this to be a very good definition and plan to adopt it when I am asked this question. In fact, I'm going to add it to my wiki.UnitTest The author also touches on TDD in the very first chapter, which I was surprised, and delighted to see. His coverage is very basic, much like you'll find in myIntroduction to TDDseries on this blog. The author dedicates the unreleased chapter 12 to this subject. Looking forward to it. Overall, the first chapter has inspired me to purchase the early release digital edition of the book. So expect a full review shortly.
Was having a conversation at the office today about TDD. Talking about TDD with some of my co-workers who still develop in a more traditional manner motivated me to write an introduction to TDD for them. I know, I know, there are plenty on the web, but this little write up serves two purposes. One, help my co-workers who aren't familiar with some of the TDD ways learn how and why we (the TDD collective) develop the way we do. Two, the more you talk about write about a topic, the better you get at that topic. TDD goes something like this.
- Write a failing test.
- Make the test pass as fast as possible.
- Refactor existing or add new tests.
- Make those new/refactored tests pass.