Java Properties dupe key detect using Javassist

In a prior post, I used Commons Configuration to detect duplicate properties in a Properties file. The code was very simple.

Here I present a solution using a Dynamic Proxy class. A complexity is that though Properties extends the Map interface, that interface does not declare a load method. And, the JDK Dynamic Proxy support can only be used for interfaces, not concrete classes. The Javassist library can be used for this purpose as shown in listing 1 below.

Listing 1, dupe detect with Javassist Source Gist

package com.octodecillion.util;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;

/**
 * Detect duplicate properties when loading Properties from stream.
 * <p>
 * This version uses <a href="https://jboss-javassist.github.io/javassist/">Javassist</a> Dynamic Proxy support.
 * 
 * @author jbetancourt
 * @since Nov 18, 2015
 */
public class DuplicatePropertyDetectorWithJavassist {

    /**
     * Detect duplicate keys in Properties resource.
     * <p>
     * @see Properties#load(Reader)
     * 
     * @param reader The reader is <b>NOT</b> closed.
     * @return Map Map where map key is duplicated key and list is values of those keys
     * @throws IOException reading the stream
     * @throws RuntimeException for any issue with proxying
     */
    public Map<String, List<String>> load(Reader reader) throws IOException {
        if(reader==null){ throw new NullPointerException("reader cannot be null");}
        
        final Map<String, List<String>> dupeResults = new HashMap<>();
        final String put_method_name = "put";
        
        try {
            ProxyFactory factory = new ProxyFactory();
            factory.setSuperclass(Properties.class);
            factory.setFilter(new MethodFilter() {
                @Override
                public boolean isHandled(Method m) {                    
                    return m.getName().equals(put_method_name);
                }
            });

            ((Properties) factory.create(new Class<?>[0], new Object[0], 
              new MethodHandler() {
                @Override
                public Object invoke(Object self, Method thisMethod, 
                    Method proceed, Object[] args) throws Throwable {

                    String key = (String) args[0],value = (String) args[1];

                    if (((Properties) self).containsKey(key)) {
                        List<String> list = new ArrayList<>();
                        if (dupeResults.containsKey(key)) {
                            list = dupeResults.get(key);
                        } else {
                            dupeResults.put(key, list);
                        }

                        list.add(value);
                    }

                    return proceed.invoke(self, args);
                }

            })).load(reader);

        } catch (NoSuchMethodException | IllegalArgumentException 
                | InstantiationException | IllegalAccessException
                | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        return dupeResults;
    }    
}

Links
Javassist

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Java dupe key Properties detect using Commons Configuration

Java Properties files can contain duplicate key entries. This can be a problem since the Java Properties loader will just keep the last value parsed.

Not a problem for small applications, but when property files grow in number and size this can become a maintenance issue. Fortunately there are many solutions for this (I hope). This post will present a very simple method that performs duplicate key detection.

When first confronted with dupe detection goal, reading the Properties file directly and determining dupes using a HashMap sounds simple. However, you would have to duplicate the Properties file format parsing. That can get complex. For example, a property entry may use “:” or “=” to specify the key, value pair. Plus, you would have to handle the line continuations feature, and other requirements.

Commons Configuration makes this simple since its Properties loader will create lists for any duplicate property key. Thus, to detect duplicates, just find which property values are lists, see listing 1 below.

Listing 1, Duplicate key detection using Commons Config Also available as a Gist

package com.octodecillion.util;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;

/**
 * Detect duplicate properties when loading Properties from stream.
 * <p>
 * 
 * @author jbetancourt
 * @since
 */
public class DuplicatePropDetectWithCommonsConfig {

