Archive for the ‘Code’ Category

Setup Jenkins on TomCat/Windows with Mercurial Repository in BitBucket over SSH

This is just the list of steps that I’ve made to get a Windows build machine execute a Jenkins Job (running inside TomCat) clone a Mercurial repository hosted on BitBucket with SSH authentication.

  • Install TomCat (I’ve used the 7)
  • Install Jenkins on TomCat
  • Create a Windows User for executing the TomCat (Lets reference it as CI_USER, but you can name it as you like)
  • Set the TomCat process to execute with the CI_USER
  • Log in on the machine with the CI_USER
    • Download putty zip so that you can create a SSH key.
      • Generate a key using “PUTTYGEN.EXE”
      • Copy the Public-key and add it as a Deployment keys on your Repository settings on BitBucket.
      • Save the private key without a passphrase.
    • Install TortoiseHG on the Jenkins Machine.
    • Create a user Mercurial settings file on C:\Documents and Settings\CI_USER\Mercurial.ini (Look here for references)
    • Add this code to the file

      [ui]
      ssh=”C:\PATH_TO_TORTOISE_HG_INSTALL_ROOT\TortoisePlink.exe” -batch -i “C:\PATH_TO_PRIVATE_KEY_FILE_CREATED_WITH_PUTTYGEN.ppk”

    • I’m not really sure if this step is really mandatory, but do it just in case:
      • Manually clone your repo using TortoiseHG. Make sure you use the ssh url from bitbucket as source and some temporary folder as destination.
      • Accept Bitbucket certificate and add it to the cache (Click yes if any window appears regarding that)
    • Install the Mercurial plugin on Jenkins.
    • Go to jenkins and configure your job to point to the ssh url
    • Happy CI

Debug a Google Chrome Developer Tools Panel Extension

A Google Chrome Developer Tools Panel Extension is (as stated in the documentation):

a way to integrate your extension into Developer Tools window UI: create your own panels, access existing panels, and add sidebars…

Its an awesome way to increment a Chrome user experience while he is viewing another page in the main content area. For those who does not know, Chrome extensions are plain html + js + css files. They are really easy to implement.

The problem: How to debug a Google Chrome Developer Tools Panel Extension?

One of the main difficulties I’ve found when starting to developing them, was debugging. I could not find an easy way to see the errors they were giving, and I could not understand how to use Developer Tools itself to inspect the elements, check the javascript code, etc.

When you create a extension, you have a manifest.json file that contains information about it. Here is an example:

{
  "name": "Sample",
  "version": "0.1.0",
  "description": "Sample DevTools Extension",
  "devtools_page": "devtools.html",
  "manifest_version": 2
}

The devtools.html usually looks like this:

<html>
<body>
<script src="devtools.js"></script>
</body>
</html>

The devtools.js is where the magic happens. Here you usually call the chrome api methods to register your objects, panels, etcs:

// This will register the panel. 
// NOTE: The second argument is required, so you need a image file to be the icon of your panel otherwise it just won't work (it did not for me at least)
chrome.devtools.panels.create("Sample Panel",
                              "Icon.png",
                              "panel.html",
                              function(panel) { 
                              });

The panel.html is the page that will appear on the Developer tools panel. Here is an example:

<html>
<body>
    <h1>Hello from a panel!</h1>
</body>
</html>

Here is the final result:

The solution: Add the panel html page as an options page

Just add the panel html page as the options page of your extension, changing the manifest.json file like this:

{
  "name": "Sample",
  "version": "0.1.0",
  "description": "Sample DevTools Extension",
  "devtools_page": "devtools.html",
  "options_page": "panel.html",
  "manifest_version": 2
}

With that, you will be able to open your Panel page like an options page. Clicking on the options link of your extension on the “Extensions” tab:

By clicking the link, chrome will open the page as a normal html page, giving you access of the Developer Tools itself to debug your extension:

Happy debugging (and coding)! 😀

Easier automated builds and continuous integration with Naven: A .NET port of Maven

I love Apache Maven. I really do. It increased my productivity and quality on java projects so much! I stopped worring about the small and repetitive details about my build process.

But here in 4N1, we have a lot of projects in .NET, and we could not find a good, easy and free tool like Maven for the .NET world, so we decided to start our own.

Naven comes to the rescue!!!

