Why Unit Test?

Contrary to popular belief, the purpose of unit tests is not to verify correctness of code. Correctness can only be determined by a human. Code can be beautifully engineered and thoroughly unit tested, yet incorrect. The purpose of unit testing is more nuanced: to prevent changes to the expected behavior. When we write unit tests, we are formally specifying the expected behaviors of the testSubject. Whether of not these expectations are the correct expectations is purely subjective. When all of the expected behavior of our code is being witnessed by unit tests, we have a ‘safety net’ in place that allows us to add new expected behaviors and refactor existing expected behavior implementations with confidence that all of the preexisting desired behavior remains in place.

    Unit Tests fall into 3 main categories:

  1. Tests for methods that have a return value and no side effects. These are the most straightforward methods to test. ‘assertEquals(expectedReturnValue, actualReturnValue)’ is used to test this type of method. ‘verify(…)’ statements are not needed for this method type. Using verify() during tests for this method type is only making the test fragile because you are locking the behavior into a certain implementation unnecessarily.
  2. Tests for methods with side effects only. This method type is characterized by by its ‘void’ return type. These methods must have some side effect(s) that we must verify, otherwise they would be dead code. Testing this method type does require using verify() to witness a certain implementation in most cases. In our example, we must verify that a certain DAO method is called with specific parameters to persist some data when ‘saveExampleVO()’ is called. We want a test to fail if this internal behavior is altered or goes missing without also updating the corresponding tests to match our new definition of expected behavior. A better technique is to avoid creating or using void return type methods. Our example could be altered such that mockExampleDao returns some success/failure message and we could assert() that testSubject.saveExampleVO() returns the value from the injected mockExampleDao instead of validating the implementation.
  3. Tests for methods that return a value and also have unrelated side effects. This is just bad coding style. This method type violates the single responsibility principle and should be avoided. Both assert() and verify() statement are required to witness the desirable behavior in this case. Its best to refactor this type of method instead.

 

    “That’s not Testable…” – this really means “I don’t want to or don’t know how to unit test that”. Difficulty with unit testing a class is a code smell, usually too many behaviors packed into long methods that don’t inject their dependencies. Refactor by decomposition until the code is testable. Avoid using non OOP concepts like static method calls and procedural programming style.

Strive to test the public interface behavior only. If a bug exists in the class that in no way shape or form is externally observable by testing its public interface, is it really a bug after all? Write tests that witness desirable external behaviors, but avoid enforcing any particular implementation. Ideally we want to leave the implementation free to be refactored without failing any tests, as long as the externally observable behavior remains unchanged. As long as the implementation still produces the ‘right answer’ we are not concerned with how the result was produced. Tests that fail during refactoring are fragile and discourage code cleanup activities.  ‘verify(…)’ statements in tests are a sign that the test is enforcing a particular implementation. ‘verify(…)’ should be avoided unless there is a desirable side effect that must be in place. Class methods with side effects should really be avoided anyway.

    Unit tests execute in isolation. Unit tests do not run within any servlet container. They do not interact with any database. The instance of a class being tested doesn’t even interact with real instances of its own dependencies. The idea is to completely isolate the testSubject and replace all dependencies with ‘imposters’ (aka mock objects) during test execution. Any test that is witnessing the interactions between 2 or more genuine class implementations is not a unit test but rather some form of integration test.

    Focus on edge/boundry cases, that’s prime bug hunting territory.

    Don’t forget to test the sad path too. Tests should also witness desirable failure conditions, such as exceptions being thrown when expected. What’s the desired behavior with input is null? EmptyString? Whitespace?

    Naming is important: Good test names should describe the behavior that is being witnessed, but not call out any details about the implementation of the behavior. For example testServiceReturnsExpectedValue() instead of testServiceReturnsValueFromDao()

Limitations of Unit Testing:

No form of testing can prove no additional undesirable behavior is present, only that all desirable behavior remains present. (The Volkswagon emissions scandal is a prime case study exhibiting the problem)

Testing that loops through every input possibility just takes too long to execute. We must spot check, focusing on edge cases.

Test Driven Development (TDD) Tutorial

Introduction:

Kent Beck, one of the original signers of the Agile manifesto and creator of eXtreme Programming, is credited with discovering Test Driven Development (TDD), but he claims he merely re-popularized the technique and coined the term. Here is what he had to say about rediscovering the technique:

“The original description of TDD was in an ancient book about programming. It said you take the input tape, manually type in the output tape you expect, then program until the actual output tape matches the expected output.
After I’d written the first xUnit framework in Smalltalk I remembered reading this and tried it out. That was the origin of TDD for me. When describing TDD to older programmers, I often hear, “Of course. How else could you program?” Therefore I refer to my role as rediscovering TDD.”

TDD is a highly disciplined approach to developing software. The technique has been around much longer that you may guess. It was not called TDD at the time, but the technique was used way back in the 1950’s by NASA during project Mercury.

 

Tutorial:

Lets use TDD to develop an simple ‘Uasi’ modem class. Uasi is a silly childhood language akin to Pig Latin. Here is how it works:

Exchange every vowel with the next vowel in alphabetical sequence. ‘U’ wraps back around and is replaced by ‘A’.

“My name is Tomas” -> “My nemi os Tumes”

Unit tests exist to prove that the desirable behaviors remain in place throughout future development and refactoring. One test per behavior. How many behaviors/tests do you think an Uasi modem should have? One? A few? Many? Let me rephrase the question: How many regression bugs are possible in an Uasi modem?

I can think of at least 20 desirable behaviors that must be in place for a working Uasi modem, and that’s just to cover the happy paths

  1.  All ‘a’ characters of the encoder input are replaced with ‘e’ characters in the encoded value.
  2.  All ‘e’ characters in the decoder input are replaced with ‘a’ characters in the decoded value.
  3.  All ‘A’ characters of the encoder input are replaced with ‘E’ characters in the encoded value.
  4.  All ‘E’ characters in the decoder input are replaced with ‘A’ characters in the decoded value.

… you get the idea

There are additional expected failure behaviors to consider as well. What is the desired behavior when input is null? Do we expect some kind of InvalidInputException or to return emptyString?

To develop our Uasi modem in a test driven fashion, we will begin the TDD rhythm of “Red, Green, Refactor”.

Red – Write 1 new unit test that covers a single desired behavior. This test should fail because the new desired behavior doesn’t exist yet. This temporary failing test will show up as red in the jUnit report results. That’s how this step gets its name.

Green – Write just enough code to make the test for the new behavior pass. Be mindful not to add any additional behavior yet that is not covered by any tests yet. Your newest test should turn ‘green’ once the new desired behavior is in place.

Refactor – Refactor your testSubject to clean up the implementation of the existing behaviors with confidence that all desired behaviors remain in place because all unit tests continue to pass. Be mindful not to introduce new behaviors that are not covered by tests during refactoring.

Lets start the RGR rhythm with our first test:

 

At this point the test will fail. Actually it won’t even compile yet. The testSubject class doesn’t exist yet, and neither does its .encode() method.  Lets finish the Red step by making this test compile.

 

Now our first test compiles, but fails when executed. Lets continue to the Green step and make this test pass by implementing the desired behavior with the bare minimum amount of code.

The unit test of our first behavior now passes, so we can move on the Refactor step where we do cleanup and make the code fit our coding standards.

 

That concludes our first RGR cycle. Continuing the Red, Green, Refactor rhythm will carefully and robustly grow our Uasi modem’s desired behaviors with confidence that regressions are not happening along the way. At the end of our second RGR iteration, our code may look something like this:

 

After many RGR iterations, here is the tests I came up with, along with 3 entirely different implementations. I doubt any of these implementations are anything like what you had in mind, but they all work perfectly fine and the tests prove it.

Tests:

Jr Level implementation:

Sr. Lever Implementation:

Master Craftsman Implementation:

Who knows how/why this works, but its fewer lines of code so it must be better 🙂

 

Now that the tests and a passing implementation are in place, we can refactor with confidence that the desirable behavior is being preserved. Try your own implementation and see if your implementation passes all the tests first try. Get these files from my Github: https://github.com/bkturley/uasiModem.

Try it yourself

As a self directed exercise, try to TDD an “Pig Greek” service. Pig Greek, also known as ‘Obish’, is another silly language sort of like Pig Latin, but easier than Pig Latin to implement because it is encoded by vowel sound position rather than by syllable position. Programmatically breaking English words into syllables is just too complicated and distracts from the purpose of the exercise. Here’s how to speak Pig Greek:

Simply add “Ob” before every vowel sound.

“My horse is in the barn” -> “MOby hOborse Obis Obin thObe bObarn”

This may seems pretty straightforward, but we are dealing with the English language, so there are certainly nuances that make the process non trivial and interesting. The word “my” for example contains no vowels, but does have a vowel sound. The word “horse” has a silent ‘e’ that makes no vowel sound. The word “teeth” has two consecutive vowels, but only one long ‘e’ vowel sound. Correctly decoding Pig Greek has many opportunities for bugs when ‘Ob’ is supposed to be preserved (“microbe”, “obey”, “global”).

 

Fun fact: Special languages like Uasi and Pig Greek that are used for secret communications while among larger groups have a named classification. They are collectively known as ‘Argot’ (pronounced are-go), ‘Cant’, or ‘Cryptolect’.

Install Truecrypt 7.1a on OSX Yosemite

TrueCrypt Install OSX Yosemite

    Despite the suspicious shutdown of Truecrypt, it is still a solid solution for your data encryption needs unless you are an enemy of state.  Installing the last usable version on Truecrypt (7.1a) requires some tribal knowledge to install on OSX Yosemite. Here is how to bypass the “TrueCrypt requires Mac OS X 10.4 or later.” error:

1) Double-click  truecrypt_7.1a_mac_os_x.dmg

2) Right-click  TrueCrypt_7.1a.mpkg and “Show Package Contents”

3) Open Contents Dir

4) Open Packages Dir

5) Install OSXFUSECore.pkg

6) Install OSXFUSEMacFUSE.pkg

7) Install MacFUSE.pkg

8) Install TrueCrypt.pkg

Answering a Recent Interview Question…Thoroughly

Here is a coding exercise I was asked to solve during a recent interview:

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

This is a basic solution, it is what I consider a rough prototype.

Here is a more architected solution. Tasks have been separated into classes with clear and narrowly defined responsibilities. I consider this a decent draft 2. This code is still not ready to be used in a production system.

 

A complete Solution:

 https://github.com/bkturley/fibonacciUnitTested

Fleshed out unit tests make this project ready for use in a production system.

Reverse engineering a 16 character display using an Atmel 328p.

Switches and interrupts on a PSoC 1 Microcontroller

I. Introduction / Summary

The most practical way for a microcontroller to retrieve input is via interrupt.  The vast majority of modern processors have interrupt functionality.  This functionality allows a processor to work on background tasks while no input has happened. Once input is detected, the processor diverts its attention to react, then returns to where it left off after the interrupt has been serviced.

II. Description and Circuit Diagrams

An optical encoder is connected to VCC and ground to provide power to its internal emitters, detectors, and squaring circuitry.  The encoders outputs are connected to P1[4] and P1[5] on the PSoc board. P2[0-6] are connected to a LCD on the evaluation board.

Using this setup, we will display to the LCD a number between 0 and 100 that reflects the direction of the encoder rotation.

Capture1

III. Description of Software

The software routine enables interrupts, starts the LCD, and takes a measurement of the B output of the rotary encoder upon startup.  It then simply executes an infinite loop with no consequences.  The only way to leave this loop is via an interrupt triggered by a change in either the A or B inputs from the rotary encoder.  Once a change in input is detected, the execution jumps to the interrupt service routine named PSoC_GPIO_ISR_C(void). This ISR takes a measurement of the A input, clears the LCD, then performs an XOR operation on the current A and the previously stored B to determine whether the rotary encoder was turned clockwise or counter clockwise.  A count variable (initially = 50) is incremented or decremented accordingly within the explicitly defined limits of 0~100. The LCD is updated to display the count variable. Finally the current value of B is stored to be used during the next execution of the ISR.

IV. Validation and Testing

The setup was tested by turning the rotary encoder clockwise and counter-clockwise while observing the LCD to see the count being updated.  The encoder was moved to both the upper and lower limits to ensure that the LCD display correctly prevented any value < 0 or > 100 from being displayed.

V. Program listing

Polling a switch Using a PSoC 1 Microcontroller

     One way for a microcontroller to retrieve input is known as polling.  Polling means repeatedly measuring  a sensors value.  I will describe how to poll a pushbutton switch  and react to its measurement when using a Psoc3 microcontroller.

Capture