    /**
     * Detect duplicate keys in Properties resource.
     * <p>
     * <a href="">Commons Config</a> is used.
     * {@link Properties} class.
     * 
     * @see Properties#load(Reader)
     * 
     * @param reader The reader is NOT closed.
     * @param delimiterParsingDisabled 
     * @return Map of keys that are duplicated with a list value of each value of duplicate. 
     * @throws ConfigurationException 
     */
    @SuppressWarnings("unchecked")
    public Map<String, List<String>> loadWithConfig(Reader reader, boolean delimiterParsing) 
      throws ConfigurationException {
        PropertiesConfiguration config = new PropertiesConfiguration();
        final Map<String, List<String>> results = new HashMap<>();

        config.setDelimiterParsingDisabled(delimiterParsing);
        config.load(reader);

        Iterator<String> keys = config.getKeys();
        while (keys.hasNext()) {
            String theKey = keys.next();
            Object valueObject = config.getProperty(theKey);
            if (!(valueObject instanceof String)) {
                results.put(theKey, (List<String>) valueObject);
            }
        }

        return results;
    }
    
    /**
     * @author jbetancourt
     *
     */
    @RunWith(Enclosed.class)
    public static class DuplicatePropDetectWithCommonsConfigTest {
        private static final String DATA1_PROPERTIES = "/Data1.properties";

        /**
         * @throws ConfigurationException
         */
        @Test
        public void testLoadFileWithConfig() throws ConfigurationException {

            InputStream is = this.getClass().getResourceAsStream(DATA1_PROPERTIES);
            Assert.assertNotNull(is);

            DuplicatePropDetectWithCommonsConfig detector = new DuplicatePropDetectWithCommonsConfig();
            Map<String, List<String>> map = detector.loadWithConfig(new InputStreamReader(is), true);
            Assert.assertEquals(1, map.size());

            Assert.assertTrue(map.containsKey("three"));

        }
    }
}

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Java fluent inline map initialization

This is a common task, and there are many good and bad solutions out there. Java 8 even has a “Supplier” that can assist with inline map initializations.

Unfortunately, Java does not have a simple method like that found in the Groovy language. A map in Groovy is:

def map = [name: ‘Gromit’, likes: ‘cheese’, id: 1234].

 
I implemented a builder in Java 7 that is just simple syntax sugar. This is before I found Per-Åke Minborg’s great blog post Java 8, Initializing Maps in the Smartest Way on the topic, or the others found online. Perhaps I was using the wrong search. Hmm.

Using my version without all the Generics details:
Map codes = InitMap.with(new HashMap())
   .put(“xyz”,”321″).put(“abc”,”362″).toMap();

Alternatively, you can create a Map instance and use the builder, no need to invoke toMap():
Map<String,String> map = new HashMap<>();
InitMap.with(map).put(“xyz”,”321″).put(“abc”,”362″);

How does it work? InitMap is just a “partial” Decorator. When you create the InitMap object the Map parameter is stored in a field. Then when you “put” key/values, they becomes a ‘put’ to the hidden map. This allow you to chain the ‘put’s. When your done adding entries, you invoke toMap() to get the actual Map instance. The simplest thing that works.

Not too sure about the Generics stuff. Generics are like a loose thread on a coat; if you keep pulling on it, soon you’ll have no coat.*

Jump to source

Links

Footnotes

*This leads, me anyway, to wondering how do you test compile only concerns, like generics? Sure, compile errors are thrown if you try to use Generics type-safe code incorrectly. But, how do you know your generics code is meeting the requirements, or that future maintenance would not still enforce the requirements?

Hmm. Only thing I can think of is you have to write unit test that invoke a Javac compiler on strings of source code.


Source Section

  • Java 8, but not the new JDK features.
  • Eclipse Mars for development

Listing 1, InitMap and tests implementation, full source Gist

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Toward predictive interfaces: ‘Google Now on tap’

In a prior post I compared “Google Now” and the concept of a Proactive User Interface. It looks like ‘Google Now on tap’ will finally be a step in the right direction.

My first impression from a quick read of some articles is that it is an expansion of the info cards concept with more correlation with current UI context. This is such a powerful, and an extremely obvious feature, that you wonder why this was not done years ago. True, Google will put more search and Big Data power behind this. But, is it really predictive and will it “learn” a users information patterns?

An information pattern example (from my prior post) is a User is viewing a web site. There is a probability that if a certain amount of time is spent or a certain page or article type is visited, that clicking a share button will be followed by predictable actions. For example, sharing a link with a colleague or loved one. The UI presented will then present a proactive plan. See “Proactive User Interface“. Generating information related to context is still requiring the user to perform wasted effort to form and act on immediate action plans. So what are those octocore chips for?

Proactive Interface v2
Diagram of idea

Updates