Naven is a port of the Maven concept, meaning that you don’t need to specify a build process, you just need to inform how your application is, and Naven will “create” the build process for you. Implemented as a command line application (but with the real logic in a C# 4.0 API), Naven can be used as a build automation tool and executed inside a continuous integration server, in fact, here in our CI server(Jenkins) we use it already.

We also did Naven to help spread build automation and CI concepts, making it easier for someone to automate their build process.

Apache Maven has a POM (Project Object Model) to define the caracteristics of your projects. Since the .NET world already have a POM (the *.csproj and such files), Naven only needs a AOM (Application Object Model). The AOM is a file that contains the basic information about your application.

Components

Basically, a Naven application has components. The currently supported are:

  • Solution: References an existing .Net solution.
  • Project: References an existing .Net project.

Phases

In the Naven world, a build process is divided in phases. Phases are nothing more that steps of a build process. The currently supported are:

  • Initialize: Deserializes the AOM file and initialize all necessary objects.
  • Validate: Validates the AOM file looking for errors (EX: pointing to an invalid solution, a non existent project file, etc)
  • Resolve Dependencies: Since version 0.2.0, Naven integrates with Nuget, meaning that if you have projects that specify their dependencies in a Nuget file (package.config) it will install the packages for you.
  • Compile: Using MSBuild, executes the compilation of the components of your application.
  • Tests: Using NUnit, Executes the automated tests of your application.

Besides the “out-of-the-box” phases, you can extend the Naven build process using NAnt, on the “custom phases”. They happen before and after their respective phases:

  • AfterInit
  • BeforeValidate
  • AfterValidate
  • BeforeResolve
  • AfterResolve
  • BeforeCompile
  • AfterCompile
  • BeforeTest
  • AfterTest

Goals

A Goal is something that you want Naven to do with that component. The currently supported are:

  • Resolve: Tells Naven to resolve the dependencies of the component. In the current version you don’t need to specify this Goal because it will process all “packages.config” files found.
  • Compile: Tells Naven that the component should be compiled.
  • Test: Tells Naven that the component have tests that should be executed.

NOTE: In the current version you need to manually specify the Goals, but we are planning to apply the concept of Convention over Configuration, and try to figure it out what are the expected Goals for a particular component, for example, adding the Test goal automatically for all projects with the name ending with “.Tests”.

Here is an example of a concrete Naven AOM file:

<?xml version="1.0" encoding="utf-8"?>
<DotNetApplication xmlns="http://naven.4n1.pt/aom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://naven.4n1.pt/aom http://naven.4n1.pt/0.3/aom.xsd">

  <!-- Application name -->
  <Name>Sample App Name</Name>

  <!-- Application description -->
  <Description>This is just a sample application.</Description>

  <!-- Path where Nuget packages will be installed -->
  <NugetPackagesFolder>packages</NugetPackagesFolder>

  <Components>

    <!-- Represents an existing solution -->
    <Solution Path="Solution.sln">
      <Goals>

        <!-- Tells naven to compile this solution. Normally this would be the solution that contains all the projects of your application. Here in <a href="http://www.4N1.pt">4N1</a>, we normally have a "main" solution, will all the projects. Its easier and faster to compile a lot of related projects. -->
        <Compile/>
      </Goals>
    </Solution>

    <!-- Represents an existing project -->
    <Project Path="SampleProject.Tests\SampleProject.Tests.csproj">
      <Goals>

        <!-- Tells naven to run the tests on this project. Naven will look on the .csproj file to find out
	where the compiled assembly is.-->
        <Test/>
      </Goals>
    </Project>

  </Components>
  <Phases>
    <AfterInit>
      <!-- Inside a "custom phase", you can use all NAnt tasks (as long as you include their assembly in the same folder Naven executable) -->
      <echo message="This is happening after Init"/>
      <echo message="This is also happening after Init"/>
      <property name="Environment" value="SomeValue"/>
      <echo message="This is the environment: ${Environment}"/>
    </AfterInit>
  </Phases>
</DotNetApplication>

How to use it?

Just grab the latest release(v 0.3.0) on the Naven repo, unzip it, create your Naven AOM file and execute the command line, like this:

  • nvn.exe PATH_TO_THE_AOM_FILE Resolve
  • – To resolve the dependencies of your application.
    or

  • nvn.exe PATH_TO_THE_AOM_FILE Compile
  • – To compile your application.
    or

  • nvn.exe PATH_TO_THE_AOM_FILE Test
  • – To compile and test your application.

Properties Support

When extending Naven native build process with NAnt, you may need to supply additional properties values when invoking Naven by command line. Just like NAnt /D:PropertyName=PropertyValue switch, you have a similar mechanism in Naven:

  • nvn PATH_TO_FILE GOAL /p=PropertyOne:ValueOne /p=PropertyTwo:ValueTwo

On the “custom phases” implementation, you reference those defined properties just like normal NAnt properties:

<?xml version="1.0" encoding="utf-8"?>
<DotNetApplication xmlns="http://naven.4n1.pt/aom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://naven.4n1.pt/aom http://naven.4n1.pt/0.3/aom.xsd">
  <Name>NAnt Support Application.</Name>
  <Description>An application that shows the NAnt support.</Description>
  <Phases>
    <AfterInit>
      <echo message="This are properties references: ${PropertyOne}, ${PropertyTwo}"/>
    </AfterInit>
  </Phases>
</DotNetApplication>

What are the next planned features?

Naven has a lot way to go to get even just a little bit closer to the great tool Maven is. With that in mind, we have planned a few features already.

  • Convention support: By parsing the main solution file or searching for project files below the base folder.
  • Support other agents: An agent (for now) may be a DependencyResolver, a Compiler or a Tester. Naven code is made with dependency injection concepts, so we could change the default agents used. The ones available now are only:
    • MSBuild for compilation
    • Nuget for dependency resolution
    • NUnit for testing
  • Additional phases: We plan also to extend the Naven build process, to include some additional phases. Some of them may be:
    • Package: Creates a package of your projects/applications in Nuget format.
    • Install: Install the package in a package manager, probably a Nuget server for now.
    • Deploy: Deploy the application/project on a server.

For all this, we really would like to receive some help or opinions, specially because Naven is Open Source, and also because we hope it make your life easir. 😀 Feel free to check it out, download it, use it, and contribute. The 4N1 team thanks you.

ASP.NET MVC4/Upshot/Knockout: Remote + Local DataSource

The SPA (Single Page Application) I’m creating, does not sync all the changes with the server using the upshot RemoteDataSource. Because of that, I had to use a mixed approach, that is, a RemoteDataSource plus a LocalDataSource. The remote one brings the data from the server, while the local is used to make changes that will update the User interface, without going to the server. Here is the code:

// Used to "construct" new Model instances
function Model(data) {
    
	var self = this;

	// add properties from the JSON data result
	upshot.map(data, "SomeEntity:#SomeNamespace", self);

	// add properties managed by upshot
	upshot.addEntityProperties(self);
};

function ViewModel() {

	self = this;

	// Code generated by the Server-side @(Html.UpshotContext(true).DataSource<SomeNamespace.EntitiestController>(x => x.GetEntities()))
	upshot.metadata({ "SomeEntity:#SomeNamespace": { "key": ["Id"], "fields": { "Id": { "type": "String:#System" } }, "rules": {}, "messages": {}} });

	upshot.dataSources.Items = upshot.RemoteDataSource({
		providerParameters: { url: "/api/Entities?action=", operationName: "GetEntities" },
		entityType: "SomeEntity:#SomeNamespace",
		bufferChanges: true,
		dataContext: undefined,
		mapping: {}
	});

	// Creates a reference to the items returned by the remote datasource
	self.dataSource = upshot.dataSources.Items.refresh();

	// Create a local datasource that references the items returned by the remote datasource
	self.localDataSource = upshot.LocalDataSource({ source: self.dataSource,
		autoRefresh: true, allowRefreshWithEdits: true
	});	

        // Creates a filter to hide the deleted items (Since we are not syncing the changes, they will keep appearing on the UI otherwise)
        self.localDatasource.setFilter({ property: 'IsDeleted', value: false, operator: '==' });

	// Creates a reference to the local datasource entities to use it on the UI binds
	self.items = self.localDataSource.getEntities();

	self.addNew = function () {

		// Create a new item
		var item = new Model(null);

		// Pushes the item to the list of items. This will update the UI
		self.items.push(item);
	}

	self.remove = function (item) {
    
		// Removes the item from the localDatasource
		self.localDataSource.deleteEntity(item);

		// To update the UI, you have to refresh the local datasource (don't know why it does not do automatically)
		self.localDataSource.refresh();
	}
}

The autoRefresh property is self-explanatory. The important one here is the allowRefreshWithEdits property, that will allow us to execute refresh’s on the local datasource while having changes (it triggers an error if you don’t do this).

Another important thing is to add a filter to hide all the deleted entities at the local datasource. Since they are not commited to the server, they will still appear if you delete them and don’t apply a filter

Now, the user interface just have to bind to the items from the localDataSource, not the remote one:

<script type="text/javascript">
    $(function () {

        // Creates a ViewModel instance
        viewModel = new ViewModel();

        ko.applyBindings(viewModel);
    }
</script>
<div data-bind="foreach: items">
	<!-- Do something to show the items -->
<div>

ASP.NET MVC 4 ApiController serialization error: No readonly properties serialized and System.Runtime.Serialization.InvalidDataContractException

I’m starting a new project using the ASP.NET MVC 4 runtime. I’m using the new ApiController feature, really cool indeed. I had a business entity (domain class) that I wished to expose. But since the ApiController default serializer don’t write readonly properties, the best answer I found on the net was to create a ViewModel wrapping an instance of my business entity exposing the properties I wanted. Check the code:

public class DomainEntityApiController : ApiController
{
	// GET /api/domainentityapi
	public IEnumerable<DomainEntityViewModel> Get()
	{
		List<DomainEntityViewModel> list = new List<DomainEntityViewModel>();

		for (int i = 0; i < 10; i++)
		{
			list.Add(new DomainEntityViewModel(new DomainEntity(i + "Id", i + "Name")));
		}

		return list;
	}
}

public class DomainEntityViewModel
{
	private DomainEntity _entity;

	public DomainEntityViewModel(DomainEntity entity)
	{
		_entity = entity;
	}

	public String Id
	{
		get { return _entity.Id; }
		set 
		{ 
			// Do nothing 
		}
	}

	public String Name
	{
		get { return _entity.Name; }
		set
		{
			// Do nothing 
		}
	}
}

public class DomainEntity
{
	private String _id;

	private String _name;

	public DomainEntity(String id, String name)
	{
		this._id = id;
		this._name = name;
	}

	public String Id
	{
		get { return _id; }
	}

	public String Name
	{
		get { return _name; }
	}
}

Compiled. Went to http://localhost/api/DomainEntityApi and BANG! Error:

Type ‘TakeThatTime.Web.Models.DomainEntityViewModel’ cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.  If the type is a collection, consider marking it with the CollectionDataContractAttribute.  See the Microsoft .NET Framework documentation for other supported types.

body {font-family:”Verdana”;font-weight:normal;font-size: .7em;color:black;}
p {font-family:”Verdana”;font-weight:normal;color:black;margin-top: -5px}
b {font-family:”Verdana”;font-weight:bold;color:black;margin-top: -5px}
H1 { font-family:”Verdana”;font-weight:normal;font-size:18pt;color:red }
H2 { font-family:”Verdana”;font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:”Lucida Console”;font-size: .9em}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }

After a long research about the error and nothing found (at least not on google first result page ;)) I tried something: Putting a no args constructor on the ViewModelClass, like this:

public class DomainEntityViewModel
{
	private DomainEntity _entity;

	// Constructor that does nothing just because of the serialization issue
	public DomainEntityViewModel()
	{
		throw new NotSupportedException();
	}

	public DomainEntityViewModel(DomainEntity entity)
	{
		_entity = entity;
	}

	public String Id
	{
		get { return _entity.Id; }
		set 
		{ 
			// Do nothing 
		}
	}

	public String Name
	{
		get { return _entity.Name; }
		set
		{
			// Do nothing 
		}
	}
}

And tried again. And it worked. Here is the response now:

<?xml version="1.0" encoding="utf-8"?><ArrayOfDomainEntityViewModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><DomainEntityViewModel><Id>0Id</Id><Name>0Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>1Id</Id><Name>1Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>2Id</Id><Name>2Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>3Id</Id><Name>3Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>4Id</Id><Name>4Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>5Id</Id><Name>5Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>6Id</Id><Name>6Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>7Id</Id><Name>7Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>8Id</Id><Name>8Name</Name></DomainEntityViewModel><DomainEntityViewModel><Id>9Id</Id><Name>9Name</Name></DomainEntityViewModel></ArrayOfDomainEntityViewModel>

Rework, an awesome book!

Well, this post may look like it has nothing to do with code/programming but fear not, it has everything to do with it.

