get feature and scenario name with cucumber-jvm

cucumber-jvm does not provide an easy way to get the feature name, scenario name or the step that is being executed. I had to find a workaround for this. For reference it is listed here. I am using the mirage project that I created a while back that provides a few utility classes around reflection. The ReflectionUtils.getFieldInObject uses that.

I created an aspect and weaved the info.cukes:cucumber-junit jar file with the aspect.

 public aspect ReportFeatureScenarioStep {  
pointcut running_feature() : execution(public * cucumber.junit.FeatureRunner.run(..));
pointcut running_scenario() : execution(public * cucumber.junit.ExecutionUnitRunner.run(..));
pointcut running_step() : execution(public * cucumber.junit.JUnitReporter.match(..));
// Not used. These are here for reference only
// pointcut completing_feature() : execution(public * cucumber.junit.FeatureRunner.run(..));
// pointcut completing_scenario() : execution(public * cucumber.junit.ExecutionUnitRunner.run(..));
// pointcut completing_step() : execution(public * cucumber.junit.JUnitReporter.result(..));
before() : running_feature() {
ParentRunner pr = (ParentRunner) thisJoinPoint.getTarget();
System.out.println(pr.getDescription().toString());
}
before() : running_scenario() {
ParentRunner pr = (ParentRunner) thisJoinPoint.getTarget();
System.out.println(pr.getDescription().toString());
}
before() : running_step() {
StepDefinitionMatch m = (StepDefinitionMatch) thisJoinPoint.getArgs()[0];
Step step = (Step) ReflectionUtils.getFieldInObject(m, "step");
System.out.println(step.getKeyword() + " " + m.getStepName());
}
// Not used. These are here for reference only
// after() : completing_feature() {
// ParentRunner pr = (ParentRunner) thisJoinPoint.getTarget();
// System.out.println("AFTER FEATURE : -->" + pr.getDescription() + "<--");
// }
//
// after() : completing_scenario() {
// ParentRunner pr = (ParentRunner) thisJoinPoint.getTarget();
// System.out.println("AFTER SCENARIO : -->" + pr.getDescription() + "<--");
// }
//
// after() : completing_step() {
// System.out.println("AFTER STEP ");
// }
}

This aspect is weaved into the cucumber-junit by doing this:

                 
org.codehaus.mojo
aspectj-maven-plugin
1.4



compile
test-compile




1.6
1.6
false
false
1.6


info.cukes
cucumber-junit


info.cukes
cucumber-java




what is your favorite design pattern ?

In the last few technical interviews I have introduced this new question on design patterns — “What is your favorite design pattern?”

The responses I got from candidates was – MVC, Singleton, DAO, Facade, Factory etc.

But what I don’t get here is how can you have a favorite design pattern?

There are so many design patterns. The underlying idea is to use the right one for the right purpose and to solve the right problem. It does not matter if you like one or the other. Your level of understanding of one pattern may be high and other may be low – and that is perfectly fine. However how can I have a favorite design patten?

what happens to the code without thought

I ran into this wonderful piece of java code at work. Just had to share this with everyone.
This code base was modified over last 4 years by at least 50 different developers with no TDD. Look at what the code ends up being in a long run.

// given that record and id are Strings
if (record != null && ((id != null && id.length() == 20) || (id == null || id.length() != 20))) {
  // do something
}

This if condition is essentially the same as

// given that record and id are Strings
if (record != null && true) {
  // do something
}

laws of software defects

Just for fun but feels so true on some days


Remember these laws of thermodynamics !
Energy can not be created nor destroyed
Energy can be changed from one form to another
In an isolated system the total energy remains the same


Now replace the word “energy” by “Defects” and you get the laws of software defects !
Defects can not be created nor destroyed
Defects can be changed from one form to another
In an isolated system the total defects remains the same


heh !

Organizing unit tests

I have been using a different approach to organizing the unit tests and this have turned out to be very effective. Worth sharing.

So if we have a class that looks like:
public class AccountService {
  public void getAllAccounts() { … }
  public void createAccount() { … }
  public void removeAccount() { … }
}

For such a class we would traditionally have a unit test class called AccountServiceTest and all the test cases for all methods mentioned above. We would also have a bunch of global variables in the Test class and a setup (@Before) method.

My different approach involves creating a unit test class for each method rather than just one test class. So now we would have three classes:
public class AccountService_getAllAccounts_Test {}
public class AccountService_createAccount_Test {}
public class AccountService_removeAccount_Test {}

Generalizing it the unit test class name should be:
<>_<>_Test.java

Each class would have test cases for only the method referenced in the file name.

So how is this approach effective?

SRP – Single Responsibility Principle – is restored
In the traditional way the SRP principle is violated with the setup method as it is now common to all the test cases for all methods for the class under test. The setup has responsibilities to setup the objects and data for all the test methods for all methods in a class. Even the Test class has multiple responsibilities to test all methods in there. With the new approach every test class has responsibility to test only one single method under test.

“Look and Feel” of unit test cases
This is more of a perception thing but it works. Say if every method under test can have 5 unit test cases, in the above example having a single test case class means we already have 15 methods in there. When a developer looks at a single class with that had large number of methods with a single setup method that looked cryptic and they were less likely to update any unit test cases or even add more tests to them. When the classes were separated the “look and feel” of the test cases improved developers are now willing to and able to extend existing code base by adding new test cases.

What are the side effects of this approach?

  • Popular plugins like moreunit do not work anymore
  • Proliferation of Test classes may be something some developers may not like at first.

Let me know what you think !!!

TDD and Technical Debt

So whats the relation between Test Driven Development and Technical Debt?

  1. Technical Debt is a term inspired from Financial Debt that people fall into
  2. People fall into Financial Debt when the spending to earning ratio gets out of order, spending more than money earned.
  3. In most cases spending more than limit is because the concept of monthly finance budgets is lacking or not enforced.
  4. The monthly budget that is setup at the start of the month or year is like writing unit test case. Then living the month by the budget is like writing exactly the code needed for the test to pass.
Hey — so just like in real lives lack of Test Driven Development or not enforcing it does cause more Technical Debt.

moving to github

I am moving all my code from presentations / pet projects to github — http://github.com/daveayan
So far I have migrated 3 projects but more are coming. So far this is what I have:

– Google App Engine Presentation I did in April 2010
– Maven in Polyglot space presentation from Columbus Polyglot user group (03/2011) and QSI Tech Lunch (05/2011)
– My pet project rjson that is a core piece for my legacy code testing project (coming soon on github)