  • Nov 9, 2015: Google just open sourced a Machine Learning system, TensorFlow.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Remove forced uppercase from WordPress post titles

The new Theme for this blog converted the titles to all uppercase. What possible UI design decision was that? Just makes no sense.

Anyway, fortunately there is a “helpful” wordpress documentation page that shows how to change this: create a child theme for your changes. This is on WordPress’s Codex. I found that link by a forum discussion, [resolved] [closed] How to change site title from all caps to lower case.

It worked! And, I don’t even know how to code WordPress. Those instruction are not very clear. For example, it mentions that you may have to do something different if the Theme uses multiple css files. Do what exactly? And my current Theme “twentyforteen” does have multiple css files, though not in the root folder.

What did I do? Created the two files, style.css and functions.php. FTP’d them to a new folder twentyfourteen-child. Then enabled the new Theme “twentyfourteen-child” in my blog.

Listing 1, style.css

/*
 Theme Name:   Twenty Fourteen Child
 Theme URI:    http://example.com/twenty-Fourteen-child/
 Description:  Twenty Fourteen Child Theme
 Author:       John Doe
 Author URI:   http://example.com
 Template:     twentyfourteen
 Version:      1.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  twenty-fourteen-child
*/
.entry-title {
	font-size: 33px;
	font-weight: 300;
	line-height: 1.0909090909;
	margin-bottom: 12px;
	margin: 0 0 12px 0;
	text-transform: none;
}

Listing 2, functions.php

<?php
/**
 * Twenty Fourteen child functions and definitions
 *
 *   ALL THE DETAILS FROM CODEX ARTICLE
 *
 * @package WordPress
 * @subpackage Twenty_Fourteen
 * @since Twenty Fourteen 1.0
 */

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );

}

I repeated the steps here so I have a reference to what worked in my situation.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Note 4 can’t connect USB to Windows 7 PC

Tried a few things trying to connect Samsung Galaxy Note 4. Only thing that worked was uninstalling the Samsung driver in the Device Manager of PC. Then when you connect the phone with a USB cable, there should be an auto detection and installing of the drivers. Three things are installed

Of course, your cable must be the right kind (not just a power cable) and so forth.

I got the tip by “xfaega” at: http://forum.xda-developers.com/showpost.php?p=49040275&postcount=19

Strange that this was always working then stopped. I wonder if it was that attempt to update Android recently that was continually interrupted. Darn amazing phones.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Large-world networks and species, social, and internet collapse

A Small-World Network is found in many naturally and and artificial situations. At the other extreme, if a network is totally connected, a complete digraph? You get zero information. This can be translated into species collapse, zero advertising revenue, and others such as ineffectual internet search.

Can this happen? In animal populations a fully connected graph is when everyone is closely related. The gene pool is stagnant. That population dies. In the internet, it could happen if everyone is on FaceBook and knows everyone else, or they are on Twitter, and follows everyone else. Another example, in the Mathematical field, a complete graph would mean that everyone would have an Erdős number of 1.

Is there a graph measure that correlates to the above? The more connected the less information, an Entropy?

Information loss, heat death. Time for another Big Bang.

Updates

  • October 3, 2015: Continuing the above line of thought, perfect order leads to zero information.
  • October 5, 2015: A Zombie Apocalypse is just a food network that is maximally connected, your next meal is sitting right next to you.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

How to unit test Java servlets

The question of how to unit test Servlets comes up a lot. How can it be done? Should it be done? What are the options?

A unit test, in the realm of xUnit semantics, is an isolated test of the smallest testable subset of a program. Usually this translates to a test of a single method in an Object. When this object itself is part of a framework or container, such tests border on becoming Integration Tests. How could these types of objects still be ‘unit tested’?

Written by: Josef Betancourt, Date: 2015-09-17, Subject: Servlet testing

Options

Here are a few options.

POJO

When you write a servlet, ultimately the servlet object is instantiated by the server container. These objects do a lot behind the scenes that may prevent invoking methods on them when not attached to an actual container.