A good friend of mine, Rui Milagaia, talked to me about a book called Rework. He told me the book was from some guys that worked in a software development company but in a non conventional way. And they succeeded.

Time passed and only recently I’ve read it. I love it. All of it.

Honestly, I recommend this book to everyone that wants to be something in life. It so easy to read, no fancy words, no delays. The book is divided in really small chapters (more like articles), mostly with 1 or 2 pages long.

It made me think a lot about my behavior and what I want to do with my life. And not only that, It showed me that some of my values and ideas are not impossible, that there are people out there that thinks the same and was able to achieve something. If you want to know more about the book, the official site is here:

http://37signals.com/rework/

If you know the book or the company, feel free to comment and share your opinion.

New JBrisk version 0.1.2

This new version of the JBrisk project contains only a critical fix for a bug in the JBriskTestRunner for parameterized Unit Tests. The bug was about displaying runs with escape literals arguments at the Eclipse JUnit Test Runner.

😀

Solve your problems!

They say that you have to love yourself first to be able to love other.

I believe that!

So why do I only attempt to solve other people problems and not solve mine?

Most professions are about solving other people problems. Software Development is mainly about that. But have you ever asked yourself what you can do or have been doing to solve your problems?

If you have a problem, there is a HUGE possibility that other people have it too.

