|
|
The story
I just completes what could be called a small one man project, a java based reporter web application. During the development I had to report my progresses to a project manager, that kept the communication with our final customer. The PM gave me an high degree of freedom about the software architecture, usually trusting the choices I made after I explained them.
I made use of JUnit test in the project, both for unit and integration tests. I also had a test database and I used DbUnit to set the test data on the db before running the tests. The build process embedded the execution of tests to avoid build anything if a test was not passing. Thus I had a quite common set up.
I told my PM about the use of automated tests from the early stages and we kept on discussing about them even though I often explained him how I was using the automated test during the development and in the building process.
My opinion
During the development I had the feeling the PM of this story was both interested and scared about automated testing.
In one hand he was undoubtedly interested because:
- he kept on asking me every now and then information about the test automation;
- he’s very curious kind of person and he was always listening to what the developer community is buzzing about.
In the other hand he was scared because:
- as a PM he needs to manage strictly set budgets and he was not really aware (and probably he is still not) of the costs and advantages of automated unit testing;
- he wrote a line of code for the last time quite a long time ago, and almost its whole experience was with procedural languages, so he was not totally accustomed with polymorphism in object oriented languages, a feature that definitely helps in writing unit test;
- he was almost obsessed by how apply unit testing to database and data driven application, since these are the application he is accustomed to;
What can be deduced ?
Things a PM should already know about unit testing
- IT people seems to know that unit testing exists and they know developers generally say they help build better applications.
Things a PM would like to know about unit testing
Here’s the list of main questions I collected from the PM. I think they are quite representative of the doubts a PM has about unit testing, and so they represent a good starting point to organize an educational and introductory session to them.
Q: how much does it cost do develop a project using unit test ?
How to answer: I think the first concept that needs to be made clear is how much does it cost to use unit testing in a project. Does unit testing make the process cheaper or more expensive ? Faster or slower ? As usually, it’s all related to money from a PM’s point of view. A good resource could be an analysis that compares different projects that made different use of unit testing.
Q: how much is the foreseen gain in quality ?
How to answer: I think it would be good to show some statistics that compare data collected from projects that made use of unit testing with ones that did not. Again, the same resources that made possible an answer to the previous question could be successfully used to answer to tis question too.
Q: can unit test be applied to the application of data driven development ?
How to answer: In some consultancy sectors, data driven application are the most important. So if you think to introduce testing, you have to do it also for the data layer, if you want your PM to be interested in unit testing. If you are working in Java I think DbUnit could be a good starting point.
Q: how it is really possible to isolate a piece of code, a class, and run it in a dedicated test environment, to test it ? What really are the benefit of it ?
How to answer: I think here we need the smallest possible project that can quickly show:
- Developing a class with test.
- How to set a test of a class that has dependencies on other classes.
- How tests of a couple of integrated classed.
- How unit test classes with dependecies on other external app.
- Show a real case in which a test suite pop up a regression bug.
I hope this would be a good guide about how to introduce your PM to unit testing.
I never wrote a single line in Perl, but today I had the necessity to install a Perl script along with some dependencies.
In Ubuntu I accomplished that running:
sudo cpanp
to start the module manager.
To actually install the module type the following command. Obviouslu the following example shows how to install the Email::LocalDelivery module. Just change it with the name of the module you want to install.
i Email::LocalDelivery --verbose
cpanp identifies all required dependencies through the web and asks the user if it should try to intall them.
Module 'Email::LocalDelivery' requires 'Email::FolderType' to be installed
...
1> Yes
2> No
3> Yes to all (for this module)
4> No to all (for this module)
Just choose “3″ and let cpanp manage all dependencies for you.
Eventually, if all works well, cpanp should show you the following confirmation message:
Module 'Email::LocalDelivery' installed successfully
No errors installing all modules
A workmate of mine is currently deep involved in a big deploy. He has to take a huge amount of sql scripts out of our SCM, check them manually to discover if the other programmers have followed the internal coding standard and fix them if this is not the case.
While it is still a mistery to me why nobody though to it, I started the development of a small tool that could possibly automatically check and fix all the errors.
Part of this tool is a diff style window that show the user what the tool is fixing. It seems that diff in Java is a quite required feature, so, here’s my solution.
Obviously I didn’t reinvented the weel and my implementation is 100% based on the one published on wikibooks. My implementation consist of a couple of class.
The first one is able to give access to strings line by line.
-
public class LineFile {
-
-
private List lines;
-
-
public LineFile(InputStream in) {
-
try {
-
lines = IOUtils.readLines(in);
-
} catch (Exception e) {
-
throw new RuntimeException(e);
-
}
-
}
-
-
public LineFile(File f) {
-
try{
-
lines = IOUtils.readLines(new FileInputStream(f));
-
}catch(Exception e){
-
throw new RuntimeException(e);
-
}
-
}
-
-
public LineFile(String from) {
-
try {
-
lines = IOUtils.readLines(new ByteArrayInputStream(from.getBytes()));
-
} catch (IOException e) {
-
throw new RuntimeException(e);
-
}
-
}
-
-
public String lineAt(int index){
-
if(index>=0 && index<lines.size()){
-
return lines.get(index);
-
}
-
return null;
-
}
-
-
public int lines() {
-
return lines!=null ? lines.size() : 0;
-
}
-
}
The second one is the actual implementation of the diff algorithm, and is based on considering each line as the most little element the algorithm can consider.
-
public class LineFile {
-
-
private List<String> lines;
-
-
public LineFile(InputStream in) {
-
try {
-
lines = IOUtils.readLines(in);
-
} catch (Exception e) {
-
throw new RuntimeException(e);
-
}
-
}
-
-
public LineFile(File f) {
-
try{
-
lines = IOUtils.readLines(new FileInputStream(f));
-
}catch(Exception e){
-
throw new RuntimeException(e);
-
}
-
}
-
-
public LineFile(String from) {
-
try {
-
lines = IOUtils.readLines(new ByteArrayInputStream(from.getBytes()));
-
} catch (IOException e) {
-
throw new RuntimeException(e);
-
}
-
}
-
-
public String lineAt(int index){
-
if(index>=0 && index<lines.size()){
-
return lines.get(index);
-
}
-
return null;
-
}
-
-
public int lines() {
-
return lines!=null ? lines.size() : 0;
-
}
-
}
Finally, to give you an idea of how it performs, here’s a couple of screenshots from the application.


