9 September 2020

Flashcards Coupling and Cohesion

Transition Coupling FLIRT-SBBLow Coupling and High Cohesion are basic design principles in both functional programming and object orientation. What is coupling? Coupling is the measure of the strength of association by a connection from one module to another. At least that is one of the definitions I found when researching the topic. Another one is that Coupling is the degree of interaction between modules. Following some original research from 1974 by W. P. Stevens, G. J. Myers and L. L. Constantine, Structured Design, IBM Systems Journal Volume 13, Issue 2, Pages 115-139, there are several types of coupling and different degrees of its strength. The same is true for cohesion. These are a lot of definitions to remember - flashcards to the rescue.

Flashcards
So I created a deck of cards about coupling and cohesion. It contains 115 questions and covers
  • Definition of Coupling
  • Coupling based on the type of its dependency.
  • Types of coupling by strength.
  • Examples of code elements with certain types of coupling.
  • Postel's Law
  • Coupling Contributing Factors
  • Definition of Cohesion
  • Cohesion based on the type of the module's elements' relationship.
  • Types of cohesion by strength.
  • Examples of code elements with certain types of cohesion.
  • Problems caused by low strength cohesion.
These are just basic definitions and code samples. For example I am missing Connascence and other more high level aspects of coupling and cohesion.

Download
I use Anki digital flashcards. Its apkg files can be used with Anki for Windows and Android and AnkiApp for Mac and iOS. Download the Coupling_and_Cohesion.apkg here.

30 August 2020

TDD a UI with Fast Tests

AndroidsThis is another part of my series of TDD-ing user interfaces. Earlier this year I looked at test driving classic, fat, state based UIs like Swing or WinForms and then web component libraries like Vaadin. In both situations it was possible to TDD the UI using the Model View Presenter (MVP) pattern and a decent test bed for testing the implementation of the view. Later I explored test driving an immediate mode GUI, which was even easier than doing so for retained mode: There was no need to search for components, capture events or trigger events. This time I want to experiment with test driving a user interface by only using UI tests. In theory I could do that with Swing or Vaadin, but the UI tests of these technologies are too slow. For my TDD cycle I want fast tests!

Android UI Tests
My friend Bastien David told me that Android UI tests are pretty fast and I talked him into running this experiment with me. I had never done any Android development and had only little knowledge of the Kotlin language - it is good to have friends who know. Bastien's Kotlin/​Android starting point used Espresso and Robolectric for testing the Android UIs. The sample test
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class HelloActivityTest {

  @get:Rule
  var activityScenarioRule = activityScenarioRule<HelloActivity>()

  @Test
  fun hello_activity_has_some_hello_text() {
    onView(withId(R.id.text_hello)).check(matches(withText("Hello!")))
  }

}
used Espresso's matchers to find the text "Hello" on the view of the HelloActivity.

First Few Tests
We worked on the same exercise used in my previous articles, the Login Form exercise. The first tests for UI elements of the LoginActivity, i.e. user name field and login button were
@RunWith(AndroidJUnit4::class)
class LoginActivityTest {

  @get:Rule
  var activityScenarioRule = activityScenarioRule<LoginActivity>()

  @Test
  fun `has username field with max length of 20`() {
    onView(withId(R.id.username))
      .check(matches(checkMaxLength(20))) // custom matcher
  }

  @Test
  fun `has label for username`() {
    onView(withId(R.id.username_label))
      .check(matches(withText("Phone, email or username")))
  }

  @Test
  fun `has login button`() {
    onView(withId(R.id.login_button))
      .check(matches(withText("Log in")))
      .check(matches(not(isEnabled())))
  }
}
These tests did not create any code, we declared the UI elements in the layout app/​src/​main/​res/​layout/​activity_login.xml to make each test pass. On Bastien's machine the tests were fast enough and it was easy to drive UI elements and their attributes. We had to create some custom Hamcrest matchers though, e.g. checkMaxLength. We decided not to go deeper and assert colours, styles or positions, but we could have.

Test Driving Logic
The next test
  @Test
  fun `when username is introduced then login button is enabled`() {
    onView(withId(R.id.username))
      .perform(typeText("a real username"))

    onView(withId(R.id.login_button))
      .check(matches(isEnabled()))
  }
brought a bit of logic into the LoginActivity,
class LoginActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_login)

    username.addTextChangedListener {
      login_button.isEnabled = true // new logic
    }
  }
}
We only spent two hours on the exercise and did not get far. Still I could see where we would end. We would inspect every behaviour by its effect on the UI. While we could use the MVP pattern, we did not as the tests were fast enough.