Why not create a solution for that problem and if its a good approach, sell it to everyone out there that feels the same.

By doing that, You are the FIRST customer/user of that solution. You’ll feel and think directly before anyone else if its good or not. And even if it’s only good for you, and don’t sell anything, even like that, You solved Your problem! You are happy with the solution! With that peace of mind, You have one less problem to think about it and you can focus more in creating solutions for other people problems.

Try it! Think a little about your problems!

Parameterized Unit Tests with JUnit

The current supported parameterized tests in JUnit seemed a little bit confusing for me and tricky to implement, at least compared to the NUnit approach. Below I will show a simple test implementation that asserts the result of the division of a number by another.

The NUnit approach:

using System;

using NUnit.Framework;

namespace JBrisk
{
    [TestFixture]
    public class DivideClassTests
    {
        [TestCase(12, 3, 4)]
        [TestCase(12, 2, 6)]
        [TestCase(12, 4, 3)]
        public void Divide(int n, int d, int q)
        {
            Assert.AreEqual(q, n / d);
        }
    }
}

NICE, NUNIT!

The JUnit approach:

package org.jbrisk.tests;

import java.util.Arrays;
import java.util.Collection;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class JUnitDivideClassTests {

	@Parameters
	public static Collection<Object[]> data() {

		return Arrays.asList(new Object[][] { { 12, 3, 4 }, { 12, 2, 6}, { 12, 4, 3 }});
	}

	private int n;
	private int d;
	private int q;

	public JUnitDivideClassTests(int n, int d, int q) {

		this.n = n;
		this.d = d;
		this.q = q;
	}

	@Test
	public void test() {

		Assert.assertEquals(q, n / d);
	}
}

JUNIT, Y U NO MAKE IT SIMPLE?

Don’t get me wrong, I love JUnit and use it daily at my projects, but this parameterized tests feature could be more simple. The reasons I did not like:

  • It needs more 20 lines of code for just a simple test, imagine a more complicated ones.
  • WHAT? I have to create a different class per parameterized test? This breaks a commonly used pattern about “One Test class per Class to Test”.
  • All the additional methods, fields, constructor, reduces the readability and maintainability of the code.

For those out there that do Unit Tests, specially the few ones on their teams/companies that do, you know how hard it is to maintain a lot of tests and even more hard to convince someone to start doing it. Less code (as long as it does not compromise readability) is better!

Well, I didn’t like it! And what my parents taught me a long time ago was:

When you don’t like something, change it!!!

And so I did! Here is the same test with JUnit, but using the @JBriskTestRunner and @ParamTest annotations implemented on my JBrisk project:

package org.jbrisk.tests;

import junit.framework.Assert;

import org.junit.runner.RunWith;

@RunWith(JBriskTestRunner.class)
public class DivideClassTests {


	@ParamTest({ @Values({ "12", "3", "4" }), @Values({ "12", "2", "6" }), @Values({ "12", "4", "3" }) })
	public void test(int q, int n, int d) {

		Assert.assertEquals(q, n / d);
	}
}

