How to avoid triggers revisited.

Posted: 2013-11-05 by Rikard Mathisson in Best Practices, Databases
Tags: , ,

When I wrote the paper “why to avoid triggers and how” a couple of years ago my current target DB was MSSQL so I forgot to mention what applies to Oracle regarding part 4.1.

4.1. Enforcing complex integrity/business rules.

Add CHECK constraints to your fields in your create
table statements [5a]. They allow using UDF:s (user
defined functions) for constraint validation. Such UDF:s
may be very complex and since they are faster than stored
procedures, and only runs when data is updated in
affected columns, they are highly efficient. Note that
check on computed columns requires persisted option (4.4
below).

Oracle allows neither user-defined functions nor sub-queries on check constraints, so that leaves out any obvious workaround for triggers. That is for implicit constraints. It is still possible to enforce explicit business rules (procedure call, for example) before committing data inside a transaction to allow late data rejection, if not prevented early in a code flow.

Early rejection of illegal values are of course preferred in any case.

Double Dabble

Posted: 2011-12-19 by Roger Wernersson in Best Practices, Design, Programming, Refactoring, Unit Tests

I’ve been trying out a bit of TDD.

Basically, I think TDD is the only way forward.

I’ll start at the beginning.

Code evolve, and as it does, it also decays if not pruned, a bit like a garden in that respect. Pruning mean refactoring to make it fulfill its evolving purpose.

Refactoring is only ever safe if we have a good unit test coverage. Unit tests we write after the production code is written are OK at best, because we tend to test things we know works. We also tend to test in a way that makes it harder to change the implementation, because as we are aware of the implementation, we take shortcuts. I’ve seen this a lot of times.

TDD forces us to write the test code first, before the production code. Hence, we can’t test the implementation, because there isn’t any. This makes it much easier to refactor the production code.

However.

The TDD cycle is something like this: write a test, test fails, write production code until the test succeeds, refactor the code.

Now, most people skip that last step.

But from what I’ve seen, even people who actually do the last step doesn’t do it fully; they refactor the production code, but not the test code. This will be their downfall. As test code decays, the production code will go stale and then everything goes downhill.

Here’s the problem: How do you ensure that you don’t break the test code when you refactor it?

I’ve mostly used TestNG. It might be a TestNG only problem, but I doubt it.

Let’s say I’ve got some production code I want to test, in this case equals(), a method actually generated by Eclipse.

    public boolean equals( Object obj )
    {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Person other = (Person) obj;
        if (myId != other.myId) return false;
        return true;
    }

Here’s my test method, using FEST asserts for the nice flow:

    @Test
    public void equalsIfAllFieldsAreEqual()
    {
        Person actual = createPerson();
        Person expected = createPerson();
        
        boolean isEqual = actual.equals(expected);
        
        assertThat(isEqual).isTrue();
    }

Not much to refactor, but it’s only an example. If I make a mistake when I refactor the production code, the test will fail and I’ll know.

But if I make a mistake when I refactor the test code so that I now test something else, or even worse, I don’t actually test anything, how would I know?

I gave this some thought and came up with a solution, but it’s somewhat convoluted. Here it is:

I’ve added a new class of which I need an instance for each testable feature:

public class Testable
{
    private boolean myState = true;
    private boolean myWasDoubleChecked = false;
    private String myName;

    public Testable(String name)
    {
        myName = name;
    }
    
    public boolean asBoolean()
    {
        return myState;
    }

    public void activate()
    {
        myState = true;
    }

    public void deactivate()
    {
        myState = false;
        myWasDoubleChecked = true;
    }

    public boolean wasDoubleChecked()
    {
        return myWasDoubleChecked;
    }

    public String getName()
    {
        return myName;
    }
}

Then I need to add an instance for each testable feature.

public class Person
{
    private int myId;
    public static Testable FEATURE_EQUAL_IF_ALL_FIELDS_ARE_EQUAL = new Testable("equal if all fields are equal");
    public static Testable FEATURE_EQUAL_IF_SAME_OBJECT = new Testable("equal if same object");