If you need more details regarding the code, don’t hesitate and drop me a message!
I got some spare time, so I decided to give TPTP a try. After all I was thinking about it for some months.
I got the chance to apply TPTP to an applet I’m working to. The applet’s main task is to upload a set of file to a remote server giving the user some useful feedbacks, mainly including a nice interface that represent the upload process and a log window. Here you can see some screenshots to have an idea.


So, the first rule of optimization is usually to discover which is the section of code that behaves badly, that provides the worst performances. I run TPTP and I obtained the following report.
 Performances of FileApplet before any optimization took place.
Quite surprisingly the worst performance is from the writeLog() method. This is a private method invoked inside a org.apache.commons.logging.Log implementation that implements an Observable/Observer pattern. This pattern is used to allow the user interface to receive notifications when the log is written. Apart of any technical consideration, the bad things here is that the performances of the code that manages the log system has the main responsibility of making the application run slower! This is absolutely a nonsense, since logging is not the application core business and the user does not want to trade performances for log capabilities, definitely!
So, I tried to discover how to improve the performances of this method, and I stumbled on ByteArrayOutputStream . This is a class from Apache Commons IO that provides the same interface of the classic java.io implementation. The project already included the apache commons IO jar, so it was really easy to change the dependency. I also made some minor fixes in the class.
So, I applied the second rule of optimization. Remove the bottleneck and measure the improvements, to understand if the update was worthwhile. I run again the TPTP an I obtained the following situation.