The good

  • Reduced the number of lines of code.
  • More readability.
  • Easier to maintain.
  • The implemented runner validates if the length of supplied arguments match the expected parameters length, and also if the supplied values can be converted to the expected type.
  • Since the JBriskTestRunner extends the BlockJUnit4ClassRunner, external tools can execute the parameterized tests (@ParamTest), non-parameterized tests (@Test) and all the other tests supported by it. And also, you don’t have to change your existing test class structure, you only have to add the @RunWith(JBriskTestRunner.class) annotation. Below is a an extended version of the class above and a screenshot of the Eclipse JUnit Test Runner executing its tests:
    package org.jbrisk.tests;
    
    import junit.framework.Assert;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    
    @RunWith(JBriskTestRunner.class)
    public class DivideClassTests {
    
    	@Test
    	public void normalTest() {
    	
    		Assert.assertEquals(1, 1);
    	}
    	
    	@Test(expected = NullPointerException.class)
    	public void testWithExpectedException() {
    		
    		throw new NullPointerException();		
    	}
    	
    	@ParamTest({ @Values({ "12", "3", "4" }), @Values({ "12", "2", "6" }), @Values({ "12", "4", "3" }) })
    	public void divideTest(int n, int d, int q) {
    
    		Assert.assertEquals(q, n / d);
    	}
    }
    

    JBrisk Parameterized Tests on Eclipse

    Notice how the Test Runner view above shows all the 3 runs of the parameterized test, showing also the arguments supplied to each one.

The bad

  • As stated here on the java docs, annotations do not support Object arrays, so, to support tests that receive arguments from different types, I had to resort to an “untyped” String array.
  • But fear not, if the JBriskTestRunner cannot convert the supplied argument to the correct parameter type, it will throw a descriptive error, something like: “The value “StringValue” supplied for the argument at idx “1” cannot be parsed to int! Check the inner exception for details.”

  • Java annotations only support primitive types, Class and enums (or arrays of the mentioned). JBriskTestRunner currently supports:
    • byte/Byte
    • char/Character
    • boolean/Boolean
    • short/Short
    • int/Int
    • long/Long
    • float/Float
    • double/Double
    • String
    • Class
  • You need to add another reference to the JBrisk project. Its not that bad because the JBrisk project does not have dependencies and supports Maven! 😀

One thing i do want to mention is that the JUnit contributors did an AWESOME job on the Runners object model. It was really easy for me to implement this feature because of that. Thank you! 😀

Easier Unit Tests with JNarcissus

Updated after major refactor on JNarcissus

For those that write a lot of Unit Tests in Java (yeeeeiiii, me included), i’ve just created an open source project that could interest you folks out there.

Its name is JNarcissus

Quoting Wikipedia:

in Greek mythology, Narcissus was a hunter from the territory of Thespiae in Boeotia who was renowned for his beauty. He was exceptionally proud, in that he disdained those who loved him. Nemesis saw this and attracted Narcissus to a pool where he saw his own reflection in the waters and fell in love with it, not realizing it was merely an image. Unable to leave the beauty of his reflection, Narcissus died.

JNarcissus won’t be hunting your bugs, but IT WILL fall in love with your objects. :D. Meaning that it will always notify you about things that should not happen.

Lets see an example. Lets say i have to test the following class:

package org.jnarcissus.core.sample;

public class JustAnotherTestClass {

	private String textField1;

	private String textField2;

	/**
	 * Returns the textField1 value.
	 * 
	 * @return textField1 value.
	 */
	public String getTextField1() {
		return textField1;
	}

	/**
	 * Sets the textField1 value.
	 * 
	 * @param textField1
	 *            New value.
	 */
	public void setTextField1(String textField1) {
		this.textField1 = textField1;
	}

	/**
	 * Returns the textField2 value.
	 * 
	 * @return textField2 value.
	 */
	public String getTextField2() {
		return textField1;
	}

	/**
	 * Sets the textField2 value.
	 * 
	 * @param textField2
	 *            New value.
	 */
	public void setTextField2(String textField2) {
		this.textField1 = textField2;
	}
}

Notice how the “copy-paste” demon got me tricked there (the getTextField2 and setTextField2 methods are using the wrong field). And lets face it, no matter how many year have passed, we always do copy-paste :D. If we follow the common Unit Test guideline (test just one requisite/feature per test) it would be really hard to get this bug. Lets see:

package org.jnarcissus.core.sample;

import org.junit.Assert;
import org.junit.Test;

public class JustAnotherTestClassTests {

	@Test
	public void setTextField1_validValue_getTextField1ReturnsSuppliedValue() {
		
		JustAnotherTestClass obj = new JustAnotherTestClass();
		
		Assert.assertNull(obj.getTextField1());
		
		obj.setTextField1("SomeValue");
		
		Assert.assertEquals("SomeValue", obj.getTextField1());
		
		obj.setTextField1(null);
		
		Assert.assertNull(obj.getTextField1());
	}
	