Similar Technologies, e.g. React
Some modern UI technologies come with a fair amount of testing support. For example the same approach should be possible with React. There is a JavaScript/​React starting point in the Login Form Kata. Some people have tried that. I do not know if they went far enough for a definite conclusion.

David Tanzer dedicated some of his React TDD videos on testing the UI: In Part 1: Testing the UI Itself he explains the necessary setup to test React and in Part 2: Value and Cost of Tests he talks about possible test cases. He does not check text elements and style of the UI as he considers these things to have little probability of breaking later. Doing TDD, he looks for tests which influence the design of the code. I highly recommend you watch all of his videos.

Conclusion: Is this still TDD?
Test driving a UI with fast tests like Android or React is certainly possible, maybe even easy. These tests are not unit tests. Is it still TDD? We definitely write the tests first so it is Acceptance test driven (A-TDD) or at least "UI specification test driven". Unlike TDD these tests do not influence the design of the code because the components of the UI are usually specified by the requirements, e.g. in wireframes. As all tests exercise the code through the UI, there is no pressure on the code, its interfaces and collaborators. Still we can evolve the code because we have full test coverage and regression safety.

24 July 2020

Interview Philipp Mayer

It has been more than a year since my last guest interview on ethics in Software Development, and I am very happy that Philipp Mayer found the time to answer my questions. When I asked Philipp about ways to contact him, he said "I do not use any social networks for work related things :)" If you are new to the series, I am talking to people in the area of software development about our social responsibility and ethics in general. I started the series in 2015 as part of my own quest for work with meaning.

Philipp why did you choose to work with software?
I chose to work with software in the third year of junior high school ("Unterstufe"). In maths we used the Texas Instruments Voyage 200 calculator on which one could code in TI Basic. Our teacher showed us a few things and told us we would be allowed to store any formula on there as long as we did it via writing an application for it. This motivated many of us to take a closer look at coding. This then led to choosing the IT department of the high school HTL Krems instead of becoming a chef.

When we met, you said that you rarely eat meat. Why do you do that?
It does for environmental reasons. I am aware of the great impact that meat production has on climate. This has led to not buying meat unless I know it is high quality and from a source that I know. As a (working, but still) student, that means that I do not often buy meat. Nowadays when I eat meat, I see it as something special, even if it is just a pair of sausages. An exception where I do eat meat without taking care of the quality is at other people's home if it were thrown away otherwise.

What do you actually do regarding climate change?
Use of public transport. I am a happy owner of the ÖsterreichCard ticket that allows me to take any train at any time within Austria. I do understand, that public transport just does not make sense for many people's everyday way to work at the moment. So I hope for improvements here. A positive thing I recently found out about is the ÖBB rail and drive service that allows me to book an electric car for less than 2 euros/hour on weekends. This is perfect for weekend trips and motivates me even more to not buy a car anytime soon.

Balance ScaleOutside of climate change, what do you consider the biggest challenges of our times?
The increasing social and financial inequality.

What else could we do to engage in the topic? For example, did you take part in public protests, donate money to NGOs or sign petitions?
  • Protests: no
  • Donate money: little
  • Sign petitions: some
I think I make a bigger impact by living a thrifty lifestyle and trying to convince people around me to do so as well.

Most of these activities are personal choices. This is great but most of our time is spent on regular work. I would like to see more impact on these important topics of my regular work, just working on "the right things". Do you think that is possible?
In general no, as the companies doing "the wrong things" tend to pay more than others. In his book "Die Kunst des guten Lebens, Rolf Dobelli cites the psychologist Paul Dolan saying that a sound consists of two parameters - frequency and amplitude. And that it is the same when it comes to happiness. There's the hedonistic and the eudaimonistic component. So I think that everyone has to find the right mix for oneself.

How do you think about selecting industry, customer and project based on your values and social responsibility?
I would once more go with the statement made in previous answer. I think it never is a pure financial choice but about the people who you work with and to what extent one sees a meaning in the project.

Let's be more specific here: Would you work for an animal factory? Would you work for a sweatshop exploiting kids in Asia?
Unfortunately, I have to be very generic with this one. For me it depends, if in my position I could enhance the situation for the poor ones (animals, children working in factories etc.) in the organization. Otherwise, I do not think I would see value in my work.

Did you ever reject a customer or an actual project, that would bring you money based on your values?
No, as I did not have the chance to do so in my career, yet.

On the other hand, what would be industries, customers and projects that you would love to work on?
Definitely environmental or social - in terms of improving the life of the weakest ones.

Thank you Philipp