The performances of the bottleneck have increased considerably. Afterward the writeLog() method lasted for ≈14% of the total run time, against a smaller ≈10%. Then I though about the reason why the method writeLog() was invoked even when the user did not visualize the log panel. What stroke me was that I never though about it, and I used the Observable/Observer pattern only to set the link between the interface and the log system. So I refactored the code to make the log interface start observing the log only when the user press the log button, and, obviously, it stops observing the log when the user leaves the log view. This makes the code a little more trickier, but removed completely the main source of poor performances. Any doubt ? Here’s the TPTP report obtained after the refactoring.
 File Applet performances after bottleneck has completely removed.
So, we can quite unsurprisingly conclude that the better improvement in performances comes from not using at all the bottleneck methods (at least when it is not strictly needed).
I spent a whole day trying to figure out how to use http components to send a file from a java program mimicking a POST multipart/form-data form.
The problem was that while a common HTML form worked with no problems at all, the POST generated with http commons was always rejected by the server.
So, I decided to dump the HTTP requests sent by the browser and by http components, and here’s what I got.
Request generated from the browser
------WebKitFormBoundaryYuxYFZoJg4fx2Tfu
Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
[file content]
------WebKitFormBoundaryYuxYFZoJg4fx2Tfu--
Request generated from http commons
--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P
Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
[file content]
--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P--
As you can see there’s a “Content-Transfer-Encoding: binary” header that is the one that caused the problem in the server. After a while I discover than when you create a new MultipartEntity, you can optionally specify a mode of operation. Currently supported modes are HttpMultipartMode.STRICT and HttpMultipartMode.BROWSER_COMPATIBLE. It’s not worth to mention that the default mode in STRICT, that maybe does not work with old or not fully standard web servers. If BROWSER_COMPATIBLE is specified instead, the data sent by http commons does not contain any Content-Transfer-Encoding header, and the delivery of the file terminates successfully.
Here’s the piece of code:
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
I was trying to install Ruby Enterprise on my Ubuntu machine. I discover you need to be sure to have some package installed if you really want to build all gems needed by Ruby On Rails.
So be sure to install at least the headers for mysql and sqlite before installing Ruby Enterprise.
$ sudo apt-get install libmysqlclient-dev
$ sudo apt-get install libsqlite3-dev
Afterward you can compile the related gems with the following commands.
$ sudo /opt/ruby-enterprise-1.8.7-2010.02/bin/gem install mysql
$ sudo /opt/ruby-enterprise-1.8.7-2010.02/bin/gem install sqlite3-ruby
Worth reading
http://amitava1.blogspot.com/2010/08/ruby-on-rails-on-centos-55-with.html
http://ubuntuforums.org/showthread.php?t=637973
http://theplana.wordpress.com/2007/05/11/install-sqlite3-on-ubuntu/
This is a quick SVN reference I update regularly, with the commands I use more. I hope you’ll find it useful.
Task: Browse a remote repository
-
svn ls svn+ssh://[alias]/[path]
Task: create a directory on a remote repository
-
svn mkdir -m "[message]" svn+ssh://[alias]/[path_to_new_dir]
Task: import a directory
-
svn import -m "[message]" [path_to_be_imported] [repository_url]
Task: check out
-
svn checkout [repository url]
Hi,
if you like to use assertions in your source code, but you miss this feature in ObjectiveC, give a look to this small class.
Assert.h
-
#import <Foundation/Foundation.h>
-
@interface Assert : NSObject {
-
}
-
+(void)that:(BOOL)expr;
-
@end
Assert.m
-
#import "Assert.h"
-
@implementation Assert
-
+(void)that:(BOOL)expr{
-
if (!expr) {
-
[NSException raise:@"Failed assertion." format:@"Failed assertion", nil];
-
}
-
}
-
@end
As you can see, there’s only one static method that you can use wherever you want.
In this snippet here’s an example how to use it.
-
#import "Assert.h"
-
-(void)doSomething{
-
[Assert that:(<your_assertion>)];
-
}
|
|