    public boolean equals( Object obj )
    {
        if (this == obj) return FEATURE_EQUAL_IF_SAME_OBJECT.asBoolean();
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Person other = (Person) obj;
        if (myId != other.myId) return false;
        return FEATURE_EQUAL_IF_ALL_FIELDS_ARE_EQUAL.asBoolean();
    }
}

I added a new class which must be the base class for all tests:

public abstract class DoubleTester
{
    private boolean myDoubleCheck = false;
    private List myFeatures = new ArrayList();

    @BeforeClass
    public void createFeatureList()
    {
        addFeatures();
    }
    
    protected abstract void addFeatures();
    
    protected void add(Testable feature)
    {
        myFeatures.add(feature);
    }

    @AfterMethod
    public void activateAllFeatures()
    {
        for(Testable feature : myFeatures)
        {
            feature.activate();
        }
        
        myDoubleCheck = false;
    }

    protected void check(Testable feature)
    {
        if (myDoubleCheck)
        {
            feature.deactivate();
        }
    }

    protected void doubleCheck()
    {
        myDoubleCheck = true;
    }
    
    @Test
    public void makesSureWeRunAfterClass()
    {
    }
    
    @AfterClass
    public void makeSureWeDoubleCheckedAllFeatures()
    {
        for(Testable feature : myFeatures)
        {
            Assert.assertTrue(feature.wasDoubleChecked(),
                    "Add double check for \""+ feature.getName() +'"');
        }
    }
}

This means a test class must do the following:

public class PersonTest extends DoubleTester
{
    
    @Override
    protected void addFeatures()
    {
        add(Person.FEATURE_EQUAL_IF_SAME_OBJECT);
        add(Person.FEATURE_EQUAL_IF_ALL_FIELDS_ARE_EQUAL);
    }
    
    @Test(expectedExceptions=AssertionError.class)
    public void doubleCheckEqualsIfSameObject()
    {
        doubleCheck();
        equalsIfSameObject();
    }
    
    @Test
    public void equalsIfSameObject()
    {
        Person expected = createPerson();
        Person actual = expected;
        
        check(Person.FEATURE_EQUAL_IF_SAME_OBJECT);
        boolean isEqual = actual.equals(expected);
        
        assertThat(isEqual).isTrue();
    }
    
    @Test(expectedExceptions=AssertionError.class)
    public void doubleCheckEqualsIfAllFieldsAreEqual()
    {
        doubleCheck();
        equalsIfAllFieldsAreEqual();
    }
    
    @Test
    public void equalsIfAllFieldsAreEqual()
    {
        Person actual = createPerson();
        Person expected = createPerson();
        
        check(Person.FEATURE_EQUAL_IF_ALL_FIELDS_ARE_EQUAL);
        boolean isEqual = actual.equals(expected);
        
        assertThat(isEqual).isTrue();
    }
}

That’s it, basically.

Now, I’ve got several issues with this.

1. I need to add code to the production code, which makes it a source of errors. I could just add it for tests I want to refactor, but now that I know of the problem, I want to double check all my tests.

2. There is probably a performance impact. How do I get rid of that in production?

3. Will I ever get anyone else to write tests like this?

I think there might be a way of doing this using annotations. It would nice to be able to do the following instead:

@Testable
public class Person
{
    private int myId;

    public boolean equals( Object obj )
    {
        if (this == obj) return true; @Doublecheck EQUAL_IF_SAME_OBJECT
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Person other = (Person) obj;
        if (myId != other.myId) return false;
        return true; @Doublecheck EQUAL_IF_ALL_FIELDS_ARE_EQUAL
    }
}

And then have the test code go like this:

public class PersonTest extends DoubleTester
{
    @Doublecheck
    public void equalsIfSameObject()
    {
        Person expected = createPerson();
        Person actual = expected;
        
        @Check=Person.FEATURE_EQUAL_IF_SAME_OBJECT
        boolean isEqual = actual.equals(expected);
        
        assertThat(isEqual).isTrue();
    }
    