A servlet, or any other server based object like an EJB, provides access to problem domain services or functionality. The easiest way to test these Objects is to refactor that service into plain old Java objects, POJO.

Jakob Jenkov writes: “… push the main business logic in the servlet into a separate class which has no dependencies on the Servlet API’s, if possible”.

If your working with a framework that is likely the design approach anyway.

Servlet stub library

A library that allows creation of “server” objects can make creating stubs for testing very easy. Again, a framework should provide such a feature.

Mocking

Mocking using modern libraries like Mockito, Powermock, and JMockit, provides a very powerful approach. There is also what appears to be a more focused Mockrunner project, which has a mockrunner-servlet module.

In listing 1 below, a test is created for a target SutServlet class’s doGet. This method will set the response status to 404 if an ID request parameter is null.

Using JMockit, proxies of HttpServletRequest and HttpServletResponse are created. The request’s getParameter and the response’s setError methods are mocked. The actual unit test assertion is done in the mocked setError method.

Listing 1, JMockit use

@RunWith(JMockit.class)
public class SutServletTest_JMockit {
    
    @Test
    public void should_Set_ResourceNotFound_If_Id_Is_Null() throws Exception {
        new SutServlet().doGet(
        new MockUp<HttpServletRequest>() {
            @Mock
            public String getParameter(String id){
                return id.compareToIgnoreCase("id") == 0 ? null : "don't care";
            }
        }.getMockInstance(),
        new MockUp<HttpServletResponse>() {
            @Mock
            public void sendError(int num){
                Assert.assertThat(num, IsEqual.equalTo(HttpServletResponse.SC_NOT_FOUND));              
            }
        }.getMockInstance());
    }
     
}

JDK Dynamic Proxies

The Mock approach can also be duplicated using dynamic proxies. JDK dynamic proxy support is usable here. JDK proxies have one limitation, they can only proxy classes that extend an interface. (Still true in Java 9?). Servlets extend interfaces, so we can the proxy support in the JDK.

Listing 2, using JDK proxies

public class SutServletTest_using_jdk_proxy {
    
    private static final String DON_T_CARE = "don't care";
    private static final String SEND_ERROR = "sendError";
    private static final String GET_PARAMETER = "getParameter";

    /**  @throws Exception  */
    @Test
    public void should_Set_ResourceNotFound_If_Id_Is_Null() throws Exception {
        
        // request object that returns null for getParameter("id") method.
        HttpServletRequest request  = (HttpServletRequest)Proxy.newProxyInstance(this.getClass().getClassLoader(),
            new Class[]{HttpServletRequest.class},
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName().compareToIgnoreCase(GET_PARAMETER) ==0){
                            return ((String)args[0]).compareToIgnoreCase("id") == 0 ? null : "oops";
                        }
                        return DON_T_CARE;
                    }
                }
        );
        
        // Response object that asserts that sendError arg is resource not found: 404.
        HttpServletResponse response  = (HttpServletResponse)Proxy.newProxyInstance(this.getClass().getClassLoader(),
            new Class[]{HttpServletResponse.class}, 
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName().compareTo(SEND_ERROR) == 0){
                            Assert.assertThat((Integer) args[0], IsEqual.equalTo(HttpServletResponse.SC_NOT_FOUND));
                        }
                        return DON_T_CARE;              }
                }
        );
         
        new SutServlet().doGet(request,response);
    }
}

Javassist Proxies

Just for completeness, in listing 3, we use the Javassist library.

Listing 3, using Javassist proxy

public class SutServletTest_using_assist {
    
    private static final String DON_T_CARE = "don't care";
    private static final String SEND_ERROR = "sendError";
    private static final String GET_PARAMETER = "getParameter";

    /**  @throws Exception  */
    @Test
    public void should_Set_ResourceNotFound_If_Id_Is_Null() throws Exception {
        
        // request object that returns null for getParameter("id") method.
        HttpServletRequest request  = (HttpServletRequest)createObject(new Class[]{HttpServletRequest.class},
            new MethodHandler() {
                public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
                    if(thisMethod.getName().compareToIgnoreCase(GET_PARAMETER) == 0){
                        return ((String)args[0]).compareToIgnoreCase("id") == 0 ? null : "oops";
                    }
                    return DON_T_CARE;
                }
            }
        ); 
        
