Errors in my post on Comparing EMF Models

2008-11-19

There was an error in the code originally posted in my article on Comparing EMF models. Thank you so much to Jim Showalter for warning me. The post has been updated with the right code. Now it’s also included an Eclipse sample project that compares two UML models.

No Comments

Generating JUnit Test Cases Dynamically

2008-09-18

In this post I’m going to talk about generating JUnit Test Cases Dynamically. In order to define tests, most JUnit’s users place their testing code inside test methods that

  • Start with test
  • Don’t have arguments

Given a TestCase object, JUnit TestSuites can dynamically extract test methods that follow these conventions and run them on the fly. However, this behavior isn’t enough in some cases. The problem of this approach is that, from the developer’s point of view, tests must be written statically.

Imagine you have a directory with many text files. For each file, you want to do the same kind of testing. Since the test result depends on each file, what you really want is to generate dynamically test cases. Of course you can have a single test method, and do all the testing there. The main problem of this approach is that Test Runners won’t be able to collect results properly: a single fail with one file would result as a failure. You won’t notice which tests are valid and which aren’t.

Generating tests cases dynamically is very simple. JUnit’s design itself is simple. This is one of the main reasons of why this framework is so successful. JUnit was created by Kent Beck and Erich Gamma. It represents an excellent oportunity to see GOF design patterns in action (in the same way that JHotDraw, another framework created by Erich Gamma as a design patterns exercise). In JUnit, a Test Case is, surprisingly, a Test Case. A Test Suite is a composite of Test Case. You can create a Test Suite as a normal object and, programmatically, populate it with as many instances of a test case as you want.

Let’s see a very simple example. Imagine you have the following structure of folders:

Folder Structure for the sample

For each folder, you want to create a Test Suite. For each file, you want to test that its extension must be .txt. In this way, you are going to create a parallel structure using test suites and test cases.

Below, the test suite is shown. It receives a directory in the constructor. It goes through all the contained files and subdirectories. For each subdirectory, a new TestSuite is created and added to the composite (recursively). For each file, a new TestCase is created and added in the same way. The actual testing is going to be done in these test case instances.

public class TextFileTestSuite extends TestSuite {
  public TextFileTestSuite(File directory) {
    super(directory.getName());
    for (File file : directory.listFiles()) {
      if (file.isDirectory())
        addTest(new TextFileTestSuite(file));
      else
        addTest(new TextFileTestCase(file));
    }
  }
}

The test case’s implementation is very straighforward. It receives the concrete file to test in the constructor. It also overrides the runTest() method, where the real testing code is placed.

 public class TextFileTestCase extends TestCase {
  private File file;
 
  public TextFileTestCase(File file) {
    super();
    this.file = file;
    setName(file.getName());
  }
 
  protected void runTest() throws Throwable {
    assertTrue(file.getName().endsWith(".txt"));
  }
 }

And that’s all. You can now check the results on a Test Runner:

 public class AllTests {
  private static final String TEST_FOLDER = "testdata";
 
  public static Test suite() {
    TestSuite suite = new TestSuite(
        "Test for net.jorgemanrubia.junitdinamically.sample");
    //$JUnit-BEGIN$
    suite.addTest(new TextFileTestSuite(new File(TEST_FOLDER)));
    //$JUnit-END$
    return suite;
  }
 }

With the exposed structure of folders, you will obtain something like this:

Test Results using Eclipse's JUnit Test Runner

3 Comments

Comparing EMF Models

2008-07-6

At work, we needed a mechanism to compare EMF models. We are developing a system that uses ATL model to model transformations. We wanted to validate the transformations with JUnit unit tests. We needed a mechanism that let us compare expected models with transformed output models.

EMF Compare

I started evaluating the EMF Compare Framework. This framework targets model comparison by building a EMF model of the differences found during the comparison process. It let you evaluate differences pretty exhaustively. It evaluates source and target models by trying to match parallel elements. For related elements, matching is applied recursively.

The differences model is build of matched and unmatched elements. Matched elements let you examine the similarity of the matching (a number between 0 and 1). It seems as if two elements match just by having the same metaclass. Then, the similarity is set depending of how similar are their attributes. If the two models are identical, the root elements matching similarity is 1. If you change the value of two attributes, for example, then this precision was over 0.9. If you just change the order of two nodes, the precision was again under 1, even when the references in the metamodel weres unordered. This behavior wasn’t very good for our purposes, since models under comparison could have different orders in their references.

If you think in the semantic of the comparison, two models can be identical when their unordered references don’t have the same order, don’t they? I suspect that EMF Compare probably would let you configure different comparison strategies easily, but we found a simpler way to achieve what we wanted.