    @Doublecheck
    public void equalsIfAllFieldsAreEqual()
    {
        Person actual = createPerson();
        Person expected = createPerson();
        
        @Check=Person.FEATURE_EQUAL_IF_ALL_FIELDS_ARE_EQUAL
        boolean isEqual = actual.equals(expected);
        
        assertThat(isEqual).isTrue();
    }
}

Either way. I’d like to know what everyone else is doing to address this.

How do you make sure you don’t break the test you refactor?

/Roger

Flattr Roger

An Agile point of view

Posted: 2011-07-06 by Rikard Mathisson in Methodology

I’ve had a long WordPress break due to a recent career change. Becoming a consultant have given me a slight change of perspective since I’ve been moving from product development to, more or less, producing hours

Thinking about perspectives; often different roles in a project have very different perspective upon measuring lead time, resources and workload. Even though most of the industry have accepted agile processes as cost effecient and an resource effective tool for reducing waste and getting prioritiez right – not everybody gets it! Agile methods have become the daily bread of all kinds of companies; ranging from telecom to car manufacturing.

It seems to me that understanding agile methods is a essentially different from implementing them! Take SCRUM, for example; just adding tasks as post-it on a whiteboard does not make you Agile. And in turn, that does not make you produce less waste or being able to deliver prioritized values on target or on time. It does neither make your team members happier or reduces the need for quality requirements. It also does not make your teams able to work disconnected from the customer (a.k.a black-box), which by the way is probably as far from SCRUM as you can come.

This should be obvious, it may seem. However, that is probably due to my software engineer perspective. Apparently not everyone involved in software development processes understands that reducing waste and increasing quality is hard labour that requires planning and serious thought. Good quality does not come from yellow post-its. Neither does more output.

It seems that due to your personal perspective, you may or may not understand that number-crunching is not actually a part of the production; it is just a tool for measurement. And as such, measurement cannot be achieved without affecting the outcome! Hence, the less you measure, the more effecient you can produce.

when measuring the  physical state of a quantum system there’s a fundamental limit to the amount of precision that can be achieved
/Werner Heisenberg

However, I have come to mind that whether this is true or not, in the arbitrary team, depends on that team’s perspective on labour. It  heavily depends upon the level of engagement and self-propelling in the team itself!

Conclusions

  • Output may be negative affected by the method of measurement, which also have impact on the quality of the output
  • Poor output  is a management problem and not a measuring issue, and there are proper Agile ways to deal with it
“Working more hours” does not necessarily mean “producing more output”
/Agile SCRUM

Testing my Heritage

Posted: 2011-03-13 by Roger Wernersson in Best Practices, Programming, Unit Tests
Tags: ,

I love being right. So much so, that if I discover that I’m wrong, I change my mind immediately. I think I was wrong about this last week. Unfortunately, this might turn out to be more of a discussion than anything else. However, the journey, as we all know, is the goal. I don’t think I’ll be changing my mind on this again though. (But I’m willing to do it if I’m proven wrong. :-)

I think the best approach is to test all inherited methods by having your DerivedClassTest classes inherit from BaseClassTest class. This way you will test all important methods of the base class from the point of view of all the derived classes, ensuring that you didn’t introduce any bugs when over-riding base class implementation.

I hate to remove the previous content of this post, because I thought I was so clever. But as the saying goes; sometimes you have to Kill Your Darlings.

Flattr Roger

Eclipse Quickies

Posted: 2011-02-09 by Rikard Mathisson in Programming
Tags: ,

Working with Eclipse everyday combined with being pro-keyboard usage I get pretty annoyed sometimes that Eclipse forces me to use the mouse more that most other IDE:s.

However, here is a quick list of shortcuts that applies by default in Eclipse and that are most useful, although sometimes annoyingly limited.

Happy coding!

Read the rest of this entry »

The Knights who say NIH

Posted: 2011-02-02 by Roger Wernersson in Documentation

As I’ve written about before, I’m interested in humans reading and remembering what I write. Therefore I try to tease the brains of the reader with BDD User Stories about characters to whom the reader can relate.

I wrote a quite amusing user story involving Hansel and Gretel. To illustrate this I added a picture of a gingerbread house. Now it looks like it will be removed because a colleague higher up the food chain thinks it is unprofessional.

It is frustrating. I’m trying to improve, reach higher, make the organization and products better. Almost everyone who read these documents are very positive to my ideas.

I think I’ve just met one of The Knights who say NIH ( Not Invented Here).

 

Flattr Roger

Shifting DOS Parameters

Posted: 2011-01-17 by Rikard Mathisson in DOS, Programming
Tags: ,

Every now and then you’ll find myself in need to automate tedious and repetitious work task like this;

  1. update local source from repository
  2. clean and deploy the source
  3. run unit tests- run static analysis
  4. more of this stuff …

… repeating it over and over again. In this situation I often find myself writing batch scripts in DOS (trying to keep scripts compatible with most Windows versions).  One of the (many) annoying limitations in DOS scripting is that you can only refer to maximum 10 parameters. And already with a few parameters you might end up with all parameters being mandatory rather than optional.

Here follows a rather complete code example for DOS which shifts out parameters and run blocks of the script based on what parameters have been set.

Ps. If you read the code carefully, I’ve included several general hints about writing .bat scripts. Sorry btw for the syntax coloring scheme, i found no MS-DOS syntax schema so I used perl instead, it’s almost the same anyway ;-)

@echo off
@rem Author: rikard.mathisson@gmail.com
@rem Date: 2011-01-15

@rem Copyright: Just please give me credit, otherwise public domain.

@rem This is an example of how to switch command line parameters in a
@rem simple (and best practice) way. Note that this script uses basic
@rem GOTO:s and :LABELS as we all did in the early 80's - but it's for
@rem good reasons - DOS does not handle flow control at all, unless you
@rem have the benefin of using Power Pack - which is not always possible.

echo This is a parameter demo. All CLI parameters will be looped and printed below.
set /a i=0 >> NUL
set silent=no
set filename=__unset

:LOOP

@rem Here is the part where your program should handle parameter input
@rem Jump to MAIN label, when no more parameters found, and do the main processing.
if "%1"=="" goto MAIN

@rem This counter is not only for nice printout but also to make it possible to know if no parameters was given. The redirect to NUL is just to avoid the result being printed to the console and the /a flag is to let the SET command know it's an arithmetic expression.
set /a i+=1 >> NUL

@rem Here you can process input parameters accordingly, lite switches etc.
@rem I include a small and simple example of handling switches where the /s switch will make this script silent and the /f switch will allow output to a specified file. /? will jump to HELP section without processing other parameters.
if "%1"=="/?" goto HELP
if "%1"=="/s" goto SUB_S
if "%1"=="/f" goto SUB_F

if "%silent%"=="no" echo [DEBUG] parameter #%i%=%1

:RETURN

@rem Get the next parameter into %1 and repeat
shift
goto LOOP

@rem This is a good place to put help text when the user forgot using parameters.
if %i%==0 echo goto HELP

:SUB_S
@rem This is the subroutine for handling the /s switch.
set silent=yes
goto RETURN

:SUB_F
@rem This is the subroutine for handling the /f FILENAME switch.
@rem Note that it shifts out another (the FILENAME) parameter.
shift
set filename=%1
if "%silent%"=="no" echo [DEBUG] FILNENAME set to "%filename%"
goto RETURN

:MAIN

@rem This is the main program section. Add your subprogram here.
@rem Example code writes the "dir" output to a file, if specified, otherwise to console (STDOUT).
if "%silent%"=="no" echo [DEBUG] MAIN Begin

set mycommand=dir
@rem Note that the caret (^) is used for escaping the redirect (>) character below.
if not "%filename%"=="__unset" set mycommand=%mycommand% ^> %filename%
if "%silent%"=="no" echo [DEBUG] MYCOMMAND set to "%mycommand%"

@rem Note that the line below executes the value stored in mycommand
%mycommand%

if "%silent%"=="no" echo [DEBUG] MAIN End
goto END

:HELP
echo Syntax: params [/s] [/f FILENAME] [...]
echo - /s mutes the debug output
echo - /f send main output to FILENAME istead of console

:END
if "%silent%"=="no" echo [DEBUG] DONE!