        // Response object that asserts that sendError arg is resource not found: 404.
        HttpServletResponse response  = (HttpServletResponse)createObject(new Class[]{HttpServletResponse.class},
            new MethodHandler() {
                public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
                    if(thisMethod.getName().compareTo(SEND_ERROR) == 0){
                        Assert.assertThat((Integer) args[0], IsEqual.equalTo(HttpServletResponse.SC_NOT_FOUND));
                    }
                    return DON_T_CARE;
                }
            }
        );
         
        new SutServlet().doGet(request,response);
    }
    
    /**
     * Create Object based on interface.
     * <p>
     * Just to remove duplicate code in should_Return_ResourceNotFound_If_Id_Is_Null test.
     * @param interfaces array of T interfaces
     * @param mh MethodHandler
     * @return Object
     * @throws Exception
     */
    private <T> Object createObject(T[] interfaces, MethodHandler mh ) throws Exception{
        ProxyFactory factory = new ProxyFactory();
        factory.setInterfaces((Class<?>[]) interfaces); // hmmm.        
        return factory.create(new Class[0], new Object[0], mh);
    }
}

Embedded server

Its also possible to start an embedded server, deploy the servlets, and then run the tests. Various Java app servers (like Tomcat and Jetty) support this and are well documented. The complexity comes when only partial integration is required. For example, we may want to have a real app server running the tests, but do we also really need a database server too? Thus, we also have to deploy stubs or mocks to this embedded server. Many resources on web for this approach, for example, “Integration Testing a Spring Boot Application“.

Another approach is the concept of the Hermetic Servers.

AOP

AOP can be used on embedded server, and this would allow “easy” mocking of integration endpoints and mocks. Such an approach was shown here “Unit test Struts applications with mock objects and AOP“.

References

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Continuous Testing while developing, CDT?

I previously wrote about Continuous Testing here. Strange, at the time a web search turned up very little about the concept. What was found was the use of the term in the sphere of Continuous Integration systems and processes. Today there are more relevant hits.

Terminology
On Wikipedia the term CT, “Continuous testing”, is redirected to Test Automation. I don’t know the arcana of Wikipedia but “Continuous testing” is hidden somewhere as you can see if you visit the redirection link. The edits on the redirection page shows that some editors where getting into the details of ‘real’ CT, etc.

One editor mentioned the problem of dependency detection. If you edit source Foo and source Fee is a dependency, then you should rerun tests for Fee too?

Via a web search, Wikipedia article has, Continuous test-driven development, CTDD. That seems relevant. However, that seems to imply the original Test Driven Development TDD practices are being used. From what I read, TDD is not that popular. The use of unit testing is more popular. So, if a tool automatically runs unit or functional tests on local code changes, that has nothing to do with how those tests were written, TDD or not. The tests could have been written years later for some legacy system that is now being maintained with appropriate tests.

CT is also possible in non-IDE dev environments of course. An example is Wallaby.js, which is a continuous test runner for JavaScript.

Continuous Testing
We don’t edit code then invoke a compile step anymore. Our IDEs do that automatically. Then why have to invoke our unit tests manually? This “Continuous Testing” (CT) approach enables a smoother Test-Driven Development (TDD), maintenance, or refactoring, work flow.

This type of CT is in contrast to tests run on a Continuous Integration server, Continuous Developer Tests, CDT. Dev tests (unit, functional, integration, …) are run in the developer workstation in response to source changes. Nothing new of course, IDEs have always rebuilt on such events, but the tests have not been run at a fine-grained level.

Is there any evidence of this? Some papers on CT are found here.

Great videos on the CT as implemented in Mighty-Moose, a product for Microsoft Visual Studio, are found at continuoustests.
Mighty Moose Demo, a CT product for Visual-Studio.

Cons?
Mentioning this to any developer will give you immediate “buts”: But my tests take too long; it would be distracting; I change code constantly;…… I sometimes think developers are driven by a little motor in them, but … but … but … buuuut.