	@Test
	public void setTextField1_validValue_getTextField2ReturnsSuppliedValue() {
		
		JustAnotherTestClass obj = new JustAnotherTestClass();
		
		Assert.assertNull(obj.getTextField2());
		
		obj.setTextField2("SomeValue");
		
		Assert.assertEquals("SomeValue", obj.getTextField2());
		
		obj.setTextField2(null);
		
		Assert.assertNull(obj.getTextField2());
	}
}

Both tests will pass, because they test only one feature. And I know this is the Unit Testing philosophy, but you can also say is one of its weakness. For that (and a lot of other cases) JNarcissus was made! Lets see how we solve this problem with JNarcissus:

package org.jnarcissus.core.sample;

import org.jnarcissus.core.JNarcissus;
import org.junit.Assert;
import org.junit.Test;

public class JustAnotherTestClassTests {
	
@Test
	public void setTextField1_validValueAndAssertsWithJNarcissus_getTextField1ReturnsSuppliedValue() {

		JustAnotherTestClass obj = JNarcissus.create(JustAnotherTestClass.class);

		JNarcissus.assertNull(obj.getTextField1());
		
		JNarcissus.assertNull(obj.getTextField2());
		
		obj.setTextField1("SomeValue");

		JNarcissus.assertEquals("SomeValue", obj.getTextField1());

		obj.setTextField1(null);

		JNarcissus.assertNull(obj.getTextField1()).andPreviousAsserts();
	}

	@Test
	public void setTextField2_validValueAndAssertsWithJNarcissus_getTextField2ReturnsSuppliedValue() {

		JustAnotherTestClass obj = JNarcissus.create(JustAnotherTestClass.class);

		JNarcissus.assertNull(obj.getTextField1());
		
		JNarcissus.assertNull(obj.getTextField2());

		obj.setTextField2("SomeValue");

		JNarcissus.assertEquals("SomeValue", obj.getTextField2()).andPreviousAsserts();

		obj.setTextField2(null);

		JNarcissus.assertNull(obj.getTextField2()).andPreviousAsserts();
	}
}

Executing the code now throws the following error:

java.lang.AssertionError: Called: org.jnarcissus.core.sample.JustAnotherTestClass.getTextField1()
Expected: null
Actual: “SomeValue”

NICE! Now the tests fail!!! Aaaaa the red color… i don’t know if i love more making tests fail or making tests pass! 🙂 But how does the magic happens? Well, the first important line is this:

JustAnotherTestClass obj = JNarcissus.create(JustAnotherTestClass.class);

This will create an instance of the supplied class but, this instance will be special. It will have all its methods calls monitored by JNarcissus. But JNarcissus does not know yet what to monitor. Normally on a test, we ASSERT what we expect to be true (A value equals to an expected value, a condition returning false, etc). Look at the following line:

JNarcissus.assertNull(obj.getTextField1());

With the line above, we are providing the information JNarcissus needs to monitor our instance. It means something like this:

JNarcissus, assert that the obj.getTextField1() method returns null and, EXCEPT I SAY OTHERWISE, all subsequent calls to the obj.getTextField1() method should return null. ALWAYS.

As our test continues, we may need to update the information to be monitored. Look at the next two lines below:

JNarcissus.assertNull(obj.getTextField2());
obj.setTextField2("SomeValue");

The first line only makes the same as the previous assert but now to the obj.getTextField2() method. But the second line is calling the obj.setTextFielld2 method with a value. This means that the expected return value from the obj.getTextField2() method should NOT BE NULL anymore. It should be equal to the one supplied to the obj.setTextFielld2 method. We need to update this information on JNarcissus (Remember the “EXCEPT I SAY OTHERWISE” condition?). We do this simply calling another assert on the same method:

JNarcissus.assertEquals("SomeValue", obj.getTextField2()).andPreviousAsserts();

To JNarcissus, this means something like this:

JNarcissus, assert that the obj.getTextField2() method returns a value equals to “SomeValue” and, EXCEPT I SAY OTHERWISE, all subsequent calls to the obj.getTextField2() method should return a value equals to “SomeValue”. ALWAYS. And also, execute all the previous asserts i made until now.

The .andPreviousAsserts() method executes all the asserts the code made before. And of course, it will only execute the most recent assert for a given method. I like to call this feature Assertive Memory. Because basically, is a memory of all the current asserts made to an object. If we were to look at the assertive memory state through the test, it would look like this:

obj.getTextField1() obj.getTextField2()
Before setting value Assert is null Assert is null
After setting value Assert is null Assert is equals to “SomeValue”

When you are updating the information (lets read it, the assert you want to keep stored) about a method, JNarcissus does not only take in consideration the method witch you are calling, but also the arguments you use. For example, lets say we have a method that accepts an argument, and that we want to monitor different return values from it:

	
/**
* A method with an argument that impacts the returned value.
* 
* @param number
*            Number argument.
* @return The supplied number to String.
*/
public String numberToString(int number) {

if (number == 0)
	return "Zero";
else if (number == 1)
        return "One";
else
	return "Don't know";
}

We can monitor methods with arguments the same way we do with methods without arguments:

	
@Test
	public void numberToString_returnsCorrectValue() {
		
		JustAnotherTestClass obj = JNarcissus.create(JustAnotherTestClass.class);
		
		JNarcissus.assertEquals("Zero", obj.numberToString(0));
		JNarcissus.assertEquals("One", obj.numberToString(1));
		JNarcissus.assertEquals("Don'tknow", obj.numberToString(2));
	}

What this means to JNarcissus:

JNarcissus, assert that the obj.numberToString method called with the argument 0 returns a value equals to “Zero” and, EXCEPT I SAY OTHERWISE, all subsequent calls to the obj.numberToString method called with the argument 0 should return a value equals to “Zero”. ALWAYS.
JNarcissus, assert that the obj.numberToString method called with the argument 1 returns a value equals to “One” and, EXCEPT I SAY OTHERWISE, all subsequent calls to the obj.numberToString method called with the argument 1 should return a value equals to “One”. ALWAYS.
JNarcissus, assert that the obj.numberToString method called with the argument 2 returns a value equals to “Don’tKnow” and, EXCEPT I SAY OTHERWISE, all subsequent calls to the obj.numberToString method called with the argument 2 should return a value equals to “Don’tKnow”. ALWAYS.

Executing this test will throw the error:

java.lang.AssertionError: org.jnarcissus.core.sample.JustAnotherTestClass.numberToString(2)
Expected: “Don’tknow”
Actual: “Don’t know”

I’ve made this error on purpose, just to show that JNarcissus monitors method call with arguments also. We can easily fix the test by correct the string “Don’tknow” to “Don’t know”.

Why all the trouble

Well, i wrote JNarcissus because in some point while doing Unit Tests, I noticed that in some more complicated cases, I was doing the same asserts very often. JNarcissus main reason to exist was to erase du/tri/quadru/####plicated “asserts” code. The other main reason was to understand how Mocking frameworks are made :D. You see, under the hood, JNarcissus uses the same technique most of the Mocking Frameworks use, that is: In runtime, generate a class that extends the class you want to mock, and direct all method calls made to that instance to the mocking framework stubs. In fact, the first version of JNarcissus was made based on the GREAT AND AWESOME (I really, really like it) mocking framework Mockito. You can see the influence from Mocking frameworks, since in JNarcissus you can actually assert information about the monitored methods:

JNarcissus.assertMethod(obj, new CallCountMatcher(1)).numberToString(0);
JNarcissus.assertMethod(obj, new CallCountMatcher(new GreaterOrEqual<Integer>(1))).numberToString(0);

The first line above will assert that the number of calls made to the obj.numberToString(0) method was exactly 1. The second line shows just an overload to the CallCountMatcher constructor that receives a Matcher object (yes, from the awesome library Hamcrest). that asserts that the number of calls to the obj.numberToString(0) method is Greater or Equal to 1. This is a good feature when you use dependency injection on your tests, and does not want to create a mock, but simply verify that a method was called.

Internally, JNarcissus uses the Hamcrest matchers to do the asserts. So you can also do something like this:

// These two lines means the same thing
JNarcissus.assertNull(obj.getTextField1());
JNarcissus.assertThat(obj.getTextField1(), CoreMatchers.nullValue());

Whats next?

Well, JNarcissus it still in its beggining, but i already use it for making Unit Tests at my projects. I plan to port JNarcissus to .NET also, but still don’t know when it will be. Like most of the mocking and dependency injection frameworks that use the “derived class technique” or “proxy class technique”, JNarcissus has some limitations. It cannot monitor final methods or classes. I will try to overcome this limitation in the future, but only if there is the demand to.