Modifying the EcoreUtil.EqualityHelper class to ignore order in references

A friend told me have a look at the equals() method provided by the org.eclipse.emf.ecore.util.EcoreUtil class. It receives two EObject elements and compare them recursively. The two models have to had exactly the same structure in order be equal (no matter wether references were ordered or unordered). Again stabbed with the same problem. A look at the source of the method revealed that it delegates completely the functionality in a helper inner class: EqualityHelper. This class code is well factorized and it can be understood easily. The comparison of two list of elements was properly contained in an equals(List, List) method. So we try to hack this method in order to ignore orders when comparing.

After spending some hours trying to make a very complex modification of the method, another friend proposed the simplest way to compare two lists: sort them both and then compare sorted lists expecting exactly the same order. The solution was as obvious as wonderfully easy to implement: we already had the exhaustive comparison so we only needed to center our efforts in sorting the lists.

The last thing we needed was to find an EObject comparison criteria in order to implement the proper java.util.Comparator. This wasn’t that easy and we finally ended up parsing the toString() method result so we can obtain the attributes list string (the attribute’s name is hard coded in the EMF generated code of each concrete toString() method).

Below the source code of the modified EqualityHelper is shown.

public class EMFComparator extends EcoreUtil.EqualityHelper {
 
  class EObjectComparator implements Comparator<EObject> {
    public int compare(EObject object1, EObject object2) {
      String targetString1 = extractComparisonString(object1);
      String targetString2 = extractComparisonString(object2);

      return targetString1.compareTo(targetString2);
    }

    private String extractComparisonString(EObject object) {
      return object.toString().replaceAll(
          object.getClass().getName(), "").replaceAll(
          Integer.toHexString(object.hashCode()), "");
    }
  }

  @Override
  public boolean equals(List list1, List list2) {
    Comparator comparator = new EObjectComparator();

    List<EObject> sortedList1 = new ArrayList<EObject>(list1);
    List<EObject> sortedList2 = new ArrayList<EObject>(list2);

    Collections.sort(sortedList1, comparator);
    Collections.sort(sortedList2, comparator);
   
    return super.equals(sortedList1, sortedList2);
  }

Conclusion

I was a bit surprised of not finding this problem solved when googling for it. I’m sure more people have had this need and have solved this problem before. When you are transforming models, you need a formal way to compare real output models and expected output models. I wouldn’t develop a complex transformation system with a lot of transformation rules without this system. Lateral effects when modifying transformation rules can break the system and being easily unnoticed. If transformations are an essential mechanism in a data loading system, like our case is, this danger is not acceptable.

Update (2008-11-19)

There was an error in the code originally posted. The method extractComparisonString() received an String object, when it should receive an EObject (it didn’t make sense). Thank you so much to Jim Showalter for warning me. I should have copy/pasted from what I coded at work, instead of rewriting at home.

You can also download an Eclipse sample project that compares two UML models. It includes the source of the comparator.

11 Comments

Posting from Textmate

2008-05-31

I’m writing this entry using Textmate. I been a lot of time waiting to use this fantastic editor. Finally, I’ve bought a 17 inches MacBook Pro. I’m really loving it!. So much time reading things about MacOS (and Textmate) and now, well, all my expectations are fulfilled.

Posting a blog entry with Textmate

Until now, I was using ubuntu in my laptop. JEdit was my every-day editor. I really consider it a great editor, totally customizable, extremely solid and with a huge amount of plugins available. I’ll keep using it in other computers (for example, in my work).

So why change? Well, like many people, I was amazed by the look of the Editor used by David Heinemeier in the first Rails screencast. Since then, all the reviews about Textmate I’ve read agree: it’s a superb product. I’ve only been using it for 3 days and I’m totally convinced it’s going to be my editor from now on. A very nice surprise is the excellent LaTeX bundle.

No Comments

Skittlish theme for Typo

2008-05-23

I have adapted a theme I really love to use it with the blogging engine that runs this site: Typo. It’s the Skittlish theme, originally created by Damien Tanner and Cristi Balan for Mephisto’s.

I still have to polish several details before submitting it to the Typo’s theme repository.

For now, you can download the Skittlish theme for Typo directly from this site.

1 Comment

Hello World!

2008-04-29

This is the first post in my very new personal page.

I created this site because I wanted to have a place to write about software development. I have interests in many areas, specially those related to MDD (Model Driven Development), software development methods and agile practices.

This site starts as a fresh Typo installation hosted on Site 5. I love Rails and Ruby and I intend to use this site as a place to experiment. We’ll see if the experiment lasts…

No Comments