Implementations?
Why isn’t automatically running of tests supported in IDE’s like Eclipse? Build systems, like Maven, have always supported test goals. Now Gradle will support Continuous Builds.

Is there is a direct way to invoke the JUnit plugin via adding a new custom “builder” to Eclipse? A builder in Eclipse is triggered by resource changes. So, on source code change this builder would have to run an associated ‘JUnit run configuration’ that in turn could run the GUI test runner or the build system which invokes the tests.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

In dev, a missing test always passes

What if a you lose an automated test? What if that was testing a critical functional area? This article discusses this and for unit tests implements a Java @RequiresTest annotation

How to lose a test

Can’t lose a test? Sure you can. Test reports just give you counts and changes? Who looks at that? No one. In a long time span, test maintenance can develop warts and tests are silently deleted since they are failing and its too hard to fix or no time available. The original developers of a component may have gone on to other things and that tender loving care is nowhere to be found.

Coverage reports don’t help much with this. Unless there are drastic changes in test results or coverage levels, no one looks at them, they become just another management spreadsheet number, or developer hipster feel-good schtick.

Who loses tests

Sure, for tools, utilities and highly focused systems, especially FOSS, this is not likely. The rapid change and larger development teams ensure full use of test tools. In these projects there is more likely to be a level of “test-infected” developers.

For other kinds of systems, like IT projects, testing will be forgotten when the scat hits the fan, or when the test evangelist moves on or gives up. Testing will just rely on manually repeated testing of a local facsimile of the target system and waterfail test department testing.

Quoting Fowler here “Imperfect tests, run frequently, are much better than perfect tests that are never written at all.”, I would add or those that are never run.

Does it matter

For real-world large applications that quickly become legacy, any missing tests can prove disastrous. A missing test would make any potential defect show up much later. Later is too late and costs more to fix.

Ironically, the best example of the lost of tests are legacy systems that have no automated tests, a de-testable system. In such a system, defects are found in late stage waterfall phases, or worse in production.

What should be tested

Ideally everything would have a valid unit/functional/integration test. In reality this is not cost effective and some would argue that some things should not be tested. For example, it is claimed that getter/setters do not need tests. (Clearly in a language with true properties, this is true. Java, not.)

So if some things should not be tested, what should be? And if those things that should be tested are not tested?

Options

If missing tests are a concern, what can be done? As in many system decisions, it depends: What kind of tests, when are the tests run, who manages the tests, what kind of test monitoring, and so forth.
The following are just a few options that could be considered.

Monitoring of missing tests

The Continuous Integration system or the build tools it invokes present and track missing tests. Missing tests are considered a failure and must be acted on: confirming or removing from consideration.
There is no need to create this missing test list. The build system adds to this list as each build is performed.

Required tests database

For critical systems or subsystems a required test database could be used. This would be more of a management and tool issue since an ongoing project may change many tests during its duration.
Required tests specification is not a new concept. Hardware systems have always had such a concept and even go further by having Built-In Self Tests.
Note that one argument against recent standards and by extension a ‘required test database’ is that this is not congruent with modern agile processes.

Requires test annotation

For “devtests”, using xUnit frameworks, it is much easier to indicate what should be tested. This can be easily made part of the build configuration system and run as part of the test phase. To make more resilient to bit rot, the source code itself should store this information. In the Java devcology this can be done for unit tests using annotations.

Example

In listing 1, a developer has decided that two methods should have tests. So the methods are annotated with @RequiresTest.
Listing 1, an application class with annotations

package com.anywhere.app;

import com.octodecillion.test.RequiresTest;

/**
  */
public class Foo1 {	
	@RequiresTest
	public void fum1(){
        // stuff		
	}

	@RequiresTest
	public void fum12(){		
        // stuff
	}
}

Below in listing 2, a Java implementation of a RequiresTest annotation is shown. It uses the same approach I used in Search Java classpath for JUnit tests using Spring, except now the filter checks for a different annotation. These two could be combined into one implementation that searches for tests or requires annotation.

Funny, I did not annotate the RequiresTestAnnotationScanner with @RequiresTest.

Listing 2. A requires test annotation

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

The celebrated man in the street

%d bloggers like this: